Browse Source

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.
tags/v1.3.90
Pierre Ossman 9 years ago
parent
commit
0c9bd4b0ba
45 changed files with 200 additions and 363 deletions
  1. 0
    9
      common/rfb/CMsgHandler.h
  2. 2
    3
      common/rfb/CopyRectDecoder.cxx
  3. 1
    1
      common/rfb/CopyRectDecoder.h
  4. 8
    2
      common/rfb/Decoder.h
  5. 6
    5
      common/rfb/Encoder.h
  6. 7
    6
      common/rfb/HextileDecoder.cxx
  7. 1
    1
      common/rfb/HextileDecoder.h
  8. 11
    9
      common/rfb/HextileEncoder.cxx
  9. 1
    1
      common/rfb/HextileEncoder.h
  10. 7
    6
      common/rfb/RREDecoder.cxx
  11. 1
    1
      common/rfb/RREDecoder.h
  12. 5
    4
      common/rfb/RREEncoder.cxx
  13. 1
    1
      common/rfb/RREEncoder.h
  14. 5
    4
      common/rfb/RawDecoder.cxx
  15. 1
    1
      common/rfb/RawDecoder.h
  16. 7
    17
      common/rfb/RawEncoder.cxx
  17. 1
    1
      common/rfb/RawEncoder.h
  18. 5
    5
      common/rfb/TightDecoder.cxx
  19. 2
    2
      common/rfb/TightDecoder.h
  20. 6
    7
      common/rfb/TightEncoder.cxx
  21. 3
    3
      common/rfb/TightEncoder.h
  22. 15
    15
      common/rfb/VNCSConnectionST.cxx
  23. 0
    2
      common/rfb/VNCSConnectionST.h
  24. 0
    1
      common/rfb/VNCServerST.cxx
  25. 1
    8
      common/rfb/VNCServerST.h
  26. 9
    10
      common/rfb/ZRLEDecoder.cxx
  27. 1
    1
      common/rfb/ZRLEDecoder.h
  28. 9
    10
      common/rfb/ZRLEEncoder.cxx
  29. 1
    1
      common/rfb/ZRLEEncoder.h
  30. 3
    3
      common/rfb/hextileDecode.h
  31. 4
    3
      common/rfb/hextileEncode.h
  32. 3
    2
      common/rfb/hextileEncodeBetter.h
  33. 4
    3
      common/rfb/rreDecode.h
  34. 6
    6
      common/rfb/tightDecode.h
  35. 11
    10
      common/rfb/tightEncode.h
  36. 3
    3
      common/rfb/zrleDecode.h
  37. 3
    2
      common/rfb/zrleEncode.h
  38. 1
    26
      vncviewer/CConn.cxx
  39. 0
    10
      vncviewer/CConn.h
  40. 3
    24
      vncviewer/DesktopWindow.cxx
  41. 7
    9
      vncviewer/DesktopWindow.h
  42. 16
    0
      vncviewer/PlatformPixelBuffer.cxx
  43. 6
    0
      vncviewer/PlatformPixelBuffer.h
  44. 8
    106
      vncviewer/Viewport.cxx
  45. 5
    19
      vncviewer/Viewport.h

+ 0
- 9
common/rfb/CMsgHandler.h View File

@@ -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;
};
}

+ 2
- 3
common/rfb/CopyRectDecoder.cxx View File

@@ -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));
}

+ 1
- 1
common/rfb/CopyRectDecoder.h View File

@@ -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

+ 8
- 2
common/rfb/Decoder.h View File

@@ -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);

+ 6
- 5
common/rfb/Encoder.h View File

@@ -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);

+ 7
- 6
common/rfb/HextileDecoder.cxx View File

@@ -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;
}
}

+ 1
- 1
common/rfb/HextileDecoder.h View File

@@ -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

+ 11
- 9
common/rfb/HextileEncoder.cxx View File

@@ -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;
}

+ 1
- 1
common/rfb/HextileEncoder.h View File

@@ -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

+ 7
- 6
common/rfb/RREDecoder.cxx View File

@@ -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;
}
}

+ 1
- 1
common/rfb/RREDecoder.h View File

@@ -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

+ 5
- 4
common/rfb/RREEncoder.cxx View File

@@ -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;
}


+ 1
- 1
common/rfb/RREEncoder.h View File

@@ -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;
};

+ 5
- 4
common/rfb/RawDecoder.cxx View File

@@ -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;
}

+ 1
- 1
common/rfb/RawDecoder.h View File

@@ -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

+ 7
- 17
common/rfb/RawEncoder.cxx View File

@@ -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();
}

+ 1
- 1
common/rfb/RawEncoder.h View File

@@ -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

+ 5
- 5
common/rfb/TightDecoder.cxx View File

@@ -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) */

+ 2
- 2
common/rfb/TightDecoder.h View File

@@ -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;

+ 6
- 7
common/rfb/TightEncoder.cxx View File

@@ -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;

+ 3
- 3
common/rfb/TightEncoder.h View File

@@ -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;

+ 15
- 15
common/rfb/VNCSConnectionST.cxx View File

@@ -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;
}

+ 0
- 2
common/rfb/VNCSConnectionST.h View File

@@ -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;

+ 0
- 1
common/rfb/VNCServerST.cxx View File

@@ -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)
{

+ 1
- 8
common/rfb/VNCServerST.h View File

@@ -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;

+ 9
- 10
common/rfb/ZRLEDecoder.cxx View File

@@ -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;
}

+ 1
- 1
common/rfb/ZRLEDecoder.h View File

@@ -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;
};

+ 9
- 10
common/rfb/ZRLEEncoder.cxx View File

@@ -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;
}

+ 1
- 1
common/rfb/ZRLEEncoder.h View File

@@ -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;

+ 3
- 3
common/rfb/hextileDecode.h View File

@@ -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);
}
}
}

+ 4
- 3
common/rfb/hextileEncode.h View File

@@ -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;

+ 3
- 2
common/rfb/hextileEncodeBetter.h View File

@@ -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();

+ 4
- 3
common/rfb/rreDecode.h View File

@@ -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);
}
}


+ 6
- 6
common/rfb/tightDecode.h View File

@@ -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;
}

+ 11
- 10
common/rfb/tightEncode.h View File

@@ -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)

+ 3
- 3
common/rfb/zrleDecode.h View File

@@ -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);
}
}


+ 3
- 2
common/rfb/zrleEncode.h View File

@@ -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);
}

+ 1
- 26
vncviewer/CConn.cxx View File

@@ -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 //////////////////////


+ 0
- 10
vncviewer/CConn.h View File

@@ -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);


+ 3
- 24
vncviewer/DesktopWindow.cxx View File

@@ -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();
}



+ 7
- 9
vncviewer/DesktopWindow.h View File

@@ -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);


+ 16
- 0
vncviewer/PlatformPixelBuffer.cxx View File

@@ -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;
}

+ 6
- 0
vncviewer/PlatformPixelBuffer.h View File

@@ -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

+ 8
- 106
vncviewer/Viewport.cxx View File

@@ -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;

+ 5
- 19
vncviewer/Viewport.h View File

@@ -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;

Loading…
Cancel
Save