Skip to content

Commit

Permalink
Merge branch 'mouse-button-support' of https://github.com/CendioHalim…
Browse files Browse the repository at this point in the history
  • Loading branch information
CendioOssman committed Nov 18, 2024
2 parents 0959ce9 + c40d8a4 commit 5816986
Show file tree
Hide file tree
Showing 37 changed files with 217 additions and 57 deletions.
1 change: 1 addition & 0 deletions common/rfb/CConnection.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ void CConnection::updateEncodings()
encodings.push_back(pseudoEncodingContinuousUpdates);
encodings.push_back(pseudoEncodingFence);
encodings.push_back(pseudoEncodingQEMUKeyEvent);
encodings.push_back(pseudoEncodingExtendedMouseButtons);

if (Decoder::supported(preferredEncoding)) {
encodings.push_back(preferredEncoding);
Expand Down
5 changes: 5 additions & 0 deletions common/rfb/CMsgHandler.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ void CMsgHandler::endOfContinuousUpdates()
server.supportsContinuousUpdates = true;
}

void CMsgHandler::supportsExtendedMouseButtons()
{
server.supportsExtendedMouseButtons = true;
}

void CMsgHandler::supportsQEMUKeyEvent()
{
server.supportsQEMUKeyEvent = true;
Expand Down
1 change: 1 addition & 0 deletions common/rfb/CMsgHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ namespace rfb {
virtual void fence(uint32_t flags, unsigned len, const uint8_t data[]);
virtual void endOfContinuousUpdates();
virtual void supportsQEMUKeyEvent();
virtual void supportsExtendedMouseButtons();
virtual void serverInit(int width, int height,
const PixelFormat& pf,
const char* name) = 0;
Expand Down
4 changes: 4 additions & 0 deletions common/rfb/CMsgReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ bool CMsgReader::readMsg()
handler->supportsQEMUKeyEvent();
ret = true;
break;
case pseudoEncodingExtendedMouseButtons:
handler->supportsExtendedMouseButtons();
ret = true;
break;
default:
ret = readRect(dataRect, rectEncoding);
break;
Expand Down
38 changes: 34 additions & 4 deletions common/rfb/CMsgWriter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#endif

#include <stdio.h>
#include <assert.h>

#include <rdr/OutStream.h>
#include <rdr/MemOutStream.h>
Expand Down Expand Up @@ -172,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();
}

Expand Down
2 changes: 1 addition & 1 deletion common/rfb/CMsgWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ namespace rfb {
void writeFence(uint32_t flags, unsigned len, const uint8_t data[]);

void writeKeyEvent(uint32_t keysym, uint32_t keycode, bool down);
void writePointerEvent(const Point& pos, uint8_t buttonMask);
void writePointerEvent(const Point& pos, uint16_t buttonMask);

void writeClientCutText(const char* str);

Expand Down
7 changes: 7 additions & 0 deletions common/rfb/ClientParams.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,10 @@ bool ClientParams::supportsContinuousUpdates() const
return true;
return false;
}

bool ClientParams::supportsExtendedMouseButtons() const
{
if (supportsEncoding(pseudoEncodingExtendedMouseButtons))
return true;
return false;
}
1 change: 1 addition & 0 deletions common/rfb/ClientParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ namespace rfb {
bool supportsLEDState() const;
bool supportsFence() const;
bool supportsContinuousUpdates() const;
bool supportsExtendedMouseButtons() const;

int compressLevel;
int qualityLevel;
Expand Down
5 changes: 5 additions & 0 deletions common/rfb/SConnection.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,11 @@ void SConnection::supportsQEMUKeyEvent()
writer()->writeQEMUKeyEvent();
}

void SConnection::supportsExtendedMouseButtons()
{
writer()->writeExtendedMouseButtonsSupport();
}

void SConnection::versionReceived()
{
}
Expand Down
2 changes: 2 additions & 0 deletions common/rfb/SConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ namespace rfb {

void supportsQEMUKeyEvent() override;

virtual void supportsExtendedMouseButtons() override;


// Methods to be overridden in a derived class

Expand Down
2 changes: 1 addition & 1 deletion common/rfb/SDesktop.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 9 additions & 2 deletions common/rfb/SMsgHandler.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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*/,
Expand All @@ -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*/)
{
}

Expand Down Expand Up @@ -167,3 +170,7 @@ void SMsgHandler::supportsLEDState()
void SMsgHandler::supportsQEMUKeyEvent()
{
}

void SMsgHandler::supportsExtendedMouseButtons()
{
}
7 changes: 6 additions & 1 deletion common/rfb/SMsgHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
};
}
Expand Down
27 changes: 24 additions & 3 deletions common/rfb/SMsgReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
33 changes: 32 additions & 1 deletion common/rfb/SMsgWriter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,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)
{
}

