/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011-2017 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
CMsgHandler::setExtendedDesktopSize(reason, result, w, h, layout);
}
+void CConnection::readAndDecodeRect(const Rect& r, int encoding,
+ ModifiablePixelBuffer* pb)
+{
+ decoder.decodeRect(r, encoding, pb);
+ decoder.flush();
+}
+
void CConnection::framebufferUpdateStart()
{
CMsgHandler::framebufferUpdateStart();
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011-2017 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int w, int h,
const ScreenSet& layout);
+ virtual void readAndDecodeRect(const Rect& r, int encoding,
+ ModifiablePixelBuffer* pb);
+
virtual void framebufferUpdateStart();
virtual void framebufferUpdateEnd();
virtual void dataRect(const Rect& r, int encoding);
virtual void endOfContinuousUpdates();
virtual void serverInit() = 0;
+ virtual void readAndDecodeRect(const Rect& r, int encoding,
+ ModifiablePixelBuffer* pb) = 0;
+
virtual void framebufferUpdateStart();
virtual void framebufferUpdateEnd();
virtual void dataRect(const Rect& r, int encoding) = 0;
* 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>
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;
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();
void readSetXCursor(int width, int height, const Point& hotspot);
void readSetCursor(int width, int height, const Point& hotspot);
+ void readSetCursorWithAlpha(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);
if (cp->supportsLocalCursor) {
encodings[nEncodings++] = pseudoEncodingXCursor;
encodings[nEncodings++] = pseudoEncodingCursor;
+ encodings[nEncodings++] = pseudoEncodingCursorWithAlpha;
}
if (cp->supportsDesktopResize)
encodings[nEncodings++] = pseudoEncodingDesktopSize;
const int pseudoEncodingDesktopName = -307;
const int pseudoEncodingFence = -312;
const int pseudoEncodingContinuousUpdates = -313;
+ const int pseudoEncodingCursorWithAlpha = -314;
// TightVNC-specific
const int pseudoEncodingLastRect = -224;