diff options
author | Pierre Ossman <ossman@cendio.se> | 2017-02-19 15:51:19 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2017-02-22 16:58:30 +0100 |
commit | 6b68f977880530e95dc31a1f342a11f2c36b75a1 (patch) | |
tree | da0be948b42ffa068f240a19ecbc3f8cfac179e1 | |
parent | 6b75e7705c7608dbea3bdc6301b368d7ea6293b2 (diff) | |
download | tigervnc-6b68f977880530e95dc31a1f342a11f2c36b75a1.tar.gz tigervnc-6b68f977880530e95dc31a1f342a11f2c36b75a1.zip |
Client support for X Cursor
-rw-r--r-- | common/rfb/CMsgReader.cxx | 58 | ||||
-rw-r--r-- | common/rfb/CMsgReader.h | 1 | ||||
-rw-r--r-- | common/rfb/CMsgWriter.cxx | 4 |
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) |