Expand Down Expand Up @@ -302,6 +302,14 @@ void SMsgWriter::writeQEMUKeyEvent()
needQEMUKeyEvent = true;
}

void SMsgWriter::writeExtendedMouseButtonsSupport()
{
if (!client->supportsEncoding(pseudoEncodingExtendedMouseButtons))
throw std::logic_error("Client does not support Extended Mouse Buttons");

needExtMouseButtonsEvent = true;
}

bool SMsgWriter::needFakeUpdate()
{
if (needSetDesktopName)
Expand All @@ -314,6 +322,8 @@ bool SMsgWriter::needFakeUpdate()
return true;
if (needQEMUKeyEvent)
return true;
if (needExtMouseButtonsEvent)
return true;
if (needNoDataUpdate())
return true;

Expand Down Expand Up @@ -362,6 +372,8 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects)
nRects++;
if (needQEMUKeyEvent)
nRects++;
if (needExtMouseButtonsEvent)
nRects++;
}

os->writeU16(nRects);
Expand Down Expand Up @@ -501,6 +513,11 @@ void SMsgWriter::writePseudoRects()
writeQEMUKeyEventRect();
needQEMUKeyEvent = false;
}

if (needExtMouseButtonsEvent) {
writeExtendedMouseButtonsRect();
needExtMouseButtonsEvent = false;
}
}

void SMsgWriter::writeNoDataRects()
Expand Down Expand Up @@ -733,3 +750,17 @@ void SMsgWriter::writeQEMUKeyEventRect()
os->writeU16(0);
os->writeU32(pseudoEncodingQEMUKeyEvent);
}

void SMsgWriter::writeExtendedMouseButtonsRect()
{
if (!client->supportsEncoding(pseudoEncodingExtendedMouseButtons))
throw std::logic_error("Client does not support extended mouse button events");
if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
throw std::logic_error("SMsgWriter::writeExtendedMouseButtonsRect: nRects out of sync");

os->writeS16(0);
os->writeS16(0);
os->writeU16(0);
os->writeU16(0);
os->writeU32(pseudoEncodingExtendedMouseButtons);
}
5 changes: 5 additions & 0 deletions common/rfb/SMsgWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand All @@ -160,6 +164,7 @@ namespace rfb {
bool needCursorPos;
bool needLEDState;
bool needQEMUKeyEvent;
bool needExtMouseButtonsEvent;

typedef struct {
uint16_t reason, result;
Expand Down
2 changes: 1 addition & 1 deletion common/rfb/ServerParams.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ServerParams::ServerParams()
: majorVersion(0), minorVersion(0),
supportsQEMUKeyEvent(false),
supportsSetDesktopSize(false), supportsFence(false),
supportsContinuousUpdates(false),
supportsContinuousUpdates(false), supportsExtendedMouseButtons(false),
width_(0), height_(0),
ledState_(ledUnknown)
{
Expand Down
1 change: 1 addition & 0 deletions common/rfb/ServerParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace rfb {
bool supportsSetDesktopSize;
bool supportsFence;
bool supportsContinuousUpdates;
bool supportsExtendedMouseButtons;

private:

Expand Down
2 changes: 1 addition & 1 deletion common/rfb/VNCSConnectionST.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,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));
Expand Down
2 changes: 1 addition & 1 deletion common/rfb/VNCSConnectionST.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion common/rfb/VNCServerST.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,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)
Expand Down
Loading

0 comments on commit 5816986

Please sign in to comment.