diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx index c1c6ad17c..1a84807a9 100644 --- a/common/rfb/CMsgReader.cxx +++ b/common/rfb/CMsgReader.cxx @@ -118,9 +118,6 @@ bool CMsgReader::readMsg() case msgTypeEndOfContinuousUpdates: ret = readEndOfContinuousUpdates(); break; - case msgTypeExtendedMouseSupport: - ret = readSupportExtendedMouseButton(); - break; default: throw Exception("Unknown message type %d", currentMsgType); } @@ -205,6 +202,10 @@ bool CMsgReader::readMsg() handler->supportsQEMUKeyEvent(); ret = true; break; + case pseudoEncodingExtendedMouseButtons: + handler->supportExtendedMouseButtons(); + ret = true; + break; default: ret = readRect(dataRect, rectEncoding); break; @@ -457,12 +458,6 @@ bool CMsgReader::readEndOfContinuousUpdates() return true; } -bool CMsgReader::readSupportExtendedMouseButton() -{ - handler->supportExtendedMouseButtons(); - return true; -} - bool CMsgReader::readFramebufferUpdate() { if (!is->hasData(1 + 2)) diff --git a/common/rfb/CMsgReader.h b/common/rfb/CMsgReader.h index 8000762bc..3b1c0ddbd 100644 --- a/common/rfb/CMsgReader.h +++ b/common/rfb/CMsgReader.h @@ -56,7 +56,6 @@ namespace rfb { bool readExtendedClipboard(int32_t len); bool readFence(); bool readEndOfContinuousUpdates(); - bool readSupportExtendedMouseButton(); bool readFramebufferUpdate(); diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx index 8ba87e801..99ed49357 100644 --- a/common/rfb/CMsgWriter.cxx +++ b/common/rfb/CMsgWriter.cxx @@ -182,29 +182,22 @@ void CMsgWriter::writePointerEvent(const Point& pos, int buttonMask) if (p.x >= server->width()) p.x = server->width() - 1; if (p.y >= server->height()) p.y = server->height() - 1; - if (server->supportsExtendedMouseButtons) - { - writePointerEventExt(pos,buttonMask); - return; + if (server->supportsExtendedMouseButtons) { + startMsg(msgTypePointerEventExt); + os->writeU16(buttonMask); + os->writeU16(p.x); + os->writeU16(p.y); + endMsg(); + } + else { + startMsg(msgTypePointerEvent); + os->writeU8(buttonMask); + os->writeU16(p.x); + os->writeU16(p.y); + endMsg(); } - - startMsg(msgTypePointerEvent); - os->writeU8(buttonMask); - os->writeU16(p.x); - os->writeU16(p.y); - endMsg(); -} - -void CMsgWriter::writePointerEventExt(const Point& p, int buttonMask) -{ - startMsg(msgTypePointerEventExt); - os->writeU16(buttonMask); - os->writeU16(p.x); - os->writeU16(p.y); - endMsg(); } - void CMsgWriter::writeClientCutText(const char* str) { if (strchr(str, '\r') != NULL) diff --git a/common/rfb/CMsgWriter.h b/common/rfb/CMsgWriter.h index 1b76c1da6..1b70a1d01 100644 --- a/common/rfb/CMsgWriter.h +++ b/common/rfb/CMsgWriter.h @@ -55,7 +55,6 @@ namespace rfb { void writeKeyEvent(uint32_t keysym, uint32_t keycode, bool down); void writePointerEvent(const Point& pos, int buttonMask); - void writePointerEventExt(const Point& pos, int buttonMask); void writeClientCutText(const char* str); diff --git a/common/rfb/SMsgHandler.cxx b/common/rfb/SMsgHandler.cxx index 972620707..bee4530f8 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, firstExtMouseButtonEvent; firstFence = !client.supportsFence(); firstContinuousUpdates = !client.supportsContinuousUpdates(); firstLEDState = !client.supportsLEDState(); firstQEMUKeyEvent = !client.supportsEncoding(pseudoEncodingQEMUKeyEvent); + firstExtMouseButtonEvent = !client.supportsEncoding(pseudoEncodingExtendedMouseButtons); client.setEncodings(nEncodings, encodings); @@ -72,7 +73,7 @@ void SMsgHandler::setEncodings(int nEncodings, const int32_t* encodings) supportsLEDState(); if (client.supportsEncoding(pseudoEncodingQEMUKeyEvent) && firstQEMUKeyEvent) supportsQEMUKeyEvent(); - if (client.supportsEncoding(pseudoEncodingExtendedMouseButtons)) + if (client.supportsEncoding(pseudoEncodingExtendedMouseButtons) && firstExtMouseButtonEvent) supportsExtendedMouseButtons(); } diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx index cdb284d24..6cdb9e2be 100644 --- a/common/rfb/SMsgReader.cxx +++ b/common/rfb/SMsgReader.cxx @@ -100,7 +100,7 @@ bool SMsgReader::readMsg() ret = readPointerEvent(); break; case msgTypePointerEventExt: - ret = readPointerEvenExt(); + ret = readPointerEventExt(); break; case msgTypeClientCutText: ret = readClientCutText(); @@ -284,7 +284,7 @@ bool SMsgReader::readPointerEvent() return true; } -bool SMsgReader::readPointerEvenExt() +bool SMsgReader::readPointerEventExt() { if (!is->hasData(2 + 2 + 2)) return false; diff --git a/common/rfb/SMsgReader.h b/common/rfb/SMsgReader.h index 0a5b287d9..6b64e5df5 100644 --- a/common/rfb/SMsgReader.h +++ b/common/rfb/SMsgReader.h @@ -53,7 +53,7 @@ namespace rfb { bool readKeyEvent(); bool readPointerEvent(); - bool readPointerEvenExt(); + bool readPointerEventExt(); bool readClientCutText(); bool readExtendedClipboard(int32_t len); diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index 39ce3699e..a25c558ab 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -50,6 +50,7 @@ SMsgWriter::SMsgWriter(ClientParams* client_, rdr::OutStream* os_) needSetDesktopName(false), needCursor(false), needCursorPos(false), needLEDState(false), needQEMUKeyEvent(false) + ,needExtMouseButtonEvent(false) { } @@ -307,9 +308,8 @@ void SMsgWriter::writeExtendedMouseButtonSupport() { if (!client->supportsEncoding(pseudoEncodingExtendedMouseButtons)) throw Exception("Client does not support Extended Mouse Buttons"); - - startMsg(msgTypeExtendedMouseSupport); - endMsg(); + + needExtMouseButtonEvent = true; } bool SMsgWriter::needFakeUpdate() @@ -324,6 +324,8 @@ bool SMsgWriter::needFakeUpdate() return true; if (needQEMUKeyEvent) return true; + if (needExtMouseButtonEvent) + return true; if (needNoDataUpdate()) return true; @@ -372,6 +374,8 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects) nRects++; if (needQEMUKeyEvent) nRects++; + if (needExtMouseButtonEvent) + nRects++; } os->writeU16(nRects); @@ -511,6 +515,11 @@ void SMsgWriter::writePseudoRects() writeQEMUKeyEventRect(); needQEMUKeyEvent = false; } + + if (needExtMouseButtonEvent) { + writeExtendedMouseButtonRect(); + needExtMouseButtonEvent = false; + } } void SMsgWriter::writeNoDataRects() @@ -744,3 +753,17 @@ void SMsgWriter::writeQEMUKeyEventRect() os->writeU16(0); os->writeU32(pseudoEncodingQEMUKeyEvent); } + +void SMsgWriter::writeExtendedMouseButtonRect() +{ + if (!client->supportsEncoding(pseudoEncodingExtendedMouseButtons)) + throw Exception("Client does not support extended mouse button events"); + if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader) + throw Exception("SMsgWriter::writeExtendedMouseButtonRect: 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 71cf2bbe4..e96257ea6 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -151,6 +151,7 @@ namespace rfb { void writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY); void writeLEDStateRect(uint8_t state); void writeQEMUKeyEventRect(); + void writeExtendedMouseButtonRect(); ClientParams* client; rdr::OutStream* os; @@ -163,6 +164,7 @@ namespace rfb { bool needCursorPos; bool needLEDState; bool needQEMUKeyEvent; + bool needExtMouseButtonEvent; typedef struct { uint16_t reason, result; diff --git a/common/rfb/msgTypes.h b/common/rfb/msgTypes.h index e2bc3423f..14fb6037f 100644 --- a/common/rfb/msgTypes.h +++ b/common/rfb/msgTypes.h @@ -28,8 +28,6 @@ namespace rfb { const int msgTypeEndOfContinuousUpdates = 150; - const int msgTypeExtendedMouseSupport = 151; - const int msgTypeServerFence = 248; // client to server diff --git a/java/com/tigervnc/rfb/CMsgReader.java b/java/com/tigervnc/rfb/CMsgReader.java index 2289535d8..5dd9402e1 100644 --- a/java/com/tigervnc/rfb/CMsgReader.java +++ b/java/com/tigervnc/rfb/CMsgReader.java @@ -80,9 +80,6 @@ public void readMsg() case MsgTypes.msgTypeEndOfContinuousUpdates: readEndOfContinuousUpdates(); break; - case MsgTypes.msgTypeExtendedMouseSupport: - readSupportExtendedMouseButton(); - break; default: vlog.error("unknown message type "+type); throw new Exception("unknown message type"); @@ -119,6 +116,9 @@ public void readMsg() case Encodings.pseudoEncodingExtendedDesktopSize: readExtendedDesktopSize(x, y, w, h); break; + case Encodings.pseudoEncodingExtendedMouseButtons: + handler.SupportExtendedMouseButton(); + break; case Encodings.pseudoEncodingClientRedirect: nUpdateRectsLeft = 0; readClientRedirect(x, y, w, h); @@ -195,11 +195,6 @@ protected void readEndOfContinuousUpdates() handler.endOfContinuousUpdates(); } - protected void readSupportExtendedMouseButton() - { - handler.SupportExtendedMouseButton(); - } - protected void readFramebufferUpdate() { is.skip(1); diff --git a/java/com/tigervnc/rfb/CMsgWriter.java b/java/com/tigervnc/rfb/CMsgWriter.java index 27a24ee2c..b92c181ea 100644 --- a/java/com/tigervnc/rfb/CMsgWriter.java +++ b/java/com/tigervnc/rfb/CMsgWriter.java @@ -150,26 +150,20 @@ synchronized public void writePointerEvent(Point pos, int buttonMask) if (p.x >= server.width()) p.x = server.width() - 1; if (p.y >= server.height()) p.y = server.height() - 1; - if(server.supportsExtendedMouseButtons) - { - writePointerEventExt(pos,buttonMask); - return; + if(server.supportsExtendedMouseButtons) { + startMsg(MsgTypes.msgTypePointerEventExt); + os.writeU16(buttonMask); + os.writeU16(p.x); + os.writeU16(p.y); + endMsg(); + } + else { + startMsg(MsgTypes.msgTypePointerEvent); + os.writeU8(buttonMask); + os.writeU16(p.x); + os.writeU16(p.y); + endMsg(); } - - startMsg(MsgTypes.msgTypePointerEvent); - os.writeU8(buttonMask); - os.writeU16(p.x); - os.writeU16(p.y); - endMsg(); - } - - synchronized public void writePointerEventExt(Point p, int buttonMask) - { - startMsg(MsgTypes.msgTypePointerEventExt); - os.writeU16(buttonMask); - os.writeU16(p.x); - os.writeU16(p.y); - endMsg(); } synchronized public void writeClientCutText(String str, int len) diff --git a/java/com/tigervnc/vncviewer/Viewport.java b/java/com/tigervnc/vncviewer/Viewport.java index 4bbf39a14..654e4dbb8 100644 --- a/java/com/tigervnc/vncviewer/Viewport.java +++ b/java/com/tigervnc/vncviewer/Viewport.java @@ -257,14 +257,14 @@ public int handle(MouseEvent e) if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) != 0) buttonMask |= 4; - //there are no masks for buttons 4 and 5 so we need to check for them only when pressed. - if (tk.areExtraMouseButtonsEnabled() && e.getID() == MouseEvent.MOUSE_PRESSED) { + //there are no masks for buttons 6 and 7 so we need to check for them only when pressed. + if (tk.areExtraMouseButtonsEnabled()){ //Back - if (MouseInfo.getNumberOfButtons() >= 4 && e.getButton() == 6) - buttonMask |= 128; + if (MouseInfo.getNumberOfButtons() >= 6 && ((e.getModifiersEx() & e.getMaskForButton(6)) != 0)) + buttonMask |= 1024; //Forward - if (MouseInfo.getNumberOfButtons() >= 5 && e.getButton() == 7) - buttonMask |= 256; + if (MouseInfo.getNumberOfButtons() >= 7 && ((e.getModifiersEx() & e.getMaskForButton(7)) != 0)) + buttonMask |= 512; } if (e.getID() == MouseEvent.MOUSE_WHEEL) { diff --git a/unix/xserver/hw/vnc/vncInput.c b/unix/xserver/hw/vnc/vncInput.c index 0e1038658..1dbe4a3c0 100644 --- a/unix/xserver/hw/vnc/vncInput.c +++ b/unix/xserver/hw/vnc/vncInput.c @@ -50,7 +50,7 @@ extern const unsigned int code_map_qnum_to_xorgevdev_len; extern const unsigned short code_map_qnum_to_xorgkbd[]; extern const unsigned int code_map_qnum_to_xorgkbd_len; -#define BUTTONS 9 +#define BUTTONS 11 DeviceIntPtr vncKeyboardDev; DeviceIntPtr vncPointerDev; @@ -206,8 +206,11 @@ static int vncPointerProc(DeviceIntPtr pDevice, int onoff) btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); - btn_labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_BACK); - btn_labels[8] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_FORWARD); + btn_labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_SIDE); + btn_labels[8] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_EXTRA); + btn_labels[9] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_FORWARD); + btn_labels[10] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_BACK); + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index 818cea679..94cde1b50 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -606,10 +606,13 @@ int Viewport::handle(int event) if (Fl::event_button3()) buttonMask |= 4; - if(Fl::event_buttons()&FL_BUTTON(4)) - buttonMask |= 128; - if(Fl::event_buttons()&FL_BUTTON(5)) - buttonMask |= 256; + //Fl::event_button is only good for FL_PUSH and FL_RELEASE + if(event == FL_PUSH) { + if (Fl::event_button() == 8) //Mouse Back + buttonMask |= 1024; + if (Fl::event_button() == 9) //Mouse Forward + buttonMask |= 512; + } if (event == FL_MOUSEWHEEL) { wheelMask = 0;