diff --git a/common/rfb/InputHandler.h b/common/rfb/InputHandler.h index e16a810..c804832 100644 --- a/common/rfb/InputHandler.h +++ b/common/rfb/InputHandler.h @@ -36,6 +36,7 @@ namespace rfb { rdr::U32 __unused_attr keycode, bool __unused_attr down) { } virtual void pointerEvent(const Point& __unused_attr pos, + const Point& __unused_attr abspos, int __unused_attr buttonMask, const bool __unused_attr skipClick, const bool __unused_attr skipRelease, diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx index fc01884..9bfdaa2 100644 --- a/common/rfb/SMsgReader.cxx +++ b/common/rfb/SMsgReader.cxx @@ -226,7 +226,8 @@ void SMsgReader::readPointerEvent() int y = is->readU16(); int scrollX = is->readS16(); int scrollY = is->readS16(); - handler->pointerEvent(Point(x, y), mask, false, false, scrollX, scrollY); + + handler->pointerEvent(Point(x, y), Point(0, 0), mask, false, false, scrollX, scrollY); } diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index c6affa5..1738330 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -712,7 +712,7 @@ void VNCSConnectionST::setPixelFormat(const PixelFormat& pf) setCursor(); } -void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY) +void VNCSConnectionST::pointerEvent(const Point& pos, const Point& abspos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY) { pointerEventTime = lastEventTime = time(0); server->lastUserInputTime = lastEventTime; @@ -725,7 +725,45 @@ void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool } if (!rfb::Server::acceptPointerEvents) return; if (!server->pointerClient || server->pointerClient == this) { - pointerEventPos = pos; + Point newpos = pos; + if (pos.x & 0x4000) { + newpos.x &= ~0x4000; + newpos.y &= ~0x4000; + + if (newpos.x & 0x8000) { + newpos.x &= ~0x8000; + newpos.x = -newpos.x; + } + if (newpos.y & 0x8000) { + newpos.y &= ~0x8000; + newpos.y = -newpos.y; + } + + if (newpos.x < 0) { + if (pointerEventPos.x + newpos.x >= 0) + pointerEventPos.x += newpos.x; + else + pointerEventPos.x = 0; + } else { + pointerEventPos.x += newpos.x; + if (pointerEventPos.x >= cp.width) + pointerEventPos.x = cp.width; + } + + if (newpos.y < 0) { + if (pointerEventPos.y + newpos.y >= 0) + pointerEventPos.y += newpos.y; + else + pointerEventPos.y = 0; + } else { + pointerEventPos.y += newpos.y; + if (pointerEventPos.y >= cp.height) + pointerEventPos.y = cp.height; + } + } else { + pointerEventPos = pos; + } + if (buttonMask) server->pointerClient = this; else @@ -746,7 +784,7 @@ void VNCSConnectionST::pointerEvent(const Point& pos, int buttonMask, const bool } } - server->desktop->pointerEvent(pointerEventPos, buttonMask, skipclick, skiprelease, scrollX, scrollY); + server->desktop->pointerEvent(newpos, pointerEventPos, buttonMask, skipclick, skiprelease, scrollX, scrollY); } } diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index e088c10..d60155b 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -207,7 +207,7 @@ namespace rfb { virtual void queryConnection(const char* userName); virtual void clientInit(bool shared); virtual void setPixelFormat(const PixelFormat& pf); - virtual void pointerEvent(const Point& pos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY); + virtual void pointerEvent(const Point& pos, const Point& abspos,int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY); virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); virtual void framebufferUpdateRequest(const Rect& r, bool incremental); virtual void setDesktopSize(int fb_width, int fb_height, diff --git a/kasmweb b/kasmweb index 6c708d8..41e9ae9 160000 --- a/kasmweb +++ b/kasmweb @@ -1 +1 @@ -Subproject commit 6c708d8254103594b0435663eb73f3b0dba2b2e3 +Subproject commit 41e9ae92c137ce07559c94a5abcf5cf29ef15ca6 diff --git a/unix/xserver/hw/vnc/Input.c b/unix/xserver/hw/vnc/Input.c index d85f4dd..3042730 100644 --- a/unix/xserver/hw/vnc/Input.c +++ b/unix/xserver/hw/vnc/Input.c @@ -239,6 +239,40 @@ void vncPointerMove(int x, int y) cursorPosY = y; } +void vncPointerMoveRelative(int x, int y, int absx, int absy) +{ + int valuators[2]; +#if XORG < 111 + int n; +#endif +#if XORG >= 110 + ValuatorMask mask; +#endif + +// if (cursorPosX == absx && cursorPosY == absy) +// return; + + valuators[0] = x; + valuators[1] = y; +#if XORG < 110 + n = GetPointerEvents(eventq, vncPointerDev, MotionNotify, 0, + POINTER_RELATIVE, 0, 2, valuators); + enqueueEvents(vncPointerDev, n); +#elif XORG < 111 + valuator_mask_set_range(&mask, 0, 2, valuators); + n = GetPointerEvents(eventq, vncPointerDev, MotionNotify, 0, + POINTER_RELATIVE, &mask); + enqueueEvents(vncPointerDev, n); +#else + valuator_mask_set_range(&mask, 0, 2, valuators); + QueuePointerEvents(vncPointerDev, MotionNotify, 0, + POINTER_RELATIVE, &mask); +#endif + + cursorPosX = absx; + cursorPosY = absy; +} + void vncScroll(int x, int y) { ValuatorMask mask; valuator_mask_zero(&mask); diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h index 8041224..066bcbb 100644 --- a/unix/xserver/hw/vnc/Input.h +++ b/unix/xserver/hw/vnc/Input.h @@ -36,6 +36,8 @@ void vncInitInputDevice(bool freeKeyMappings); void vncPointerButtonAction(int buttonMask, const unsigned char skipclick, const unsigned char skiprelease); void vncPointerMove(int x, int y); +void vncPointerMoveRelative(int x, int y, int absx, int absy); + void vncScroll(int x, int y); void vncGetPointerPos(int *x, int *y); diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 111cf26..4c08fec 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -461,12 +461,17 @@ void XserverDesktop::approveConnection(uint32_t opaqueId, bool accept, // // SDesktop callbacks - -void XserverDesktop::pointerEvent(const Point& pos, int buttonMask, +void XserverDesktop::pointerEvent(const Point& pos, const Point& abspos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX, int scrollY) { if (scrollX == 0 && scrollY == 0) { - vncPointerMove(pos.x + vncGetScreenX(screenIndex), pos.y + vncGetScreenY(screenIndex)); + if (pos.equals(abspos)) { + vncPointerMove(pos.x + vncGetScreenX(screenIndex), pos.y + vncGetScreenY(screenIndex)); + } else { + vncPointerMoveRelative(pos.x, pos.y, + abspos.x + vncGetScreenX(screenIndex), + abspos.y + vncGetScreenY(screenIndex)); + } vncPointerButtonAction(buttonMask, skipClick, skipRelease); } else { vncScroll(scrollX, scrollY); diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index fb9b365..32a204b 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -93,7 +93,7 @@ public: const char* rejectMsg=0); // rfb::SDesktop callbacks - virtual void pointerEvent(const rfb::Point& pos, int buttonMask, + virtual void pointerEvent(const rfb::Point& pos, const rfb::Point& abspos, int buttonMask, const bool skipClick, const bool skipRelease, int scrollX = 0, int scrollY = 0); virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down); virtual unsigned int setScreenLayout(int fb_width, int fb_height,