summaryrefslogtreecommitdiffstats
path: root/rfb
diff options
context:
space:
mode:
Diffstat (limited to 'rfb')
-rw-r--r--rfb/ConnParams.cxx5
-rw-r--r--rfb/ConnParams.h1
-rw-r--r--rfb/SMsgWriter.h2
-rw-r--r--rfb/SMsgWriterV3.cxx26
-rw-r--r--rfb/SMsgWriterV3.h2
-rw-r--r--rfb/VNCSConnectionST.cxx38
-rw-r--r--rfb/encodings.h1
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;