aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb')
-rw-r--r--common/rfb/ClientParams.cxx7
-rw-r--r--common/rfb/ClientParams.h1
-rw-r--r--common/rfb/SConnection.cxx5
-rw-r--r--common/rfb/SConnection.h2
-rw-r--r--common/rfb/SDesktop.h2
-rw-r--r--common/rfb/SMsgHandler.cxx11
-rw-r--r--common/rfb/SMsgHandler.h7
-rw-r--r--common/rfb/SMsgReader.cxx27
-rw-r--r--common/rfb/SMsgWriter.cxx33
-rw-r--r--common/rfb/SMsgWriter.h5
-rw-r--r--common/rfb/VNCSConnectionST.cxx2
-rw-r--r--common/rfb/VNCSConnectionST.h2
-rw-r--r--common/rfb/VNCServerST.cxx2
-rw-r--r--common/rfb/VNCServerST.h2
-rw-r--r--common/rfb/encodings.h1
15 files changed, 97 insertions, 12 deletions
diff --git a/common/rfb/ClientParams.cxx b/common/rfb/ClientParams.cxx
index bc20c3d7..5ea104cf 100644
--- a/common/rfb/ClientParams.cxx
+++ b/common/rfb/ClientParams.cxx
@@ -228,3 +228,10 @@ bool ClientParams::supportsContinuousUpdates() const
return true;
return false;
}
+
+bool ClientParams::supportsExtendedMouseButtons() const
+{
+ if (supportsEncoding(pseudoEncodingExtendedMouseButtons))
+ return true;
+ return false;
+} \ No newline at end of file
diff --git a/common/rfb/ClientParams.h b/common/rfb/ClientParams.h
index ea86ea78..f715c47f 100644
--- a/common/rfb/ClientParams.h
+++ b/common/rfb/ClientParams.h
@@ -101,6 +101,7 @@ namespace rfb {
bool supportsLEDState() const;
bool supportsFence() const;
bool supportsContinuousUpdates() const;
+ bool supportsExtendedMouseButtons() const;
int compressLevel;
int qualityLevel;
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
index 905f88a4..9d481017 100644
--- a/common/rfb/SConnection.cxx
+++ b/common/rfb/SConnection.cxx
@@ -433,6 +433,11 @@ void SConnection::supportsQEMUKeyEvent()
writer()->writeQEMUKeyEvent();
}
+void SConnection::supportsExtendedMouseButtons()
+{
+ writer()->writeExtendedMouseButtonsSupport();
+}
+
void SConnection::versionReceived()
{
}
diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h
index 0a11f67b..a839f663 100644
--- a/common/rfb/SConnection.h
+++ b/common/rfb/SConnection.h
@@ -98,6 +98,8 @@ namespace rfb {
void supportsQEMUKeyEvent() override;
+ virtual void supportsExtendedMouseButtons() override;
+
// Methods to be overridden in a derived class
diff --git a/common/rfb/SDesktop.h b/common/rfb/SDesktop.h
index 1d3c325f..c97e788a 100644
--- a/common/rfb/SDesktop.h
+++ b/common/rfb/SDesktop.h
@@ -98,7 +98,7 @@ namespace rfb {
// pointerEvent() is called whenever a client sends an event that
// the pointer moved, or a button was pressed or released.
virtual void pointerEvent(const Point& /*pos*/,
- uint8_t /*buttonMask*/) {};
+ uint16_t /*buttonMask*/) {};
// handleClipboardRequest() is called whenever a client requests
// the server to send over its clipboard data. It will only be
diff --git a/common/rfb/SMsgHandler.cxx b/common/rfb/SMsgHandler.cxx
index 03917926..1dce634d 100644
--- a/common/rfb/SMsgHandler.cxx
+++ b/common/rfb/SMsgHandler.cxx
@@ -53,12 +53,13 @@ void SMsgHandler::setPixelFormat(const PixelFormat& pf)
void SMsgHandler::setEncodings(int nEncodings, const int32_t* encodings)
{
bool firstFence, firstContinuousUpdates, firstLEDState,
- firstQEMUKeyEvent;
+ firstQEMUKeyEvent, firstExtMouseButtonsEvent;
firstFence = !client.supportsFence();
firstContinuousUpdates = !client.supportsContinuousUpdates();
firstLEDState = !client.supportsLEDState();
firstQEMUKeyEvent = !client.supportsEncoding(pseudoEncodingQEMUKeyEvent);
+ firstExtMouseButtonsEvent = !client.supportsEncoding(pseudoEncodingExtendedMouseButtons);
client.setEncodings(nEncodings, encodings);
@@ -72,6 +73,8 @@ void SMsgHandler::setEncodings(int nEncodings, const int32_t* encodings)
supportsLEDState();
if (client.supportsEncoding(pseudoEncodingQEMUKeyEvent) && firstQEMUKeyEvent)
supportsQEMUKeyEvent();
+ if (client.supportsEncoding(pseudoEncodingExtendedMouseButtons) && firstExtMouseButtonsEvent)
+ supportsExtendedMouseButtons();
}
void SMsgHandler::keyEvent(uint32_t /*keysym*/, uint32_t /*keycode*/,
@@ -80,7 +83,7 @@ void SMsgHandler::keyEvent(uint32_t /*keysym*/, uint32_t /*keycode*/,
}
void SMsgHandler::pointerEvent(const Point& /*pos*/,
- uint8_t /*buttonMask*/)
+ uint16_t /*buttonMask*/)
{
}
@@ -167,3 +170,7 @@ void SMsgHandler::supportsLEDState()
void SMsgHandler::supportsQEMUKeyEvent()
{
}
+
+void SMsgHandler::supportsExtendedMouseButtons()
+{
+} \ No newline at end of file
diff --git a/common/rfb/SMsgHandler.h b/common/rfb/SMsgHandler.h
index cff8b1bd..c5d13d78 100644
--- a/common/rfb/SMsgHandler.h
+++ b/common/rfb/SMsgHandler.h
@@ -57,7 +57,7 @@ namespace rfb {
virtual void keyEvent(uint32_t keysym, uint32_t keycode,
bool down);
virtual void pointerEvent(const Point& pos,
- uint8_t buttonMask);
+ uint16_t buttonMask);
virtual void clientCutText(const char* str);
@@ -98,6 +98,11 @@ namespace rfb {
// handler will send a pseudo-rect back, signalling server support.
virtual void supportsQEMUKeyEvent();
+ // supportsExtendedMouseButtons() is called the first time we detect that the
+ // client supports sending 16 bit mouse button state. This lets us pass more button
+ // states between server and client.
+ virtual void supportsExtendedMouseButtons();
+
ClientParams client;
};
}
diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx
index 9ddea53d..0aa83e3a 100644
--- a/common/rfb/SMsgReader.cxx
+++ b/common/rfb/SMsgReader.cxx
@@ -272,11 +272,32 @@ bool SMsgReader::readKeyEvent()
bool SMsgReader::readPointerEvent()
{
+ int mask;
+ int x;
+ int y;
+
if (!is->hasData(1 + 2 + 2))
return false;
- int mask = is->readU8();
- int x = is->readU16();
- int y = is->readU16();
+
+ is->setRestorePoint();
+
+ mask = is->readU8();
+ x = is->readU16();
+ y = is->readU16();
+
+ if (handler->client.supportsExtendedMouseButtons() && mask & 0x80 ) {
+ int highBits;
+ int lowBits;
+
+ if (!is->hasDataOrRestore(1))
+ return false;
+
+ highBits = is->readU8();
+ lowBits = mask & 0x7f; /* Clear marker bit */
+ mask = (highBits << 7) | lowBits;
+ }
+
+ is->clearRestorePoint();
handler->pointerEvent(Point(x, y), mask);
return true;
}
diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx
index 0c03b51d..d1218c11 100644
--- a/common/rfb/SMsgWriter.cxx
+++ b/common/rfb/SMsgWriter.cxx
@@ -49,7 +49,7 @@ SMsgWriter::SMsgWriter(ClientParams* client_, rdr::OutStream* os_)
nRectsInUpdate(0), nRectsInHeader(0),
needSetDesktopName(false), needCursor(false),
needCursorPos(false), needLEDState(false),
- needQEMUKeyEvent(false)
+ needQEMUKeyEvent(false), needExtMouseButtonsEvent(false)
{
}
@@ -303,6 +303,14 @@ void SMsgWriter::writeQEMUKeyEvent()
needQEMUKeyEvent = true;
}
+void SMsgWriter::writeExtendedMouseButtonsSupport()
+{
+ if (!client->supportsEncoding(pseudoEncodingExtendedMouseButtons))
+ throw Exception("Client does not support Extended Mouse Buttons");
+
+ needExtMouseButtonsEvent = true;
+}
+
bool SMsgWriter::needFakeUpdate()
{
if (needSetDesktopName)
@@ -315,6 +323,8 @@ bool SMsgWriter::needFakeUpdate()
return true;
if (needQEMUKeyEvent)
return true;
+ if (needExtMouseButtonsEvent)
+ return true;
if (needNoDataUpdate())
return true;
@@ -363,6 +373,8 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects)
nRects++;
if (needQEMUKeyEvent)
nRects++;
+ if (needExtMouseButtonsEvent)
+ nRects++;
}
os->writeU16(nRects);
@@ -502,6 +514,11 @@ void SMsgWriter::writePseudoRects()
writeQEMUKeyEventRect();
needQEMUKeyEvent = false;
}
+
+ if (needExtMouseButtonsEvent) {
+ writeExtendedMouseButtonsRect();
+ needExtMouseButtonsEvent = false;
+ }
}
void SMsgWriter::writeNoDataRects()
@@ -734,3 +751,17 @@ void SMsgWriter::writeQEMUKeyEventRect()
os->writeU16(0);
os->writeU32(pseudoEncodingQEMUKeyEvent);
}
+
+void SMsgWriter::writeExtendedMouseButtonsRect()
+{
+ if (!client->supportsEncoding(pseudoEncodingExtendedMouseButtons))
+ throw Exception("Client does not support extended mouse button events");
+ if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::writeExtendedMouseButtonsRect: nRects out of sync");
+
+ os->writeS16(0);
+ os->writeS16(0);
+ os->writeU16(0);
+ os->writeU16(0);
+ os->writeU32(pseudoEncodingExtendedMouseButtons);
+}
diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h
index c46551e9..7bc0ed6a 100644
--- a/common/rfb/SMsgWriter.h
+++ b/common/rfb/SMsgWriter.h
@@ -93,6 +93,9 @@ namespace rfb {
// And QEMU keyboard event handshake
void writeQEMUKeyEvent();
+ // let the client know we support extended mouse button support
+ void writeExtendedMouseButtonsSupport();
+
// needFakeUpdate() returns true when an immediate update is needed in
// order to flush out pseudo-rectangles to the client.
bool needFakeUpdate();
@@ -148,6 +151,7 @@ namespace rfb {
void writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY);
void writeLEDStateRect(uint8_t state);
void writeQEMUKeyEventRect();
+ void writeExtendedMouseButtonsRect();
ClientParams* client;
rdr::OutStream* os;
@@ -160,6 +164,7 @@ namespace rfb {
bool needCursorPos;
bool needLEDState;
bool needQEMUKeyEvent;
+ bool needExtMouseButtonsEvent;
typedef struct {
uint16_t reason, result;
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 88deff8c..7a796dc2 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -477,7 +477,7 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf)
setCursor();
}
-void VNCSConnectionST::pointerEvent(const Point& pos, uint8_t buttonMask)
+void VNCSConnectionST::pointerEvent(const Point& pos, uint16_t buttonMask)
{
if (rfb::Server::idleTimeout)
idleTimer.start(secsToMillis(rfb::Server::idleTimeout));
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index d857ef32..17de9d01 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -123,7 +123,7 @@ namespace rfb {
void queryConnection(const char* userName) override;
void clientInit(bool shared) override;
void setPixelFormat(const PixelFormat& pf) override;
- void pointerEvent(const Point& pos, uint8_t buttonMask) override;
+ void pointerEvent(const Point& pos, uint16_t buttonMask) override;
void keyEvent(uint32_t keysym, uint32_t keycode,
bool down) override;
void framebufferUpdateRequest(const Rect& r,
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 114ff347..977fa937 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -482,7 +482,7 @@ void VNCServerST::keyEvent(uint32_t keysym, uint32_t keycode, bool down)
}
void VNCServerST::pointerEvent(VNCSConnectionST* client,
- const Point& pos, uint8_t buttonMask)
+ const Point& pos, uint16_t buttonMask)
{
time_t now = time(nullptr);
if (rfb::Server::maxIdleTime)
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 6cc75a68..dc4f9aad 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -117,7 +117,7 @@ namespace rfb {
// Event handlers
void keyEvent(uint32_t keysym, uint32_t keycode, bool down);
- void pointerEvent(VNCSConnectionST* client, const Point& pos, uint8_t buttonMask);
+ void pointerEvent(VNCSConnectionST* client, const Point& pos, uint16_t buttonMask);
void handleClipboardRequest(VNCSConnectionST* client);
void handleClipboardAnnounce(VNCSConnectionST* client, bool available);
diff --git a/common/rfb/encodings.h b/common/rfb/encodings.h
index e427572f..16868460 100644
--- a/common/rfb/encodings.h
+++ b/common/rfb/encodings.h
@@ -36,6 +36,7 @@ namespace rfb {
const int pseudoEncodingXCursor = -240;
const int pseudoEncodingCursor = -239;
+ const int pseudoEncodingExtendedMouseButtons = -316;
const int pseudoEncodingDesktopSize = -223;
const int pseudoEncodingLEDState = -261;
const int pseudoEncodingExtendedDesktopSize = -308;