Skip to content

Commit

Permalink
Support forward and back mouse button events
Browse files Browse the repository at this point in the history
  • Loading branch information
dcommander committed Jan 15, 2025
1 parent 98ded85 commit 8cef2c6
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 28 deletions.
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ if bump scrolling is enabled. Setting the `turbovnc.fshidedock` system
property to `0` or `1` causes the viewer to always show or always hide the menu
bar and dock in full-screen mode, irrespective of bump scrolling.

12. The TurboVNC Server and Viewer now implement the Extended Mouse Buttons
RFB extension, which allows forward and back mouse button events to be
transmitted to the VNC server.


3.1.4
=====
Expand Down
7 changes: 5 additions & 2 deletions common/rfb/rfbproto.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (C) 2009-2010, 2012-2013, 2015, 2022, 2024 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2009-2010, 2012-2013, 2015, 2022, 2024-2025
* D. R. Commander. All Rights Reserved.
* Copyright (C) 2009 Vic Lee. All Rights Reserved.
* Copyright (C) 2004-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (C) 2000-2006 Constantin Kaplinsky. All Rights Reserved.
Expand Down Expand Up @@ -507,6 +507,7 @@ typedef struct _rfbInteractionCapsMsg {
* 0xFFFFFE00 .. 0xFFFFFE64 -- fine-grained quality level (0-100 scale)
* -512 .. -412
* 0xFFFFFEC3 -- Tight encoding without zlib
* 0xFFFFFEC4 -- Extended mouse buttons
* 0xFFFFFEC7 .. 0xFFFFFEC8 -- flow control extensions
* -313 .. -312
* 0xFFFFFECC -- extended desktop size
Expand Down Expand Up @@ -546,6 +547,8 @@ typedef struct _rfbInteractionCapsMsg {

#define rfbEncodingTightWithoutZlib 0xFFFFFEC3 /* -317 */

#define rfbEncodingExtendedMouseButtons 0xFFFFFEC4 /* -316 */

#define rfbEncodingContinuousUpdates 0xFFFFFEC7 /* -313 */
#define rfbEncodingFence 0xFFFFFEC8 /* -312 */

Expand Down
6 changes: 4 additions & 2 deletions java/com/turbovnc/rfb/CMsgHandler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (C) 2011-2012, 2015, 2018, 2022 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2011-2012, 2015, 2018, 2022, 2025 D. R. Commander.
* All Rights Reserved.
* Copyright 2009-2011, 2019 Pierre Ossman for Cendio AB
* Copyright (C) 2011 Brian P. Hinz
* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Expand Down Expand Up @@ -115,6 +115,8 @@ public void endOfContinuousUpdates() {
public abstract void enableQEMUExtKeyEvent();
public abstract void setLEDState(int state);

public abstract void enableExtMouseButtons();

public abstract void setCursor(int width, int height, Point hotspot,
int[] data, byte[] mask);
public abstract void serverInit();
Expand Down
6 changes: 5 additions & 1 deletion java/com/turbovnc/rfb/CMsgReader.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* Copyright (C) 2012, 2017-2018, 2022 D. R. Commander. All Rights Reserved.
/* Copyright (C) 2012, 2017-2018, 2022, 2025 D. R. Commander.
* All Rights Reserved.
* Copyright 2016, 2018-2019 Pierre Ossman for Cendio AB
* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
Expand Down Expand Up @@ -346,6 +347,9 @@ public void readMsg(Params params) {
case RFB.ENCODING_VMWARE_LED_STATE:
readVMwareLEDState();
break;
case RFB.ENCODING_EXTENDED_MOUSE_BUTTONS:
handler.enableExtMouseButtons();
break;
default:
readRect(new Rect(x, y, x + w, y + h), encoding);
break;
Expand Down
11 changes: 10 additions & 1 deletion java/com/turbovnc/rfb/CMsgWriter.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2012, 2015, 2017-2018, 2020-2024 D. R. Commander.
/* Copyright (C) 2012, 2015, 2017-2018, 2020-2025 D. R. Commander.
* All Rights Reserved.
* Copyright 2009-2011, 2017-2019 Pierre Ossman for Cendio AB
* Copyright (C) 2011, 2015 Brian P. Hinz
Expand Down Expand Up @@ -339,10 +339,18 @@ public synchronized void writePointerEvent(Point pos, int buttonMask)
if (p.x >= cp.width) p.x = cp.width - 1;
if (p.y >= cp.height) p.y = cp.height - 1;

int extButtonMask = 0;
if (cp.supportsExtMouseButtons && (buttonMask & 0xFF80) != 0) {
extButtonMask = (buttonMask & 0xFF80) >> 7;
buttonMask = (buttonMask & 0x7F) | 0x80;
}

startMsg(RFB.POINTER_EVENT);
os.writeU8(buttonMask);
os.writeU16(p.x);
os.writeU16(p.y);
if (extButtonMask != 0)
os.writeU8(extButtonMask);
endMsg();
}

Expand Down Expand Up @@ -419,6 +427,7 @@ public synchronized void writeSetEncodings(int preferredEncoding,
encodings[nEncodings++] = RFB.ENCODING_VMWARE_LED_STATE;
}
encodings[nEncodings++] = RFB.ENCODING_TIGHT_WITHOUT_ZLIB;
encodings[nEncodings++] = RFB.ENCODING_EXTENDED_MOUSE_BUTTONS;

if (Decoder.supported(preferredEncoding)) {
encodings[nEncodings++] = preferredEncoding;
Expand Down
5 changes: 3 additions & 2 deletions java/com/turbovnc/rfb/ConnParams.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (C) 2011-2012, 2015, 2018, 2022, 2024 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2011-2012, 2015, 2018, 2022, 2024-2025 D. R. Commander.
* All Rights Reserved.
* Copyright 2019 Pierre Ossman for Cendio AB
* Copyright (C) 2012 Brian P. Hinz
* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Expand Down Expand Up @@ -148,6 +148,7 @@ public void setClipboardCaps(int flags, int[] lengths)
public boolean supportsLastRect;
public boolean supportsGII;
public boolean supportsQEMUExtKeyEvent;
public boolean supportsExtMouseButtons;
public int ledState = RFB.LED_UNKNOWN;

public boolean supportsSetDesktopSize;
Expand Down
8 changes: 6 additions & 2 deletions java/com/turbovnc/rfb/RFB.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (C) 2011-2012, 2015-2018, 2021-2022, 2024 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2011-2012, 2015-2018, 2021-2022, 2024-2025
* D. R. Commander. All Rights Reserved.
* Copyright 2009, 2011, 2019 Pierre Ossman for Cendio AB
* Copyright (C) 2011-2012 Brian P. Hinz
* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Expand Down Expand Up @@ -219,6 +219,8 @@ public static String encodingName(int num) {

public static final int ENCODING_TIGHT_WITHOUT_ZLIB = -317;

public static final int ENCODING_EXTENDED_MOUSE_BUTTONS = -316;

public static final int ENCODING_CONTINUOUS_UPDATES = -313;
public static final int ENCODING_FENCE = -312;

Expand Down Expand Up @@ -341,6 +343,8 @@ public static String encodingName(int num) {
public static final int BUTTON5_MASK = 16;
public static final int BUTTON6_MASK = 32;
public static final int BUTTON7_MASK = 64;
public static final int BUTTON8_MASK = 128;
public static final int BUTTON9_MASK = 256;

//***************************************************************************
// GII
Expand Down
71 changes: 61 additions & 10 deletions java/com/turbovnc/vncviewer/CConn.java
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,11 @@ public void enableQEMUExtKeyEvent() {
}
}

public void enableExtMouseButtons() {
vlog.info("Enabling Extended Mouse Buttons");
cp.supportsExtMouseButtons = true;
}

// Sync server's LED state with the client's
public void pushLEDState()
{
Expand Down Expand Up @@ -2820,6 +2825,8 @@ public void writePointerEvent(MouseEvent ev) {
if (state() != RFBSTATE_NORMAL || shuttingDown || benchmark)
return;

boolean debugButton = true;

switch (ev.getID()) {
case MouseEvent.MOUSE_PRESSED:
switch (ev.getButton()) {
Expand All @@ -2832,15 +2839,39 @@ public void writePointerEvent(MouseEvent ev) {
case 4:
// X11 uses Buttons 6 and 7 for (respectively) left and right
// scroll wheel events, but Java/X11 uses Buttons 4 and 5.
if (!Utils.isX11()) return;
buttonMask |= RFB.BUTTON6_MASK; break;
if (Utils.isX11()) {
buttonMask |= RFB.BUTTON6_MASK;
debugButton = false;
// X11 uses Buttons 8 and 9 for (respectively) back and forward
// buttons, but Java/macOS and Java/Windows use Buttons 4 and 5.
} else if (cp.supportsExtMouseButtons)
buttonMask |= RFB.BUTTON8_MASK;
else return;
break;
case 5:
if (!Utils.isX11()) return;
buttonMask |= RFB.BUTTON7_MASK; break;
if (Utils.isX11()) {
buttonMask |= RFB.BUTTON7_MASK;
debugButton = false;
} else if (cp.supportsExtMouseButtons)
buttonMask |= RFB.BUTTON9_MASK;
else return;
break;
case 6:
// X11 uses Buttons 8 and 9 for (respectively) back and forward
// buttons, but Java/X11 uses Buttons 6 and 7.
if (Utils.isX11() && cp.supportsExtMouseButtons)
buttonMask |= RFB.BUTTON8_MASK;
else return;
break;
case 7:
if (Utils.isX11() && cp.supportsExtMouseButtons)
buttonMask |= RFB.BUTTON9_MASK;
else return;
break;
default:
return;
}
if (ev.getButton() <= 3)
if (debugButton)
vlog.debug("mouse PRESS, button " + ev.getButton() +
", coords " + ev.getX() + "," + ev.getY());
break;
Expand All @@ -2853,15 +2884,35 @@ public void writePointerEvent(MouseEvent ev) {
case 3:
buttonMask &= ~RFB.BUTTON3_MASK; break;
case 4:
if (!Utils.isX11()) return;
buttonMask &= ~RFB.BUTTON6_MASK; break;
if (Utils.isX11()) {
buttonMask &= ~RFB.BUTTON6_MASK;
debugButton = false;
} else if (cp.supportsExtMouseButtons)
buttonMask &= ~RFB.BUTTON8_MASK;
else return;
break;
case 5:
if (!Utils.isX11()) return;
buttonMask &= ~RFB.BUTTON7_MASK; break;
if (Utils.isX11()) {
buttonMask &= ~RFB.BUTTON7_MASK;
debugButton = false;
} else if (cp.supportsExtMouseButtons)
buttonMask &= ~RFB.BUTTON9_MASK;
else return;
break;
case 6:
if (Utils.isX11() && cp.supportsExtMouseButtons)
buttonMask &= ~RFB.BUTTON8_MASK;
else return;
break;
case 7:
if (Utils.isX11() && cp.supportsExtMouseButtons)
buttonMask &= ~RFB.BUTTON9_MASK;
else return;
break;
default:
return;
}
if (ev.getButton() <= 3)
if (debugButton)
vlog.debug("mouse release, button " + ev.getButton() +
", coords " + ev.getX() + "," + ev.getY());
break;
Expand Down
6 changes: 3 additions & 3 deletions unix/Xvnc/programs/Xserver/hw/vnc/kbdptr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
*
*/

/* Copyright (C) 2014-2016, 2019, 2021-2022, 2024 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2014-2016, 2019, 2021-2022, 2024-2025 D. R. Commander.
* All Rights Reserved.
* Copyright (C) 2013, 2017-2018 Pierre Ossman for Cendio AB.
* All Rights Reserved.
* Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
Expand Down Expand Up @@ -526,7 +526,7 @@ void PtrAddEvent(int buttonMask, int x, int y)
cursorPosY = y;
}

for (i = 0; i < 7; i++) {
for (i = 0; i < 9; i++) {
if ((buttonMask ^ oldButtonMask) & (1 << i)) {
if (buttonMask & (1 << i)) {
valuator_mask_set_range(&mask, 0, 0, NULL);
Expand Down
6 changes: 5 additions & 1 deletion unix/Xvnc/programs/Xserver/hw/vnc/rfb.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* rfb.h - header file for RFB DDX implementation.
*/

/* Copyright (C) 2010-2024 D. R. Commander. All Rights Reserved.
/* Copyright (C) 2010-2025 D. R. Commander. All Rights Reserved.
* Copyright (C) 2011, 2015 Pierre Ossman for Cendio AB. All Rights Reserved.
* Copyright (C) 2011 Joel Martin
* Copyright (C) 2011 Gernot Tenchio
Expand Down Expand Up @@ -444,6 +444,8 @@ typedef struct rfbClientRec {
extension */
Bool enableTightWithoutZlib; /* client supports Tight Encoding Without
Zlib extension */
Bool enableExtMouseButtons; /* client supports Extended Mouse Buttons
extension */
Bool useRichCursorEncoding; /* rfbEncodingRichCursor is preferred */
Bool cursorWasChanged; /* cursor shape update should be sent */
Bool cursorWasMoved; /* cursor position update should be sent */
Expand Down Expand Up @@ -493,6 +495,8 @@ typedef struct rfbClientRec {
Bool pendingDesktopResize, pendingExtDesktopResize;
int reason, result;

Bool pendingExtMouseButtonsRect;

/* Server-side key mapping */
Bool pendingQEMUExtKeyEventRect, pendingLEDState;
unsigned int ledState;
Expand Down
Loading

0 comments on commit 8cef2c6

Please sign in to comment.