summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2017-02-19 15:51:19 +0100
committerPierre Ossman <ossman@cendio.se>2017-02-22 16:58:30 +0100
commit6b68f977880530e95dc31a1f342a11f2c36b75a1 (patch)
treeda0be948b42ffa068f240a19ecbc3f8cfac179e1
parent6b75e7705c7608dbea3bdc6301b368d7ea6293b2 (diff)
downloadtigervnc-6b68f977880530e95dc31a1f342a11f2c36b75a1.tar.gz
tigervnc-6b68f977880530e95dc31a1f342a11f2c36b75a1.zip
Client support for X Cursor
-rw-r--r--common/rfb/CMsgReader.cxx58
-rw-r--r--common/rfb/CMsgReader.h1
-rw-r--r--common/rfb/CMsgWriter.cxx4
3 files changed, 62 insertions, 1 deletions
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx
index bbb99096..152c2c85 100644
--- a/common/rfb/CMsgReader.cxx
+++ b/common/rfb/CMsgReader.cxx
@@ -88,6 +88,9 @@ void CMsgReader::readMsg()
case pseudoEncodingLastRect:
nUpdateRectsLeft = 1; // this rectangle is the last one
break;
+ case pseudoEncodingXCursor:
+ readSetXCursor(w, h, Point(x,y));
+ break;
case pseudoEncodingCursor:
readSetCursor(w, h, Point(x,y));
break;
@@ -191,6 +194,61 @@ void CMsgReader::readRect(const Rect& r, int encoding)
handler->dataRect(r, encoding);
}
+void CMsgReader::readSetXCursor(int width, int height, const Point& hotspot)
+{
+ rdr::U8 pr, pg, pb;
+ rdr::U8 sr, sg, sb;
+ int data_len = ((width+7)/8) * height;
+ int mask_len = ((width+7)/8) * height;
+ rdr::U8Array data(data_len);
+ rdr::U8Array mask(mask_len);
+
+ int x, y;
+ rdr::U8 buf[width*height*4];
+ rdr::U8* out;
+
+ if (width * height) {
+ pr = is->readU8();
+ pg = is->readU8();
+ pb = is->readU8();
+
+ sr = is->readU8();
+ sg = is->readU8();
+ sb = is->readU8();
+
+ is->readBytes(data.buf, data_len);
+ is->readBytes(mask.buf, mask_len);
+ }
+
+ int maskBytesPerRow = (width+7)/8;
+ out = buf;
+ for (y = 0;y < height;y++) {
+ for (x = 0;x < width;x++) {
+ int byte = y * maskBytesPerRow + x / 8;
+ int bit = 7 - x % 8;
+
+ if (data.buf[byte] & (1 << bit)) {
+ out[0] = pr;
+ out[1] = pg;
+ out[2] = pb;
+ } else {
+ out[0] = sr;
+ out[1] = sg;
+ out[2] = sb;
+ }
+
+ if (mask.buf[byte] & (1 << bit))
+ out[3] = 255;
+ else
+ out[3] = 0;
+
+ out += 4;
+ }
+ }
+
+ handler->setCursor(width, height, hotspot, buf);
+}
+
void CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
{
int data_len = width * height * (handler->cp.pf().bpp/8);
diff --git a/common/rfb/CMsgReader.h b/common/rfb/CMsgReader.h
index 42c64965..296d99f0 100644
--- a/common/rfb/CMsgReader.h
+++ b/common/rfb/CMsgReader.h
@@ -60,6 +60,7 @@ namespace rfb {
void readRect(const Rect& r, int encoding);
+ void readSetXCursor(int width, int height, const Point& hotspot);
void readSetCursor(int width, int height, const Point& hotspot);
void readSetDesktopName(int x, int y, int w, int h);
void readExtendedDesktopSize(int x, int y, int w, int h);
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx
index 6536eaf2..2ad3a79a 100644
--- a/common/rfb/CMsgWriter.cxx
+++ b/common/rfb/CMsgWriter.cxx
@@ -71,8 +71,10 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
int nEncodings = 0;
rdr::U32 encodings[encodingMax+3];
- if (cp->supportsLocalCursor)
+ if (cp->supportsLocalCursor) {
+ encodings[nEncodings++] = pseudoEncodingXCursor;
encodings[nEncodings++] = pseudoEncodingCursor;
+ }
if (cp->supportsDesktopResize)
encodings[nEncodings++] = pseudoEncodingDesktopSize;
if (cp->supportsExtendedDesktopSize)