diff options
Diffstat (limited to 'common/rfb/CMsgWriter.cxx')
-rw-r--r-- | common/rfb/CMsgWriter.cxx | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx index 1bd8040f..0128c431 100644 --- a/common/rfb/CMsgWriter.cxx +++ b/common/rfb/CMsgWriter.cxx @@ -22,6 +22,7 @@ #endif #include <stdio.h> +#include <assert.h> #include <rdr/OutStream.h> #include <rdr/MemOutStream.h> @@ -31,7 +32,6 @@ #include <rfb/fenceTypes.h> #include <rfb/qemuTypes.h> #include <rfb/clipboardTypes.h> -#include <rfb/Exception.h> #include <rfb/PixelFormat.h> #include <rfb/Rect.h> #include <rfb/ServerParams.h> @@ -77,7 +77,7 @@ void CMsgWriter::writeSetDesktopSize(int width, int height, const ScreenSet& layout) { if (!server->supportsSetDesktopSize) - throw Exception("Server does not support SetDesktopSize"); + throw std::logic_error("Server does not support SetDesktopSize"); startMsg(msgTypeSetDesktopSize); os->pad(1); @@ -116,7 +116,7 @@ void CMsgWriter::writeEnableContinuousUpdates(bool enable, int x, int y, int w, int h) { if (!server->supportsContinuousUpdates) - throw Exception("Server does not support continuous updates"); + throw std::logic_error("Server does not support continuous updates"); startMsg(msgTypeEnableContinuousUpdates); @@ -133,11 +133,11 @@ void CMsgWriter::writeEnableContinuousUpdates(bool enable, void CMsgWriter::writeFence(uint32_t flags, unsigned len, const uint8_t data[]) { if (!server->supportsFence) - throw Exception("Server does not support fences"); + throw std::logic_error("Server does not support fences"); if (len > 64) - throw Exception("Too large fence payload"); + throw std::out_of_range("Too large fence payload"); if ((flags & ~fenceFlagsSupported) != 0) - throw Exception("Unknown fence flags"); + throw std::invalid_argument("Unknown fence flags"); startMsg(msgTypeClientFence); os->pad(3); @@ -173,18 +173,47 @@ void CMsgWriter::writeKeyEvent(uint32_t keysym, uint32_t keycode, bool down) } -void CMsgWriter::writePointerEvent(const Point& pos, uint8_t buttonMask) +void CMsgWriter::writePointerEvent(const Point& pos, uint16_t buttonMask) { Point p(pos); + bool extendedMouseButtons; + if (p.x < 0) p.x = 0; if (p.y < 0) p.y = 0; if (p.x >= server->width()) p.x = server->width() - 1; if (p.y >= server->height()) p.y = server->height() - 1; + /* The highest bit in buttonMask is never sent to the server */ + assert(!(buttonMask & 0x8000)); + + /* Only send extended pointerEvent message when needed */ + extendedMouseButtons = buttonMask & 0x7f80; + startMsg(msgTypePointerEvent); - os->writeU8(buttonMask); - os->writeU16(p.x); - os->writeU16(p.y); + if (server->supportsExtendedMouseButtons && extendedMouseButtons) { + int higherBits; + int lowerBits; + + higherBits = (buttonMask >> 7) & 0xff; + assert(!(higherBits & 0xfc)); /* Bits 2-7 are reserved */ + + lowerBits = buttonMask & 0x7f; + lowerBits |= 0x80; /* Set marker bit to 1 */ + + os->writeU8(lowerBits); + os->writeU16(p.x); + os->writeU16(p.y); + os->writeU8(higherBits); + } else { + /* Marker bit must be set to 0, otherwise the server might confuse + * the marker bit with the highest bit in a normal PointerEvent + * message. + */ + buttonMask &= 0x7f; + os->writeU8(buttonMask); + os->writeU16(p.x); + os->writeU16(p.y); + } endMsg(); } @@ -192,7 +221,7 @@ void CMsgWriter::writePointerEvent(const Point& pos, uint8_t buttonMask) void CMsgWriter::writeClientCutText(const char* str) { if (strchr(str, '\r') != nullptr) - throw Exception("Invalid carriage return in clipboard data"); + throw std::invalid_argument("Invalid carriage return in clipboard data"); std::string latin1(utf8ToLatin1(str)); @@ -209,7 +238,7 @@ void CMsgWriter::writeClipboardCaps(uint32_t caps, size_t i, count; if (!(server->clipboardFlags() & clipboardCaps)) - throw Exception("Server does not support clipboard \"caps\" action"); + throw std::logic_error("Server does not support clipboard \"caps\" action"); count = 0; for (i = 0;i < 16;i++) { @@ -235,7 +264,7 @@ void CMsgWriter::writeClipboardCaps(uint32_t caps, void CMsgWriter::writeClipboardRequest(uint32_t flags) { if (!(server->clipboardFlags() & clipboardRequest)) - throw Exception("Server does not support clipboard \"request\" action"); + throw std::logic_error("Server does not support clipboard \"request\" action"); startMsg(msgTypeClientCutText); os->pad(3); @@ -247,7 +276,7 @@ void CMsgWriter::writeClipboardRequest(uint32_t flags) void CMsgWriter::writeClipboardPeek(uint32_t flags) { if (!(server->clipboardFlags() & clipboardPeek)) - throw Exception("Server does not support clipboard \"peek\" action"); + throw std::logic_error("Server does not support clipboard \"peek\" action"); startMsg(msgTypeClientCutText); os->pad(3); @@ -259,7 +288,7 @@ void CMsgWriter::writeClipboardPeek(uint32_t flags) void CMsgWriter::writeClipboardNotify(uint32_t flags) { if (!(server->clipboardFlags() & clipboardNotify)) - throw Exception("Server does not support clipboard \"notify\" action"); + throw std::logic_error("Server does not support clipboard \"notify\" action"); startMsg(msgTypeClientCutText); os->pad(3); @@ -278,7 +307,7 @@ void CMsgWriter::writeClipboardProvide(uint32_t flags, int i, count; if (!(server->clipboardFlags() & clipboardProvide)) - throw Exception("Server does not support clipboard \"provide\" action"); + throw std::logic_error("Server does not support clipboard \"provide\" action"); zos.setUnderlying(&mos); |