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