summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-07-09 16:44:11 +0200
committerPierre Ossman <ossman@cendio.se>2014-07-14 16:03:41 +0200
commit0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8 (patch)
tree500f61ee230d30fa1f8e955214c698e86b69e2f4
parent126e56420e47d72cc950d03976ee57d1efda436e (diff)
downloadtigervnc-0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8.tar.gz
tigervnc-0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8.zip
Use PixelBuffer objects as the interface for encoders and decoders
This avoid a lot of unnecessary middle men. This also pushes the responsibility for pixel format conversion into the encoders and decoders. The new bufferFromBuffer() is used for direct conversion, rather than PixelTransformer/TransImageGetter.
-rw-r--r--common/rfb/CMsgHandler.h9
-rw-r--r--common/rfb/CopyRectDecoder.cxx5
-rw-r--r--common/rfb/CopyRectDecoder.h2
-rw-r--r--common/rfb/Decoder.h10
-rw-r--r--common/rfb/Encoder.h11
-rw-r--r--common/rfb/HextileDecoder.cxx13
-rw-r--r--common/rfb/HextileDecoder.h2
-rw-r--r--common/rfb/HextileEncoder.cxx20
-rw-r--r--common/rfb/HextileEncoder.h2
-rw-r--r--common/rfb/RREDecoder.cxx13
-rw-r--r--common/rfb/RREDecoder.h2
-rw-r--r--common/rfb/RREEncoder.cxx9
-rw-r--r--common/rfb/RREEncoder.h2
-rw-r--r--common/rfb/RawDecoder.cxx9
-rw-r--r--common/rfb/RawDecoder.h2
-rw-r--r--common/rfb/RawEncoder.cxx24
-rw-r--r--common/rfb/RawEncoder.h2
-rw-r--r--common/rfb/TightDecoder.cxx10
-rw-r--r--common/rfb/TightDecoder.h4
-rw-r--r--common/rfb/TightEncoder.cxx13
-rw-r--r--common/rfb/TightEncoder.h6
-rw-r--r--common/rfb/VNCSConnectionST.cxx30
-rw-r--r--common/rfb/VNCSConnectionST.h2
-rw-r--r--common/rfb/VNCServerST.cxx1
-rw-r--r--common/rfb/VNCServerST.h9
-rw-r--r--common/rfb/ZRLEDecoder.cxx19
-rw-r--r--common/rfb/ZRLEDecoder.h2
-rw-r--r--common/rfb/ZRLEEncoder.cxx19
-rw-r--r--common/rfb/ZRLEEncoder.h2
-rw-r--r--common/rfb/hextileDecode.h6
-rw-r--r--common/rfb/hextileEncode.h7
-rw-r--r--common/rfb/hextileEncodeBetter.h5
-rw-r--r--common/rfb/rreDecode.h7
-rw-r--r--common/rfb/tightDecode.h12
-rw-r--r--common/rfb/tightEncode.h21
-rw-r--r--common/rfb/zrleDecode.h6
-rw-r--r--common/rfb/zrleEncode.h5
-rw-r--r--vncviewer/CConn.cxx27
-rw-r--r--vncviewer/CConn.h10
-rw-r--r--vncviewer/DesktopWindow.cxx27
-rw-r--r--vncviewer/DesktopWindow.h16
-rw-r--r--vncviewer/PlatformPixelBuffer.cxx16
-rw-r--r--vncviewer/PlatformPixelBuffer.h6
-rw-r--r--vncviewer/Viewport.cxx114
-rw-r--r--vncviewer/Viewport.h24
45 files changed, 200 insertions, 363 deletions
diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h
index 8b58e0e5..8e3c84ed 100644
--- a/common/rfb/CMsgHandler.h
+++ b/common/rfb/CMsgHandler.h
@@ -66,15 +66,6 @@ namespace rfb {
virtual void bell() = 0;
virtual void serverCutText(const char* str, rdr::U32 len) = 0;
- virtual void fillRect(const Rect& r, Pixel pix) = 0;
- virtual void imageRect(const Rect& r, void* pixels) = 0;
- virtual void copyRect(const Rect& r, int srcX, int srcY) = 0;
-
- virtual rdr::U8* getRawBufferRW(const Rect& r, int* stride) = 0;
- virtual void releaseRawBuffer(const Rect& r) = 0;
-
- virtual const PixelFormat &getPreferredPF(void) = 0;
-
ConnParams cp;
};
}
diff --git a/common/rfb/CopyRectDecoder.cxx b/common/rfb/CopyRectDecoder.cxx
index bb3084fd..4b104189 100644
--- a/common/rfb/CopyRectDecoder.cxx
+++ b/common/rfb/CopyRectDecoder.cxx
@@ -17,7 +17,6 @@
*/
#include <rdr/InStream.h>
#include <rfb/CConnection.h>
-#include <rfb/CMsgHandler.h>
#include <rfb/PixelBuffer.h>
#include <rfb/CopyRectDecoder.h>
@@ -31,9 +30,9 @@ CopyRectDecoder::~CopyRectDecoder()
{
}
-void CopyRectDecoder::readRect(const Rect& r, CMsgHandler* handler)
+void CopyRectDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
{
int srcX = conn->getInStream()->readU16();
int srcY = conn->getInStream()->readU16();
- handler->copyRect(r, srcX, srcY);
+ pb->copyRect(r, Point(r.tl.x-srcX, r.tl.y-srcY));
}
diff --git a/common/rfb/CopyRectDecoder.h b/common/rfb/CopyRectDecoder.h
index 5932066b..d14bf926 100644
--- a/common/rfb/CopyRectDecoder.h
+++ b/common/rfb/CopyRectDecoder.h
@@ -26,7 +26,7 @@ namespace rfb {
public:
CopyRectDecoder(CConnection* conn);
virtual ~CopyRectDecoder();
- virtual void readRect(const Rect& r, CMsgHandler* handler);
+ virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/Decoder.h b/common/rfb/Decoder.h
index 870fa80e..ff67f578 100644
--- a/common/rfb/Decoder.h
+++ b/common/rfb/Decoder.h
@@ -23,13 +23,19 @@
namespace rfb {
class CConnection;
- class CMsgHandler;
+ class ModifiablePixelBuffer;
class Decoder {
public:
Decoder(CConnection* conn);
virtual ~Decoder();
- virtual void readRect(const Rect& r, CMsgHandler* handler)=0;
+
+ // readRect() is the main interface that decodes the given rectangle
+ // with data from the CConnection, given at decoder creation, onto
+ // the ModifiablePixelBuffer. The PixelFormat of the PixelBuffer might
+ // not match the ConnParams and it is up to the decoder to do
+ // any necessary conversion.
+ virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb)=0;
static bool supported(int encoding);
static Decoder* createDecoder(int encoding, CConnection* conn);
diff --git a/common/rfb/Encoder.h b/common/rfb/Encoder.h
index 2897f9f8..aeeb5c34 100644
--- a/common/rfb/Encoder.h
+++ b/common/rfb/Encoder.h
@@ -21,11 +21,10 @@
#define __RFB_ENCODER_H__
#include <rfb/Rect.h>
-#include <rfb/TransImageGetter.h>
namespace rfb {
class SConnection;
- class TransImageGetter;
+ class PixelBuffer;
class Encoder {
public:
@@ -38,9 +37,11 @@ namespace rfb {
virtual int getNumRects(const Rect &r) { return 1; }
// writeRect() is the main interface that encodes the given rectangle
- // with data from the ImageGetter onto the SMsgWriter given at
- // encoder creation.
- virtual void writeRect(const Rect& r, TransImageGetter* ig)=0;
+ // with data from the PixelBuffer onto the SConnection given at
+ // encoder creation. The PixelFormat of the PixelBuffer might not
+ // match the ConnParams and it is up ot the encoder to do
+ // any necessary conversion.
+ virtual void writeRect(const Rect& r, PixelBuffer* pb)=0;
static bool supported(int encoding);
static Encoder* createEncoder(int encoding, SConnection* conn);
diff --git a/common/rfb/HextileDecoder.cxx b/common/rfb/HextileDecoder.cxx
index 9b335fe9..8b18b7bf 100644
--- a/common/rfb/HextileDecoder.cxx
+++ b/common/rfb/HextileDecoder.cxx
@@ -17,7 +17,7 @@
*/
#include <rfb/CMsgReader.h>
#include <rfb/CConnection.h>
-#include <rfb/CMsgHandler.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/HextileDecoder.h>
using namespace rfb;
@@ -40,13 +40,14 @@ HextileDecoder::~HextileDecoder()
{
}
-void HextileDecoder::readRect(const Rect& r, CMsgHandler* handler)
+void HextileDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
{
rdr::InStream* is = conn->getInStream();
rdr::U8* buf = conn->reader()->getImageBuf(16 * 16 * 4);
- switch (conn->cp.pf().bpp) {
- case 8: hextileDecode8 (r, is, (rdr::U8*) buf, handler); break;
- case 16: hextileDecode16(r, is, (rdr::U16*)buf, handler); break;
- case 32: hextileDecode32(r, is, (rdr::U32*)buf, handler); break;
+ const PixelFormat& pf = conn->cp.pf();
+ switch (pf.bpp) {
+ case 8: hextileDecode8 (r, is, (rdr::U8*) buf, pf, pb); break;
+ case 16: hextileDecode16(r, is, (rdr::U16*)buf, pf, pb); break;
+ case 32: hextileDecode32(r, is, (rdr::U32*)buf, pf, pb); break;
}
}
diff --git a/common/rfb/HextileDecoder.h b/common/rfb/HextileDecoder.h
index 67dc791a..ffc495e4 100644
--- a/common/rfb/HextileDecoder.h
+++ b/common/rfb/HextileDecoder.h
@@ -26,7 +26,7 @@ namespace rfb {
public:
HextileDecoder(CConnection* conn);
virtual ~HextileDecoder();
- virtual void readRect(const Rect& r, CMsgHandler* handler);
+ virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/HextileEncoder.cxx b/common/rfb/HextileEncoder.cxx
index aa1b218a..58cf7414 100644
--- a/common/rfb/HextileEncoder.cxx
+++ b/common/rfb/HextileEncoder.cxx
@@ -16,11 +16,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
-#include <rfb/TransImageGetter.h>
#include <rfb/encodings.h>
#include <rfb/SMsgWriter.h>
#include <rfb/SConnection.h>
#include <rfb/HextileEncoder.h>
+#include <rfb/PixelFormat.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/Configuration.h>
using namespace rfb;
@@ -52,30 +53,31 @@ HextileEncoder::~HextileEncoder()
{
}
-void HextileEncoder::writeRect(const Rect& r, TransImageGetter* ig)
+void HextileEncoder::writeRect(const Rect& r, PixelBuffer* pb)
{
conn->writer()->startRect(r, encodingHextile);
rdr::OutStream* os = conn->getOutStream();
- switch (conn->cp.pf().bpp) {
+ const PixelFormat& pf = conn->cp.pf();
+ switch (pf.bpp) {
case 8:
if (improvedHextile) {
- hextileEncodeBetter8(r, os, ig);
+ hextileEncodeBetter8(r, os, pf, pb);
} else {
- hextileEncode8(r, os, ig);
+ hextileEncode8(r, os, pf, pb);
}
break;
case 16:
if (improvedHextile) {
- hextileEncodeBetter16(r, os, ig);
+ hextileEncodeBetter16(r, os, pf, pb);
} else {
- hextileEncode16(r, os, ig);
+ hextileEncode16(r, os, pf, pb);
}
break;
case 32:
if (improvedHextile) {
- hextileEncodeBetter32(r, os, ig);
+ hextileEncodeBetter32(r, os, pf, pb);
} else {
- hextileEncode32(r, os, ig);
+ hextileEncode32(r, os, pf, pb);
}
break;
}
diff --git a/common/rfb/HextileEncoder.h b/common/rfb/HextileEncoder.h
index 723f5391..82fa2ec7 100644
--- a/common/rfb/HextileEncoder.h
+++ b/common/rfb/HextileEncoder.h
@@ -26,7 +26,7 @@ namespace rfb {
public:
HextileEncoder(SConnection* conn);
virtual ~HextileEncoder();
- virtual void writeRect(const Rect& r, TransImageGetter* ig);
+ virtual void writeRect(const Rect& r, PixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/RREDecoder.cxx b/common/rfb/RREDecoder.cxx
index ecc97136..8dc391a8 100644
--- a/common/rfb/RREDecoder.cxx
+++ b/common/rfb/RREDecoder.cxx
@@ -17,7 +17,7 @@
*/
#include <rfb/CMsgReader.h>
#include <rfb/CConnection.h>
-#include <rfb/CMsgHandler.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/RREDecoder.h>
using namespace rfb;
@@ -40,12 +40,13 @@ RREDecoder::~RREDecoder()
{
}
-void RREDecoder::readRect(const Rect& r, CMsgHandler* handler)
+void RREDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
{
rdr::InStream* is = conn->getInStream();
- switch (conn->cp.pf().bpp) {
- case 8: rreDecode8 (r, is, handler); break;
- case 16: rreDecode16(r, is, handler); break;
- case 32: rreDecode32(r, is, handler); break;
+ const PixelFormat& pf = conn->cp.pf();
+ switch (pf.bpp) {
+ case 8: rreDecode8 (r, is, pf, pb); break;
+ case 16: rreDecode16(r, is, pf, pb); break;
+ case 32: rreDecode32(r, is, pf, pb); break;
}
}
diff --git a/common/rfb/RREDecoder.h b/common/rfb/RREDecoder.h
index 7b6cc458..b33bc551 100644
--- a/common/rfb/RREDecoder.h
+++ b/common/rfb/RREDecoder.h
@@ -26,7 +26,7 @@ namespace rfb {
public:
RREDecoder(CConnection* conn);
virtual ~RREDecoder();
- virtual void readRect(const Rect& r, CMsgHandler* handler);
+ virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/RREEncoder.cxx b/common/rfb/RREEncoder.cxx
index a7af25db..6e23ad33 100644
--- a/common/rfb/RREEncoder.cxx
+++ b/common/rfb/RREEncoder.cxx
@@ -16,10 +16,11 @@
* USA.
*/
#include <rdr/OutStream.h>
-#include <rfb/TransImageGetter.h>
#include <rfb/encodings.h>
#include <rfb/SMsgWriter.h>
#include <rfb/SConnection.h>
+#include <rfb/PixelFormat.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/RREEncoder.h>
using namespace rfb;
@@ -42,12 +43,12 @@ RREEncoder::~RREEncoder()
{
}
-void RREEncoder::writeRect(const Rect& r, TransImageGetter* ig)
+void RREEncoder::writeRect(const Rect& r, PixelBuffer* pb)
{
int w = r.width();
int h = r.height();
rdr::U8* imageBuf = conn->writer()->getImageBuf(w*h);
- ig->getImage(imageBuf, r);
+ pb->getImage(conn->cp.pf(), imageBuf, r);
mos.clear();
@@ -59,7 +60,7 @@ void RREEncoder::writeRect(const Rect& r, TransImageGetter* ig)
}
if (nSubrects < 0) {
- RawEncoder::writeRect(r, ig);
+ RawEncoder::writeRect(r, pb);
return;
}
diff --git a/common/rfb/RREEncoder.h b/common/rfb/RREEncoder.h
index 487344f2..57c15840 100644
--- a/common/rfb/RREEncoder.h
+++ b/common/rfb/RREEncoder.h
@@ -27,7 +27,7 @@ namespace rfb {
public:
RREEncoder(SConnection* conn);
virtual ~RREEncoder();
- virtual void writeRect(const Rect& r, TransImageGetter* ig);
+ virtual void writeRect(const Rect& r, PixelBuffer* pb);
private:
rdr::MemOutStream mos;
};
diff --git a/common/rfb/RawDecoder.cxx b/common/rfb/RawDecoder.cxx
index 6ca02026..d2b3d06d 100644
--- a/common/rfb/RawDecoder.cxx
+++ b/common/rfb/RawDecoder.cxx
@@ -18,7 +18,7 @@
#include <rdr/InStream.h>
#include <rfb/CMsgReader.h>
#include <rfb/CConnection.h>
-#include <rfb/CMsgHandler.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/RawDecoder.h>
using namespace rfb;
@@ -31,7 +31,7 @@ RawDecoder::~RawDecoder()
{
}
-void RawDecoder::readRect(const Rect& r, CMsgHandler* handler)
+void RawDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
{
int x = r.tl.x;
int y = r.tl.y;
@@ -39,12 +39,13 @@ void RawDecoder::readRect(const Rect& r, CMsgHandler* handler)
int h = r.height();
int nPixels;
rdr::U8* imageBuf = conn->reader()->getImageBuf(w, w*h, &nPixels);
- int bytesPerRow = w * (conn->cp.pf().bpp / 8);
+ const PixelFormat& pf = conn->cp.pf();
+ int bytesPerRow = w * (pf.bpp / 8);
while (h > 0) {
int nRows = nPixels / w;
if (nRows > h) nRows = h;
conn->getInStream()->readBytes(imageBuf, nRows * bytesPerRow);
- handler->imageRect(Rect(x, y, x+w, y+nRows), imageBuf);
+ pb->imageRect(pf, Rect(x, y, x+w, y+nRows), imageBuf);
h -= nRows;
y += nRows;
}
diff --git a/common/rfb/RawDecoder.h b/common/rfb/RawDecoder.h
index ca7c4017..7a784c64 100644
--- a/common/rfb/RawDecoder.h
+++ b/common/rfb/RawDecoder.h
@@ -26,7 +26,7 @@ namespace rfb {
public:
RawDecoder(CConnection* conn);
virtual ~RawDecoder();
- virtual void readRect(const Rect& r, CMsgHandler* handler);
+ virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/RawEncoder.cxx b/common/rfb/RawEncoder.cxx
index f7a4f3b8..e50ebc70 100644
--- a/common/rfb/RawEncoder.cxx
+++ b/common/rfb/RawEncoder.cxx
@@ -16,10 +16,10 @@
* USA.
*/
#include <rdr/OutStream.h>
-#include <rfb/TransImageGetter.h>
#include <rfb/encodings.h>
#include <rfb/SMsgWriter.h>
#include <rfb/SConnection.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/RawEncoder.h>
using namespace rfb;
@@ -32,23 +32,13 @@ RawEncoder::~RawEncoder()
{
}
-void RawEncoder::writeRect(const Rect& r, TransImageGetter* ig)
+void RawEncoder::writeRect(const Rect& r, PixelBuffer* pb)
{
- int x = r.tl.x;
- int y = r.tl.y;
- int w = r.width();
- int h = r.height();
- int nPixels;
- rdr::U8* imageBuf = conn->writer()->getImageBuf(w, w*h, &nPixels);
- int bytesPerRow = w * (conn->cp.pf().bpp / 8);
+ rdr::U8* buf = conn->writer()->getImageBuf(r.area());
+
+ pb->getImage(conn->cp.pf(), buf, r);
+
conn->writer()->startRect(r, encodingRaw);
- while (h > 0) {
- int nRows = nPixels / w;
- if (nRows > h) nRows = h;
- ig->getImage(imageBuf, Rect(x, y, x+w, y+nRows));
- conn->getOutStream()->writeBytes(imageBuf, nRows * bytesPerRow);
- h -= nRows;
- y += nRows;
- }
+ conn->getOutStream()->writeBytes(buf, r.area() * conn->cp.pf().bpp/8);
conn->writer()->endRect();
}
diff --git a/common/rfb/RawEncoder.h b/common/rfb/RawEncoder.h
index 59e3a6de..c2d9f250 100644
--- a/common/rfb/RawEncoder.h
+++ b/common/rfb/RawEncoder.h
@@ -26,7 +26,7 @@ namespace rfb {
public:
RawEncoder(SConnection* conn);
virtual ~RawEncoder();
- virtual void writeRect(const Rect& r, TransImageGetter* ig);
+ virtual void writeRect(const Rect& r, PixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx
index bfc3352b..5f4142b4 100644
--- a/common/rfb/TightDecoder.cxx
+++ b/common/rfb/TightDecoder.cxx
@@ -19,7 +19,7 @@
*/
#include <rfb/CMsgReader.h>
#include <rfb/CConnection.h>
-#include <rfb/CMsgHandler.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/TightDecoder.h>
using namespace rfb;
@@ -44,12 +44,12 @@ TightDecoder::~TightDecoder()
{
}
-void TightDecoder::readRect(const Rect& r, CMsgHandler* handler)
+void TightDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
{
is = conn->getInStream();
- this->handler = handler;
- clientpf = handler->getPreferredPF();
- serverpf = handler->cp.pf();
+ this->pb = pb;
+ clientpf = pb->getPF();
+ serverpf = conn->cp.pf();
if (clientpf.equal(serverpf)) {
/* Decode directly into the framebuffer (fast path) */
diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h
index 2ca4ecd6..66fa9a0c 100644
--- a/common/rfb/TightDecoder.h
+++ b/common/rfb/TightDecoder.h
@@ -30,7 +30,7 @@ namespace rfb {
public:
TightDecoder(CConnection* conn);
virtual ~TightDecoder();
- virtual void readRect(const Rect& r, CMsgHandler* handler);
+ virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
private:
rdr::U32 readCompact(rdr::InStream* is);
@@ -56,7 +56,7 @@ namespace rfb {
void directFillRect16(const Rect& r, Pixel pix);
void directFillRect32(const Rect& r, Pixel pix);
- CMsgHandler* handler;
+ ModifiablePixelBuffer* pb;
rdr::InStream* is;
rdr::ZlibInStream zis[4];
JpegDecompressor jd;
diff --git a/common/rfb/TightEncoder.cxx b/common/rfb/TightEncoder.cxx
index c3f87dab..cdc23c4e 100644
--- a/common/rfb/TightEncoder.cxx
+++ b/common/rfb/TightEncoder.cxx
@@ -17,7 +17,6 @@
* USA.
*/
#include <rdr/OutStream.h>
-#include <rfb/TransImageGetter.h>
#include <rfb/PixelBuffer.h>
#include <rfb/encodings.h>
#include <rfb/ConnParams.h>
@@ -287,10 +286,10 @@ void TightEncoder::sendRectSimple(const Rect& r)
}
}
-void TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig)
+void TightEncoder::writeRect(const Rect& _r, PixelBuffer* _pb)
{
- ig = _ig;
- serverpf = ig->getPixelBuffer()->getPF();
+ pb = _pb;
+ serverpf = pb->getPF();
ConnParams* cp = &conn->cp;
clientpf = cp->pf();
@@ -366,7 +365,7 @@ void TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig)
}
if (bestr.tl.x != x) {
sr.setXYWH(x, bestr.tl.y, bestr.tl.x - x, bestr.height());
- writeRect(sr, _ig);
+ writeRect(sr, _pb);
}
// Send solid-color rectangle.
@@ -376,11 +375,11 @@ void TightEncoder::writeRect(const Rect& _r, TransImageGetter* _ig)
if (bestr.br.x != r.br.x) {
sr.setXYWH(bestr.br.x, bestr.tl.y, r.br.x - bestr.br.x,
bestr.height());
- writeRect(sr, _ig);
+ writeRect(sr, _pb);
}
if (bestr.br.y != r.br.y) {
sr.setXYWH(x, bestr.br.y, w, r.br.y - bestr.br.y);
- writeRect(sr, _ig);
+ writeRect(sr, _pb);
}
return;
diff --git a/common/rfb/TightEncoder.h b/common/rfb/TightEncoder.h
index 8a58985e..89d096b2 100644
--- a/common/rfb/TightEncoder.h
+++ b/common/rfb/TightEncoder.h
@@ -33,7 +33,7 @@ extern "C" {
namespace rfb {
- class TransImageGetter;
+ class PixelBuffer;
struct TIGHT_CONF {
unsigned int maxRectSize, maxRectWidth;
@@ -65,7 +65,7 @@ namespace rfb {
virtual void setQualityLevel(int level);
virtual void setFineQualityLevel(int quality, int subsampling);
virtual int getNumRects(const Rect &r);
- virtual void writeRect(const Rect& r, TransImageGetter* ig);
+ virtual void writeRect(const Rect& r, PixelBuffer* pb);
private:
bool checkSolidTile(Rect& r, rdr::U32* colorPtr, bool needSameColor);
@@ -123,7 +123,7 @@ namespace rfb {
rdr::MemOutStream mos;
rdr::ZlibOutStream zos[4];
JpegCompressor jc;
- TransImageGetter *ig;
+ PixelBuffer *pb;
PixelFormat serverpf, clientpf;
bool pack24;
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index e7123000..e1424b72 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -71,8 +71,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
fenceDataLen(0), fenceData(NULL),
baseRTT(-1), minRTT(-1), seenCongestion(false), pingCounter(0),
ackedOffset(0), sentOffset(0), congWindow(0), congestionTimer(this),
- server(server_),
- updates(false), image_getter(server->useEconomicTranslate),
+ server(server_), updates(false),
drawRenderedCursor(false), removeRenderedCursor(false),
continuousUpdates(false),
updateTimer(this), pointerEventTime(0),
@@ -233,8 +232,6 @@ void VNCSConnectionST::pixelBufferChange()
// work out what's actually changed.
updates.clear();
updates.add_changed(server->pb->getRect());
- vlog.debug("pixel buffer changed - re-initialising image getter");
- image_getter.init(server->pb, cp.pf(), writer());
writeFramebufferUpdate();
} catch(rdr::Exception &e) {
close(e.str());
@@ -404,7 +401,6 @@ void VNCSConnectionST::authSuccess()
char buffer[256];
cp.pf().print(buffer, 256);
vlog.info("Server default pixel format %s", buffer);
- image_getter.init(server->pb, cp.pf(), 0);
// - Mark the entire display as "dirty"
updates.add_changed(server->pb->getRect());
@@ -478,7 +474,6 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf)
char buffer[256];
pf.print(buffer, 256);
vlog.info("Client pixel format %s", buffer);
- image_getter.init(server->pb, pf, writer());
setCursor();
}
@@ -1036,16 +1031,20 @@ void VNCSConnectionST::writeFramebufferUpdate()
std::vector<Rect>::const_iterator i;
int encoding;
+ Encoder* encoder;
+ PixelBuffer* pb;
+
// Make sure the encoder has the latest settings
encoding = cp.currentEncoding();
if (!encoders[encoding])
encoders[encoding] = Encoder::createEncoder(encoding, this);
- encoders[encoding]->setCompressLevel(cp.compressLevel);
- encoders[encoding]->setQualityLevel(cp.qualityLevel);
- encoders[encoding]->setFineQualityLevel(cp.fineQualityLevel,
- cp.subsampling);
+ encoder = encoders[encoding];
+
+ encoder->setCompressLevel(cp.compressLevel);
+ encoder->setQualityLevel(cp.qualityLevel);
+ encoder->setFineQualityLevel(cp.fineQualityLevel, cp.subsampling);
// Compute the number of rectangles. Tight encoder makes the things more
// complicated as compared to the original VNC4.
@@ -1055,7 +1054,7 @@ void VNCSConnectionST::writeFramebufferUpdate()
ui.changed.get_rects(&rects);
for (i = rects.begin(); i != rects.end(); i++) {
if (i->width() && i->height()) {
- int nUpdateRects = encoders[encoding]->getNumRects(*i);
+ int nUpdateRects = encoder->getNumRects(*i);
if (nUpdateRects == 0 && cp.currentEncoding() == encodingTight) {
// With Tight encoding and LastRect support, the client does not
// care about the number of rectangles in the update - it will
@@ -1077,14 +1076,15 @@ void VNCSConnectionST::writeFramebufferUpdate()
writer()->writeCopyRect(*i, i->tl.x - ui.copy_delta.x,
i->tl.y - ui.copy_delta.y);
+ pb = server->getPixelBuffer();
+
ui.changed.get_rects(&rects);
for (i = rects.begin(); i != rects.end(); i++)
- encoders[encoding]->writeRect(*i, &image_getter);
+ encoder->writeRect(*i, pb);
if (drawRenderedCursor) {
- image_getter.setPixelBuffer(&server->renderedCursor);
- encoders[encoding]->writeRect(renderedCursorRect, &image_getter);
- image_getter.setPixelBuffer(server->pb);
+ renderedCursorRect = server->renderedCursor.getEffectiveRect();
+ encoder->writeRect(renderedCursorRect, &server->renderedCursor);
drawRenderedCursor = false;
}
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index c918c599..6adeac27 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -30,7 +30,6 @@
#include <set>
#include <rfb/SConnection.h>
#include <rfb/SMsgWriter.h>
-#include <rfb/TransImageGetter.h>
#include <rfb/VNCServerST.h>
#include <rfb/Timer.h>
@@ -193,7 +192,6 @@ namespace rfb {
VNCServerST* server;
SimpleUpdateTracker updates;
- TransImageGetter image_getter;
Region requested;
bool drawRenderedCursor, removeRenderedCursor;
Rect renderedCursorRect;
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 27eb605a..51cb86cf 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -84,7 +84,6 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
name(strDup(name_)), pointerClient(0), comparer(0),
renderedCursorInvalid(false),
queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance),
- useEconomicTranslate(false),
lastConnectionTime(0), disableclients(false),
deferTimer(this), deferPending(false)
{
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index ede52236..1e055dd9 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -177,12 +177,6 @@ namespace rfb {
// Blacklist to be shared by multiple VNCServerST instances.
void setBlacklist(Blacklist* bl) {blHosts = bl ? bl : &blacklist;}
- // setEconomicTranslate() determines (for new connections) whether pixels
- // should be translated for <=16bpp clients using a large lookup table
- // (fast) or separate, smaller R, G and B tables (slower). If set to true,
- // small tables are used, to save memory.
- void setEconomicTranslate(bool et) { useEconomicTranslate = et; }
-
// setKeyRemapper() replaces the VNCServerST's default key remapper.
// NB: A null pointer is valid here.
void setKeyRemapper(KeyRemapper* kr) { keyRemapper = kr; }
@@ -242,8 +236,7 @@ namespace rfb {
QueryConnectionHandler* queryConnectionHandler;
KeyRemapper* keyRemapper;
- bool useEconomicTranslate;
-
+
time_t lastUserInputTime;
time_t lastDisconnectTime;
time_t lastConnectionTime;
diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx
index 7e933a8f..60e5dd14 100644
--- a/common/rfb/ZRLEDecoder.cxx
+++ b/common/rfb/ZRLEDecoder.cxx
@@ -17,7 +17,7 @@
*/
#include <rfb/CMsgReader.h>
#include <rfb/CConnection.h>
-#include <rfb/CMsgHandler.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/ZRLEDecoder.h>
using namespace rfb;
@@ -66,17 +66,16 @@ ZRLEDecoder::~ZRLEDecoder()
{
}
-void ZRLEDecoder::readRect(const Rect& r, CMsgHandler* handler)
+void ZRLEDecoder::readRect(const Rect& r, ModifiablePixelBuffer* pb)
{
rdr::InStream* is = conn->getInStream();
rdr::U8* buf = conn->reader()->getImageBuf(64 * 64 * 4);
- switch (conn->cp.pf().bpp) {
- case 8: zrleDecode8 (r, is, &zis, (rdr::U8*) buf, handler); break;
- case 16: zrleDecode16(r, is, &zis, (rdr::U16*)buf, handler); break;
+ const rfb::PixelFormat& pf = conn->cp.pf();
+ switch (pf.bpp) {
+ case 8: zrleDecode8 (r, is, &zis, (rdr::U8*) buf, pf, pb); break;
+ case 16: zrleDecode16(r, is, &zis, (rdr::U16*)buf, pf, pb); break;
case 32:
{
- const rfb::PixelFormat& pf = handler->cp.pf();
-
Pixel maxPixel = pf.pixelFromRGB((rdr::U16)-1, (rdr::U16)-1, (rdr::U16)-1);
bool fitsInLS3Bytes = maxPixel < (1<<24);
bool fitsInMS3Bytes = (maxPixel & 0xff) == 0;
@@ -84,16 +83,16 @@ void ZRLEDecoder::readRect(const Rect& r, CMsgHandler* handler)
if ((fitsInLS3Bytes && pf.isLittleEndian()) ||
(fitsInMS3Bytes && pf.isBigEndian()))
{
- zrleDecode24A(r, is, &zis, (rdr::U32*)buf, handler);
+ zrleDecode24A(r, is, &zis, (rdr::U32*)buf, pf, pb);
}
else if ((fitsInLS3Bytes && pf.isBigEndian()) ||
(fitsInMS3Bytes && pf.isLittleEndian()))
{
- zrleDecode24B(r, is, &zis, (rdr::U32*)buf, handler);
+ zrleDecode24B(r, is, &zis, (rdr::U32*)buf, pf, pb);
}
else
{
- zrleDecode32(r, is, &zis, (rdr::U32*)buf, handler);
+ zrleDecode32(r, is, &zis, (rdr::U32*)buf, pf, pb);
}
break;
}
diff --git a/common/rfb/ZRLEDecoder.h b/common/rfb/ZRLEDecoder.h
index e7e2b8cb..492597e3 100644
--- a/common/rfb/ZRLEDecoder.h
+++ b/common/rfb/ZRLEDecoder.h
@@ -27,7 +27,7 @@ namespace rfb {
public:
ZRLEDecoder(CConnection* conn);
virtual ~ZRLEDecoder();
- virtual void readRect(const Rect& r, CMsgHandler* handler);
+ virtual void readRect(const Rect& r, ModifiablePixelBuffer* pb);
private:
rdr::ZlibInStream zis;
};
diff --git a/common/rfb/ZRLEEncoder.cxx b/common/rfb/ZRLEEncoder.cxx
index 968edcfb..54613e2d 100644
--- a/common/rfb/ZRLEEncoder.cxx
+++ b/common/rfb/ZRLEEncoder.cxx
@@ -17,7 +17,6 @@
*/
#include <rdr/OutStream.h>
#include <rfb/Exception.h>
-#include <rfb/TransImageGetter.h>
#include <rfb/encodings.h>
#include <rfb/ConnParams.h>
#include <rfb/SMsgWriter.h>
@@ -69,22 +68,22 @@ ZRLEEncoder::~ZRLEEncoder()
{
}
-void ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig)
+void ZRLEEncoder::writeRect(const Rect& r, PixelBuffer* pb)
{
+ const PixelFormat& pf = conn->cp.pf();
+
rdr::U8* imageBuf = conn->writer()->getImageBuf(64 * 64 * 4 + 4);
mos.clear();
- switch (conn->cp.pf().bpp) {
+ switch (pf.bpp) {
case 8:
- zrleEncode8(r, &mos, &zos, imageBuf, ig);
+ zrleEncode8(r, &mos, &zos, imageBuf, pf, pb);
break;
case 16:
- zrleEncode16(r, &mos, &zos, imageBuf, ig);
+ zrleEncode16(r, &mos, &zos, imageBuf, pf, pb);
break;
case 32:
{
- const PixelFormat& pf = conn->cp.pf();
-
Pixel maxPixel = pf.pixelFromRGB((rdr::U16)-1, (rdr::U16)-1, (rdr::U16)-1);
bool fitsInLS3Bytes = maxPixel < (1<<24);
bool fitsInMS3Bytes = (maxPixel & 0xff) == 0;
@@ -92,16 +91,16 @@ void ZRLEEncoder::writeRect(const Rect& r, TransImageGetter* ig)
if ((fitsInLS3Bytes && pf.isLittleEndian()) ||
(fitsInMS3Bytes && pf.isBigEndian()))
{
- zrleEncode24A(r, &mos, &zos, imageBuf, ig);
+ zrleEncode24A(r, &mos, &zos, imageBuf, pf, pb);
}
else if ((fitsInLS3Bytes && pf.isBigEndian()) ||
(fitsInMS3Bytes && pf.isLittleEndian()))
{
- zrleEncode24B(r, &mos, &zos, imageBuf, ig);
+ zrleEncode24B(r, &mos, &zos, imageBuf, pf, pb);
}
else
{
- zrleEncode32(r, &mos, &zos, imageBuf, ig);
+ zrleEncode32(r, &mos, &zos, imageBuf, pf, pb);
}
break;
}
diff --git a/common/rfb/ZRLEEncoder.h b/common/rfb/ZRLEEncoder.h
index d285967e..b006821d 100644
--- a/common/rfb/ZRLEEncoder.h
+++ b/common/rfb/ZRLEEncoder.h
@@ -28,7 +28,7 @@ namespace rfb {
public:
ZRLEEncoder(SConnection* conn);
virtual ~ZRLEEncoder();
- virtual void writeRect(const Rect& r, TransImageGetter* ig);
+ virtual void writeRect(const Rect& r, PixelBuffer* pb);
private:
rdr::ZlibOutStream zos;
rdr::MemOutStream mos;
diff --git a/common/rfb/hextileDecode.h b/common/rfb/hextileDecode.h
index 518a6063..56ba1181 100644
--- a/common/rfb/hextileDecode.h
+++ b/common/rfb/hextileDecode.h
@@ -38,7 +38,7 @@ namespace rfb {
#define HEXTILE_DECODE CONCAT2E(hextileDecode,BPP)
void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf,
- CMsgHandler* handler)
+ const PixelFormat& pf, ModifiablePixelBuffer* pb)
{
Rect t;
PIXEL_T bg = 0;
@@ -56,7 +56,7 @@ void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf,
if (tileType & hextileRaw) {
is->readBytes(buf, t.area() * (BPP/8));
- handler->imageRect(t, buf);
+ pb->imageRect(pf, t, buf);
continue;
}
@@ -94,7 +94,7 @@ void HEXTILE_DECODE (const Rect& r, rdr::InStream* is, PIXEL_T* buf,
}
}
}
- handler->imageRect(t, buf);
+ pb->imageRect(pf, t, buf);
}
}
}
diff --git a/common/rfb/hextileEncode.h b/common/rfb/hextileEncode.h
index 7e5b2db7..2efd74ee 100644
--- a/common/rfb/hextileEncode.h
+++ b/common/rfb/hextileEncode.h
@@ -44,7 +44,8 @@ int TEST_TILE_TYPE (PIXEL_T* data, int w, int h, PIXEL_T* bg, PIXEL_T* fg);
int HEXTILE_ENCODE_TILE (PIXEL_T* data, int w, int h, int tileType,
rdr::U8* encoded, PIXEL_T bg);
-void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig)
+void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os,
+ const PixelFormat& pf, PixelBuffer* pb)
{
Rect t;
PIXEL_T buf[256];
@@ -61,7 +62,7 @@ void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig)
t.br.x = __rfbmin(r.br.x, t.tl.x + 16);
- ig->getImage(buf, t);
+ pb->getImage(pf, buf, t);
PIXEL_T bg = 0, fg = 0;
int tileType = TEST_TILE_TYPE(buf, t.width(), t.height(), &bg, &fg);
@@ -90,7 +91,7 @@ void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig)
encoded, bg);
if (encodedLen < 0) {
- ig->getImage(buf, t);
+ pb->getImage(pf, buf, t);
os->writeU8(hextileRaw);
os->writeBytes(buf, t.width() * t.height() * (BPP/8));
oldBgValid = oldFgValid = false;
diff --git a/common/rfb/hextileEncodeBetter.h b/common/rfb/hextileEncodeBetter.h
index 3a96ab63..efb2d9ca 100644
--- a/common/rfb/hextileEncodeBetter.h
+++ b/common/rfb/hextileEncodeBetter.h
@@ -275,7 +275,8 @@ void HEXTILE_TILE::encode(rdr::U8 *dst) const
// Main encoding function.
//
-void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig)
+void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os,
+ const PixelFormat& pf, PixelBuffer* pb)
{
Rect t;
PIXEL_T buf[256];
@@ -294,7 +295,7 @@ void HEXTILE_ENCODE(const Rect& r, rdr::OutStream* os, TransImageGetter *ig)
t.br.x = __rfbmin(r.br.x, t.tl.x + 16);
- ig->getImage(buf, t);
+ pb->getImage(pf, buf, t);
tile.newTile(buf, t.width(), t.height());
int tileType = tile.getFlags();
diff --git a/common/rfb/rreDecode.h b/common/rfb/rreDecode.h
index d37461f9..9dc04703 100644
--- a/common/rfb/rreDecode.h
+++ b/common/rfb/rreDecode.h
@@ -36,11 +36,12 @@ namespace rfb {
#define READ_PIXEL CONCAT2E(readOpaque,BPP)
#define RRE_DECODE CONCAT2E(rreDecode,BPP)
-void RRE_DECODE (const Rect& r, rdr::InStream* is, CMsgHandler* handler)
+void RRE_DECODE (const Rect& r, rdr::InStream* is,
+ const PixelFormat& pf, ModifiablePixelBuffer* pb)
{
int nSubrects = is->readU32();
PIXEL_T bg = is->READ_PIXEL();
- handler->fillRect(r, bg);
+ pb->fillRect(pf, r, bg);
for (int i = 0; i < nSubrects; i++) {
PIXEL_T pix = is->READ_PIXEL();
@@ -48,7 +49,7 @@ void RRE_DECODE (const Rect& r, rdr::InStream* is, CMsgHandler* handler)
int y = is->readU16();
int w = is->readU16();
int h = is->readU16();
- handler->fillRect(Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix);
+ pb->fillRect(pf, Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), pix);
}
}
diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h
index a5963119..53dbba7e 100644
--- a/common/rfb/tightDecode.h
+++ b/common/rfb/tightDecode.h
@@ -77,7 +77,7 @@ void TIGHT_DECODE (const Rect& r)
} else {
pix = is->READ_PIXEL();
}
- handler->fillRect(r, pix);
+ pb->fillRect(serverpf, r, pix);
return;
}
@@ -153,7 +153,7 @@ void TIGHT_DECODE (const Rect& r)
PIXEL_T *buf;
int stride = r.width();
- if (directDecode) buf = (PIXEL_T *)handler->getRawBufferRW(r, &stride);
+ if (directDecode) buf = (PIXEL_T *)pb->getBufferRW(r, &stride);
else buf = (PIXEL_T *)conn->reader()->getImageBuf(r.area());
if (palSize == 0) {
@@ -225,8 +225,8 @@ void TIGHT_DECODE (const Rect& r)
}
}
- if (directDecode) handler->releaseRawBuffer(r);
- else handler->imageRect(r, buf);
+ if (directDecode) pb->commitBufferRW(r);
+ else pb->imageRect(serverpf, r, buf);
delete [] netbuf;
@@ -253,9 +253,9 @@ DECOMPRESS_JPEG_RECT(const Rect& r)
// We always use direct decoding with JPEG images
int stride;
- rdr::U8 *buf = handler->getRawBufferRW(r, &stride);
+ rdr::U8 *buf = pb->getBufferRW(r, &stride);
jd.decompress(netbuf, compressedLen, buf, stride, r, clientpf);
- handler->releaseRawBuffer(r);
+ pb->commitBufferRW(r);
delete [] netbuf;
}
diff --git a/common/rfb/tightEncode.h b/common/rfb/tightEncode.h
index 5d32cce3..1d8acc0e 100644
--- a/common/rfb/tightEncode.h
+++ b/common/rfb/tightEncode.h
@@ -114,7 +114,7 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, bool forceSolid)
{
int stride;
rdr::U32 solidColor;
- const PIXEL_T *rawPixels = (const PIXEL_T *)ig->getRawBufferR(r, &stride);
+ const PIXEL_T *rawPixels = (const PIXEL_T *)pb->getBuffer(r, &stride);
PIXEL_T *pixels = NULL;
bool grayScaleJPEG = (jpegSubsampling == subsampleGray && jpegQuality != -1);
@@ -126,7 +126,8 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, bool forceSolid)
if (forceSolid) {
// Subrectangle has already been determined to be solid.
- ig->translatePixels(rawPixels, &solidColor, 1);
+ clientpf.bufferFromBuffer((rdr::U8*)&solidColor, serverpf,
+ (const rdr::U8*)rawPixels, 1);
pixels = (PIXEL_T *)&solidColor;
palette.clear();
palette.insert(solidColor, 1);
@@ -149,14 +150,14 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, bool forceSolid)
if(palette.size() != 0 || jpegQuality == -1) {
pixels = (PIXEL_T *)conn->writer()->getImageBuf(r.area());
stride = r.width();
- ig->getImage(pixels, r);
+ pb->getImage(clientpf, pixels, r);
}
} else {
// Pixel translation will be required, so create an intermediate buffer,
// translate the raw pixels into it, and count its colors.
pixels = (PIXEL_T *)conn->writer()->getImageBuf(r.area());
stride = r.width();
- ig->getImage(pixels, r);
+ pb->getImage(clientpf, pixels, r);
if (grayScaleJPEG) palette.clear();
else FILL_PALETTE(pixels, r.area());
@@ -443,7 +444,7 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r)
int w = r.width(), h = r.height();
const PIXEL_T *rowptr, *colptr, *rowptr2, *colptr2,
*dataend = &data[stride * h];
- bool willTransform = ig->willTransform();
+ bool willTransform = !serverpf.equal(clientpf);
serverpf.bufferFromPixel((rdr::U8*)&mask, ~0);
@@ -490,8 +491,8 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r)
monodone:
if (willTransform) {
- ig->translatePixels(&c0, &c0t, 1);
- ig->translatePixels(&c1, &c1t, 1);
+ clientpf.bufferFromBuffer((rdr::U8*)&c0t, serverpf, (rdr::U8*)&c0, 1);
+ clientpf.bufferFromBuffer((rdr::U8*)&c1t, serverpf, (rdr::U8*)&c1, 1);
}
else {
c0t = c0; c1t = c1;
@@ -515,7 +516,7 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r)
ni++;
} else {
if (willTransform)
- ig->translatePixels(&ci, &cit, 1);
+ clientpf.bufferFromBuffer((rdr::U8*)&cit, serverpf, (rdr::U8*)&ci, 1);
else
cit = ci;
if (!palette.insert (cit, ni) || (palette.size() > palMaxColors)) {
@@ -529,7 +530,7 @@ void FAST_FILL_PALETTE (const PIXEL_T *data, int stride, const Rect& r)
rowptr += stride;
colptr = rowptr;
}
- ig->translatePixels(&ci, &cit, 1);
+ clientpf.bufferFromBuffer((rdr::U8*)&cit, serverpf, (rdr::U8*)&ci, 1);
if (!palette.insert (cit, ni) || (palette.size() > palMaxColors))
palette.clear();
}
@@ -543,7 +544,7 @@ bool CHECK_SOLID_TILE(Rect& r, rdr::U32 *colorPtr, bool needSameColor)
int w = r.width(), h = r.height();
int stride = w;
- buf = (const PIXEL_T *)ig->getRawBufferR(r, &stride);
+ buf = (const PIXEL_T *)pb->getBuffer(r, &stride);
colorValue = *buf;
if (needSameColor && (rdr::U32)colorValue != *colorPtr)
diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h
index 4bcbf1f0..42b28b32 100644
--- a/common/rfb/zrleDecode.h
+++ b/common/rfb/zrleDecode.h
@@ -48,7 +48,7 @@ namespace rfb {
void ZRLE_DECODE (const Rect& r, rdr::InStream* is,
rdr::ZlibInStream* zis, PIXEL_T* buf,
- CMsgHandler* handler)
+ const PixelFormat& pf, ModifiablePixelBuffer* pb)
{
int length = is->readU32();
zis->setUnderlying(is, length);
@@ -73,7 +73,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is,
if (palSize == 1) {
PIXEL_T pix = palette[0];
- handler->fillRect(t, pix);
+ pb->fillRect(pf, t, pix);
continue;
}
@@ -173,7 +173,7 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is,
//fprintf(stderr,"copying data to screen %dx%d at %d,%d\n",
//t.width(),t.height(),t.tl.x,t.tl.y);
- handler->imageRect(t, buf);
+ pb->imageRect(pf, t, buf);
}
}
diff --git a/common/rfb/zrleEncode.h b/common/rfb/zrleEncode.h
index 8767d541..e5467724 100644
--- a/common/rfb/zrleEncode.h
+++ b/common/rfb/zrleEncode.h
@@ -30,6 +30,7 @@
#include <rdr/OutStream.h>
#include <rdr/ZlibOutStream.h>
#include <rfb/Palette.h>
+#include <rfb/PixelBuffer.h>
#include <assert.h>
namespace rfb {
@@ -66,7 +67,7 @@ void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, rdr::OutStream* os);
void ZRLE_ENCODE (const Rect& r, rdr::OutStream* os,
rdr::ZlibOutStream* zos, void* buf,
- TransImageGetter *ig)
+ const PixelFormat& pf, PixelBuffer* pb)
{
zos->setUnderlying(os);
// RLE overhead is at worst 1 byte per 64x64 (4Kpixel) block
@@ -83,7 +84,7 @@ void ZRLE_ENCODE (const Rect& r, rdr::OutStream* os,
t.br.x = __rfbmin(r.br.x, t.tl.x + 64);
- ig->getImage(buf, t);
+ pb->getImage(pf, buf, t);
ZRLE_ENCODE_TILE((PIXEL_T*)buf, t.width(), t.height(), zos);
}
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index c78bb891..305eddce 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -263,7 +263,6 @@ void CConn::serverInit()
// This initial update request is a bit of a corner case, so we need
// to help out setting the correct format here.
assert(pendingPFChange);
- desktop->setServerPF(pendingPF);
cp.setPF(pendingPF);
pendingPFChange = false;
}
@@ -330,7 +329,6 @@ void CConn::framebufferUpdateEnd()
// A format change has been scheduled and we are now past the update
// with the old format. Time to active the new one.
if (pendingPFChange) {
- desktop->setServerPF(pendingPF);
cp.setPF(pendingPF);
pendingPFChange = false;
}
@@ -405,26 +403,11 @@ void CConn::dataRect(const Rect& r, int encoding)
throw Exception("Unknown rect encoding");
}
}
- decoders[encoding]->readRect(r, this);
+ decoders[encoding]->readRect(r, desktop->getFramebuffer());
sock->inStream().stopTiming();
}
-void CConn::fillRect(const rfb::Rect& r, rfb::Pixel p)
-{
- desktop->fillRect(r,p);
-}
-
-void CConn::imageRect(const rfb::Rect& r, void* p)
-{
- desktop->imageRect(r,p);
-}
-
-void CConn::copyRect(const rfb::Rect& r, int sx, int sy)
-{
- desktop->copyRect(r,sx,sy);
-}
-
void CConn::setCursor(int width, int height, const Point& hotspot,
void* data, void* mask)
{
@@ -461,18 +444,10 @@ void CConn::fence(rdr::U32 flags, unsigned len, const char data[])
pf.read(&memStream);
- desktop->setServerPF(pf);
cp.setPF(pf);
}
}
-rdr::U8* CConn::getRawBufferRW(const rfb::Rect& r, int* stride) {
- return desktop->getBufferRW(r, stride);
-}
-void CConn::releaseRawBuffer(const rfb::Rect& r) {
- desktop->commitBufferRW(r);
-}
-
////////////////////// Internal methods //////////////////////
diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h
index f7f560bc..709ca2f8 100644
--- a/vncviewer/CConn.h
+++ b/vncviewer/CConn.h
@@ -64,18 +64,8 @@ public:
void framebufferUpdateStart();
void framebufferUpdateEnd();
-
void dataRect(const rfb::Rect& r, int encoding);
- void fillRect(const rfb::Rect& r, rfb::Pixel p);
- void imageRect(const rfb::Rect& r, void* p);
- void copyRect(const rfb::Rect& r, int sx, int sy);
-
- rdr::U8* getRawBufferRW(const rfb::Rect& r, int* stride);
- void releaseRawBuffer(const rfb::Rect& r);
-
- const rfb::PixelFormat &getPreferredPF() { return fullColourPF; }
-
void setCursor(int width, int height, const rfb::Point& hotspot,
void* data, void* mask);
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index a64f02a2..d57d57ad 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -193,12 +193,6 @@ DesktopWindow::~DesktopWindow()
}
-void DesktopWindow::setServerPF(const rfb::PixelFormat& pf)
-{
- viewport->setServerPF(pf);
-}
-
-
const rfb::PixelFormat &DesktopWindow::getPreferredPF()
{
return viewport->getPreferredPF();
@@ -216,24 +210,9 @@ void DesktopWindow::setName(const char *name)
}
-void DesktopWindow::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
- viewport->fillRect(r, pix);
-}
-
-void DesktopWindow::imageRect(const rfb::Rect& r, void* pixels) {
- viewport->imageRect(r, pixels);
-}
-
-void DesktopWindow::copyRect(const rfb::Rect& r, int srcX, int srcY) {
- viewport->copyRect(r, srcX, srcY);
-}
-
-rdr::U8* DesktopWindow::getBufferRW(const rfb::Rect& r, int* stride) {
- return viewport->getBufferRW(r, stride);
-}
-
-void DesktopWindow::commitBufferRW(const rfb::Rect& r) {
- viewport->commitBufferRW(r);
+rfb::ModifiablePixelBuffer* DesktopWindow::getFramebuffer(void)
+{
+ return viewport->getFramebuffer();
}
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index 83a8c767..8b91450f 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -27,6 +27,8 @@
#include <FL/Fl_Window.H>
+namespace rfb { class ModifiablePixelBuffer; }
+
class CConn;
class Viewport;
@@ -39,26 +41,22 @@ public:
const rfb::PixelFormat& serverPF, CConn* cc_);
~DesktopWindow();
- // PixelFormat of incoming write operations
- void setServerPF(const rfb::PixelFormat& pf);
// Most efficient format (from DesktopWindow's point of view)
const rfb::PixelFormat &getPreferredPF();
// Flush updates to screen
void updateWindow();
- // Methods forwarded from CConn
+ // Updated session title
void setName(const char *name);
- void fillRect(const rfb::Rect& r, rfb::Pixel pix);
- void imageRect(const rfb::Rect& r, void* pixels);
- void copyRect(const rfb::Rect& r, int srcX, int srcY);
-
- rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
- void commitBufferRW(const rfb::Rect& r);
+ // Return a pointer to the framebuffer for decoders to write into
+ rfb::ModifiablePixelBuffer* getFramebuffer(void);
+ // Resize the current framebuffer, but retain the contents
void resizeFramebuffer(int new_w, int new_h);
+ // New image for the locally rendered cursor
void setCursor(int width, int height, const rfb::Point& hotspot,
void* data, void* mask);
diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx
index ced04467..5bd50d2c 100644
--- a/vncviewer/PlatformPixelBuffer.cxx
+++ b/vncviewer/PlatformPixelBuffer.cxx
@@ -24,3 +24,19 @@ PlatformPixelBuffer::PlatformPixelBuffer(const rfb::PixelFormat& pf,
FullFramePixelBuffer(pf, width, height, data, stride)
{
}
+
+void PlatformPixelBuffer::commitBufferRW(const rfb::Rect& r)
+{
+ FullFramePixelBuffer::commitBufferRW(r);
+ damage.assign_union(rfb::Region(r));
+}
+
+rfb::Rect PlatformPixelBuffer::getDamage(void)
+{
+ rfb::Rect r;
+
+ r = damage.get_bounding_rect();
+ damage.clear();
+
+ return r;
+}
diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h
index 03842ac8..21b93be4 100644
--- a/vncviewer/PlatformPixelBuffer.h
+++ b/vncviewer/PlatformPixelBuffer.h
@@ -20,14 +20,20 @@
#define __PLATFORMPIXELBUFFER_H__
#include <rfb/PixelBuffer.h>
+#include <rfb/Region.h>
class PlatformPixelBuffer: public rfb::FullFramePixelBuffer {
public:
PlatformPixelBuffer(const rfb::PixelFormat& pf, int width, int height,
rdr::U8* data, int stride);
+ virtual void commitBufferRW(const rfb::Rect& r);
+
virtual void draw(int src_x, int src_y, int x, int y, int w, int h) = 0;
+ rfb::Rect getDamage(void);
+protected:
+ rfb::Region damage;
};
#endif
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 70964b76..cd8b1bc3 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -27,7 +27,6 @@
#include <rfb/CMsgWriter.h>
#include <rfb/LogWriter.h>
-#include <rfb/PixelTransformer.h>
// FLTK can pull in the X11 headers on some systems
#ifndef XK_VoidSymbol
@@ -84,7 +83,7 @@ enum { ID_EXIT, ID_FULLSCREEN, ID_RESIZE,
ID_REFRESH, ID_OPTIONS, ID_INFO, ID_ABOUT, ID_DISMISS };
Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
- : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL),
+ : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL),
lastPointerPos(0, 0), lastButtonMask(0),
cursor(NULL), menuCtrlKey(false), menuAltKey(false)
{
@@ -101,8 +100,6 @@ Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
frameBuffer = createFramebuffer(w, h);
assert(frameBuffer);
- setServerPF(serverPF);
-
contextMenu = new Fl_Menu_Button(0, 0, 0, 0);
// Setting box type to FL_NO_BOX prevents it from trying to draw the
// button component (which we don't want)
@@ -130,7 +127,6 @@ Viewport::~Viewport()
{
// Unregister all timeouts in case they get a change tro trigger
// again later when this object is already gone.
- Fl::remove_timeout(handleUpdateTimeout, this);
Fl::remove_timeout(handlePointerTimeout, this);
#ifdef HAVE_FLTK_CLIPBOARD
@@ -141,9 +137,6 @@ Viewport::~Viewport()
delete frameBuffer;
- if (pixelTrans)
- delete pixelTrans;
-
if (cursor) {
if (!cursor->alloc_array)
delete [] cursor->array;
@@ -155,40 +148,6 @@ Viewport::~Viewport()
}
-void Viewport::setServerPF(const rfb::PixelFormat& pf)
-{
- if (pixelTrans)
- delete pixelTrans;
- pixelTrans = NULL;
-
- if (pf.equal(getPreferredPF()))
- return;
-
- pixelTrans = new PixelTransformer();
-
- // FIXME: This is an ugly (temporary) hack to get around a corner
- // case during startup. The conversion routines cannot handle
- // non-native source formats, and we can sometimes get that
- // as the initial format. We will switch to a better format
- // before getting any updates, but we need something for now.
- // Our old client used something completely bogus and just
- // hoped nothing would ever go wrong. We try to at least match
- // the pixel size so that we don't get any memory access issues
- // should a stray update appear.
- static rdr::U32 endianTest = 1;
- static bool nativeBigEndian = *(rdr::U8*)(&endianTest) != 1;
- if ((pf.bpp > 8) && (pf.bigEndian != nativeBigEndian)) {
- PixelFormat fake_pf(pf.bpp, pf.depth, nativeBigEndian, pf.trueColour,
- pf.redMax, pf.greenMax, pf.blueMax,
- pf.redShift, pf.greenShift, pf.blueShift);
- pixelTrans->init(fake_pf, getPreferredPF());
- return;
- }
-
- pixelTrans->init(pf, getPreferredPF());
-}
-
-
const rfb::PixelFormat &Viewport::getPreferredPF()
{
return frameBuffer->getPF();
@@ -197,65 +156,21 @@ const rfb::PixelFormat &Viewport::getPreferredPF()
// Copy the areas of the framebuffer that have been changed (damaged)
// to the displayed window.
+// FIXME: Make sure this gets called on slow updates
void Viewport::updateWindow()
{
Rect r;
- Fl::remove_timeout(handleUpdateTimeout, this);
-
- r = damage.get_bounding_rect();
- Fl_Widget::damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height());
-
- damage.clear();
-}
-
-void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
- if (pixelTrans) {
- rfb::Pixel pix2;
- pixelTrans->translatePixels(&pix, &pix2, 1);
- pix = pix2;
- }
-
- frameBuffer->fillRect(r, pix);
- damageRect(r);
+ r = frameBuffer->getDamage();
+ damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height());
}
-void Viewport::imageRect(const rfb::Rect& r, void* pixels) {
- if (pixelTrans) {
- rdr::U8* buffer;
- int stride;
- buffer = frameBuffer->getBufferRW(r, &stride);
- pixelTrans->translateRect(pixels, r.width(),
- rfb::Rect(0, 0, r.width(), r.height()),
- buffer, stride, rfb::Point(0, 0));
- frameBuffer->commitBufferRW(r);
- } else {
- frameBuffer->imageRect(r, pixels);
- }
- damageRect(r);
-}
-
-void Viewport::copyRect(const rfb::Rect& r, int srcX, int srcY) {
- frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY));
- damageRect(r);
-}
-
-rdr::U8* Viewport::getBufferRW(const rfb::Rect& r, int* stride) {
- return frameBuffer->getBufferRW(r, stride);
-}
-
-void Viewport::commitBufferRW(const rfb::Rect& r) {
- frameBuffer->commitBufferRW(r);
- damageRect(r);
+rfb::ModifiablePixelBuffer* Viewport::getFramebuffer(void)
+{
+ return frameBuffer;
}
-void Viewport::damageRect(const rfb::Rect& r) {
- damage.assign_union(rfb::Region(r));
- if (!Fl::has_timeout(handleUpdateTimeout, this))
- Fl::add_timeout(0.500, handleUpdateTimeout, this);
-};
-
#ifdef HAVE_FLTK_CURSOR
static const char * dotcursor_xpm[] = {
"5 5 2 1",
@@ -303,10 +218,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot,
const PixelFormat *pf;
- if (pixelTrans)
- pf = &pixelTrans->getInPF();
- else
- pf = &frameBuffer->getPF();
+ pf = &cc->cp.pf();
i = (U8*)data;
o = buffer;
@@ -530,16 +442,6 @@ PlatformPixelBuffer* Viewport::createFramebuffer(int w, int h)
}
-void Viewport::handleUpdateTimeout(void *data)
-{
- Viewport *self = (Viewport *)data;
-
- assert(self);
-
- self->updateWindow();
-}
-
-
void Viewport::handleClipboardChange(int source, void *data)
{
Viewport *self = (Viewport *)data;
diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h
index e112efda..0523cd14 100644
--- a/vncviewer/Viewport.h
+++ b/vncviewer/Viewport.h
@@ -22,10 +22,9 @@
#include <map>
-#include <FL/Fl_Widget.H>
+namespace rfb { class ModifiablePixelBuffer; }
-#include <rfb/Region.h>
-#include <rfb/Pixel.h>
+#include <FL/Fl_Widget.H>
class Fl_Menu_Button;
class Fl_RGB_Image;
@@ -41,23 +40,16 @@ public:
Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_);
~Viewport();
- // PixelFormat of incoming write operations
- void setServerPF(const rfb::PixelFormat& pf);
// Most efficient format (from Viewport's point of view)
const rfb::PixelFormat &getPreferredPF();
// Flush updates to screen
void updateWindow();
- // Methods forwarded from CConn
-
- void fillRect(const rfb::Rect& r, rfb::Pixel pix);
- void imageRect(const rfb::Rect& r, void* pixels);
- void copyRect(const rfb::Rect& r, int srcX, int srcY);
-
- rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
- void commitBufferRW(const rfb::Rect& r);
+ // Return a pointer to the framebuffer for decoders to write into
+ rfb::ModifiablePixelBuffer* getFramebuffer(void);
+ // New image for the locally rendered cursor
void setCursor(int width, int height, const rfb::Point& hotspot,
void* data, void* mask);
@@ -71,12 +63,8 @@ public:
private:
- void damageRect(const rfb::Rect& r);
-
PlatformPixelBuffer* createFramebuffer(int w, int h);
- static void handleUpdateTimeout(void *data);
-
static void handleClipboardChange(int source, void *data);
void handlePointerEvent(const rfb::Point& pos, int buttonMask);
@@ -96,8 +84,6 @@ private:
CConn* cc;
PlatformPixelBuffer* frameBuffer;
- rfb::PixelTransformer *pixelTrans;
- rfb::Region damage;
rfb::Point lastPointerPos;
int lastButtonMask;