aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/CMsgWriter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb/CMsgWriter.cxx')
-rw-r--r--common/rfb/CMsgWriter.cxx61
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);