diff options
author | Pierre Ossman <ossman@cendio.se> | 2017-02-19 15:50:29 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2017-02-22 17:00:37 +0100 |
commit | a4c0aac6395b11ebb387d664fca4dcd496073a37 (patch) | |
tree | 3c49aaaf5e23d04e7f876c6388b6d927ffa0a5f8 /common/rfb/CMsgReader.cxx | |
parent | 1bbe02ba8b6882aaec0a7506c4df41762dfc1663 (diff) | |
download | tigervnc-a4c0aac6395b11ebb387d664fca4dcd496073a37.tar.gz tigervnc-a4c0aac6395b11ebb387d664fca4dcd496073a37.zip |
Client support for cursors with full alpha
Diffstat (limited to 'common/rfb/CMsgReader.cxx')
-rw-r--r-- | common/rfb/CMsgReader.cxx | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx index 152c2c85..7233fbd7 100644 --- a/common/rfb/CMsgReader.cxx +++ b/common/rfb/CMsgReader.cxx @@ -16,7 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ + +#include <assert.h> #include <stdio.h> + #include <rfb/msgTypes.h> #include <rdr/InStream.h> #include <rfb/Exception.h> @@ -94,6 +97,9 @@ void CMsgReader::readMsg() case pseudoEncodingCursor: readSetCursor(w, h, Point(x,y)); break; + case pseudoEncodingCursorWithAlpha: + readSetCursorWithAlpha(w, h, Point(x,y)); + break; case pseudoEncodingDesktopName: readSetDesktopName(x, y, w, h); break; @@ -287,6 +293,50 @@ void CMsgReader::readSetCursor(int width, int height, const Point& hotspot) handler->setCursor(width, height, hotspot, buf); } +void CMsgReader::readSetCursorWithAlpha(int width, int height, const Point& hotspot) +{ + int encoding; + + const PixelFormat rgbaPF(32, 32, false, true, 255, 255, 255, 16, 8, 0); + ManagedPixelBuffer pb(rgbaPF, width, height); + PixelFormat origPF; + + rdr::U8* buf; + int stride; + + encoding = is->readS32(); + + origPF = handler->cp.pf(); + handler->cp.setPF(rgbaPF); + handler->readAndDecodeRect(pb.getRect(), encoding, &pb); + handler->cp.setPF(origPF); + + // On-wire data has pre-multiplied alpha, but we store it + // non-pre-multiplied + buf = pb.getBufferRW(pb.getRect(), &stride); + assert(stride == width); + + for (int i = 0;i < pb.area();i++) { + rdr::U8 alpha; + + alpha = buf[3]; + if (alpha == 0) + alpha = 1; // Avoid division by zero + + buf[0] = (unsigned)buf[0] * 255/alpha; + buf[1] = (unsigned)buf[1] * 255/alpha; + buf[2] = (unsigned)buf[2] * 255/alpha; + buf[3] = alpha; + + buf += 4; + } + + pb.commitBufferRW(pb.getRect()); + + handler->setCursor(width, height, hotspot, + pb.getBuffer(pb.getRect(), &stride)); +} + void CMsgReader::readSetDesktopName(int x, int y, int w, int h) { char* name = is->readString(); |