diff options
Diffstat (limited to 'rfb')
-rw-r--r-- | rfb/ConnParams.cxx | 5 | ||||
-rw-r--r-- | rfb/ConnParams.h | 1 | ||||
-rw-r--r-- | rfb/SMsgWriter.h | 2 | ||||
-rw-r--r-- | rfb/SMsgWriterV3.cxx | 26 | ||||
-rw-r--r-- | rfb/SMsgWriterV3.h | 2 | ||||
-rw-r--r-- | rfb/VNCSConnectionST.cxx | 38 | ||||
-rw-r--r-- | rfb/encodings.h | 1 |
7 files changed, 66 insertions, 9 deletions
diff --git a/rfb/ConnParams.cxx b/rfb/ConnParams.cxx index 7dcfdccf..4a8e5344 100644 --- a/rfb/ConnParams.cxx +++ b/rfb/ConnParams.cxx @@ -27,7 +27,7 @@ using namespace rfb; ConnParams::ConnParams() : majorVersion(0), minorVersion(0), width(0), height(0), useCopyRect(false), - supportsLocalCursor(false), supportsDesktopResize(false), supportsLastRect(false), + supportsLocalCursor(false), supportsLocalXCursor(false), supportsDesktopResize(false), supportsLastRect(false), customCompressLevel(false), compressLevel(6), noJpeg(false), qualityLevel(-1), name_(0), nEncodings_(0), encodings_(0), currentEncoding_(encodingRaw), verStrPos(0) @@ -88,6 +88,7 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings) nEncodings_ = nEncodings; useCopyRect = false; supportsLocalCursor = false; + supportsLocalXCursor = false; supportsLastRect = false; customCompressLevel = false; compressLevel = -1; @@ -102,6 +103,8 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings) useCopyRect = true; else if (encodings[i] == pseudoEncodingCursor) supportsLocalCursor = true; + else if (encodings[i] == pseudoEncodingXCursor) + supportsLocalXCursor = true; else if (encodings[i] == pseudoEncodingDesktopSize) supportsDesktopResize = true; else if (encodings[i] == pseudoEncodingLastRect) diff --git a/rfb/ConnParams.h b/rfb/ConnParams.h index 70578eac..09e79c25 100644 --- a/rfb/ConnParams.h +++ b/rfb/ConnParams.h @@ -70,6 +70,7 @@ namespace rfb { bool useCopyRect; bool supportsLocalCursor; + bool supportsLocalXCursor; bool supportsDesktopResize; bool supportsLastRect; diff --git a/rfb/SMsgWriter.h b/rfb/SMsgWriter.h index 72bc10a4..6dc272cf 100644 --- a/rfb/SMsgWriter.h +++ b/rfb/SMsgWriter.h @@ -82,6 +82,8 @@ namespace rfb { virtual void cursorChange(WriteSetCursorCallback* cb)=0; virtual void writeSetCursor(int width, int height, int hotspotX, int hotspotY, void* data, void* mask)=0; + virtual void writeSetXCursor(int width, int height, int hotspotX, + int hotspotY, void* data, void* mask)=0; // needFakeUpdate() returns true when an immediate update is needed in // order to flush out setDesktopSize or setCursor pseudo-rectangles to the diff --git a/rfb/SMsgWriterV3.cxx b/rfb/SMsgWriterV3.cxx index 20a72801..c34f216d 100644 --- a/rfb/SMsgWriterV3.cxx +++ b/rfb/SMsgWriterV3.cxx @@ -84,6 +84,32 @@ void SMsgWriterV3::writeSetCursor(int width, int height, int hotspotX, os->writeBytes(mask, (width+7)/8 * height); } +void SMsgWriterV3::writeSetXCursor(int width, int height, int hotspotX, + int hotspotY, void* data, void* mask) +{ + if (!wsccb) return; + if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader) + throw Exception("SMsgWriterV3::writeSetXCursor: nRects out of sync"); + os->writeS16(hotspotX); + os->writeS16(hotspotY); + os->writeU16(width); + os->writeU16(height); + os->writeU32(pseudoEncodingXCursor); + // FIXME: We only support black and white cursors, currently. We + // could pass the correct color by using the pix0/pix1 values + // returned from getBitmap, in writeSetCursorCallback. However, we + // would then need to undo the conversion from rgb to Pixel that is + // done by FakeAllocColor. + os->writeU8(0); + os->writeU8(0); + os->writeU8(0); + os->writeU8(255); + os->writeU8(255); + os->writeU8(255); + os->writeBytes(data, (width+7)/8 * height); + os->writeBytes(mask, (width+7)/8 * height); +} + void SMsgWriterV3::writeFramebufferUpdateStart(int nRects) { startMsg(msgTypeFramebufferUpdate); diff --git a/rfb/SMsgWriterV3.h b/rfb/SMsgWriterV3.h index 0bad8f17..fbd07d68 100644 --- a/rfb/SMsgWriterV3.h +++ b/rfb/SMsgWriterV3.h @@ -35,6 +35,8 @@ namespace rfb { virtual void cursorChange(WriteSetCursorCallback* cb); virtual void writeSetCursor(int width, int height, int hotspotX, int hotspotY, void* data, void* mask); + virtual void writeSetXCursor(int width, int height, int hotspotX, + int hotspotY, void* data, void* mask); virtual void writeFramebufferUpdateStart(int nRects); virtual void writeFramebufferUpdateStart(); virtual void writeFramebufferUpdateEnd(); diff --git a/rfb/VNCSConnectionST.cxx b/rfb/VNCSConnectionST.cxx index 426ecd4e..a20ec01d 100644 --- a/rfb/VNCSConnectionST.cxx +++ b/rfb/VNCSConnectionST.cxx @@ -277,7 +277,7 @@ void VNCSConnectionST::renderedCursorChange() bool VNCSConnectionST::needRenderedCursor() { return (state() == RFBSTATE_NORMAL - && (!cp.supportsLocalCursor + && (!cp.supportsLocalCursor && !cp.supportsLocalXCursor || (!server->cursorPos.equals(pointerEventPos) && (time(0) - pointerEventTime) > 0))); } @@ -478,7 +478,7 @@ void VNCSConnectionST::setInitialColourMap() void VNCSConnectionST::supportsLocalCursor() { - if (cp.supportsLocalCursor) { + if (cp.supportsLocalCursor || cp.supportsLocalXCursor) { removeRenderedCursor = true; drawRenderedCursor = false; setCursor(); @@ -487,15 +487,37 @@ void VNCSConnectionST::supportsLocalCursor() void VNCSConnectionST::writeSetCursorCallback() { + if (cp.supportsLocalXCursor) { + Pixel pix0, pix1; + rdr::U8Array bitmap(server->cursor.getBitmap(&pix0, &pix1)); + if (bitmap.buf) { + // The client supports XCursor and the cursor only has two + // colors. Use the XCursor encoding. + writer()->writeSetXCursor(server->cursor.width(), + server->cursor.height(), + server->cursor.hotspot.x, + server->cursor.hotspot.y, + bitmap.buf, server->cursor.mask.buf); + return; + } else { + // More than two colors + if (!cp.supportsLocalCursor) { + // FIXME: We could reduce to two colors. + vlog.info("Unable to send multicolor cursor: RichCursor not supported by client"); + return; + } + } + } + + // Use RichCursor rdr::U8* transData = writer()->getImageBuf(server->cursor.area()); image_getter.translatePixels(server->cursor.data, transData, - server->cursor.area()); - + server->cursor.area()); writer()->writeSetCursor(server->cursor.width(), - server->cursor.height(), - server->cursor.hotspot.x, - server->cursor.hotspot.y, - transData, server->cursor.mask.buf); + server->cursor.height(), + server->cursor.hotspot.x, + server->cursor.hotspot.y, + transData, server->cursor.mask.buf); } diff --git a/rfb/encodings.h b/rfb/encodings.h index a40af822..550440d5 100644 --- a/rfb/encodings.h +++ b/rfb/encodings.h @@ -30,6 +30,7 @@ namespace rfb { const unsigned int encodingMax = 255; + const unsigned int pseudoEncodingXCursor = 0xffffff10; const unsigned int pseudoEncodingCursor = 0xffffff11; const unsigned int pseudoEncodingDesktopSize = 0xffffff21; |