From a67ca002bb2231341618af19a063fc5365593356 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 11 Jul 2014 14:03:44 +0200 Subject: We need to set a label on all pointer buttons --- unix/xserver/hw/vnc/Input.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc index a6a51d7f..1474f93a 100644 --- a/unix/xserver/hw/vnc/Input.cc +++ b/unix/xserver/hw/vnc/Input.cc @@ -229,6 +229,8 @@ static int pointerProc(DeviceIntPtr pDevice, int onoff) btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); 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); axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); -- cgit v1.2.3 From 6a0edf58a8e2ac97957c6bbc33a8f7a471e97cd8 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 14 Jul 2014 13:20:24 +0200 Subject: Re-init VNC extension on server reset fc23895 blocked out a bit too much code when trying to make libvnc handle server resets. Even though configuration should only be handled once, the underlying VNC extension needs to be reinitilised as the X core has removed all extensions on reset. --- unix/xserver/hw/vnc/xf86vncModule.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/xserver/hw/vnc/xf86vncModule.cc b/unix/xserver/hw/vnc/xf86vncModule.cc index 58964ccf..bb666ef2 100644 --- a/unix/xserver/hw/vnc/xf86vncModule.cc +++ b/unix/xserver/hw/vnc/xf86vncModule.cc @@ -112,9 +112,9 @@ static void vncExtensionInitWithParams(INITARGS) i.param->setParam(val); } } - - vncExtensionInit(); } + + vncExtensionInit(); } } -- cgit v1.2.3 From 91313d8b659ec26c8b32c0b56fb878f2163a8317 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 14 Jul 2014 13:36:47 +0200 Subject: Let XserverDesktop handle syncing cursor position This makes InputDevice cleaner and just a glue layer for Xorg input devices. --- unix/xserver/hw/vnc/Input.cc | 12 ++++-------- unix/xserver/hw/vnc/Input.h | 18 +++++++++--------- unix/xserver/hw/vnc/XserverDesktop.cc | 6 +++++- unix/xserver/hw/vnc/XserverDesktop.h | 2 ++ 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc index 1474f93a..46b02fd1 100644 --- a/unix/xserver/hw/vnc/Input.cc +++ b/unix/xserver/hw/vnc/Input.cc @@ -116,8 +116,8 @@ static void enqueueEvents(DeviceIntPtr dev, int n) } #endif /* XORG < 111 */ -InputDevice::InputDevice(rfb::VNCServerST *_server) - : server(_server), initialized(false), oldButtonMask(0) +InputDevice::InputDevice() + : initialized(false), oldButtonMask(0) { int i; @@ -195,13 +195,9 @@ void InputDevice::PointerMove(const rfb::Point &pos) cursorPos = pos; } -void InputDevice::PointerSync(void) +const rfb::Point &InputDevice::getPointerPos(void) { - if (cursorPos.equals(oldCursorPos)) - return; - - oldCursorPos = cursorPos; - server->setCursorPos(cursorPos); + return cursorPos; } static int pointerProc(DeviceIntPtr pDevice, int onoff) diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h index e893049e..c996cb0b 100644 --- a/unix/xserver/hw/vnc/Input.h +++ b/unix/xserver/hw/vnc/Input.h @@ -29,10 +29,13 @@ #include -#include +#include +#include extern "C" { #include "input.h" +/* The Xorg headers define macros that wreak havoc with STL */ +#undef max }; #include "xorg-version.h" @@ -41,7 +44,7 @@ extern "C" { class InputDevice { public: /* Create new InputDevice instance */ - InputDevice(rfb::VNCServerST *_server); + InputDevice(); /* * Press or release buttons. Relationship between buttonMask and @@ -52,12 +55,10 @@ public: /* Move pointer to target location (point coords are absolute). */ void PointerMove(const rfb::Point &point); - /* - * Send pointer position to clients. If not called then Move() calls - * won't be visible to VNC clients. - */ - void PointerSync(void); + /* Get current known location of the pointer */ + const rfb::Point &getPointerPos(void); + /* Press or release one or more keys to get the given symbol */ void KeyboardPress(rdr::U32 keysym) { keyEvent(keysym, true); } void KeyboardRelease(rdr::U32 keysym) { keyEvent(keysym, false); } @@ -103,13 +104,12 @@ private: #endif private: - rfb::VNCServerST *server; bool initialized; DeviceIntPtr keyboardDev; DeviceIntPtr pointerDev; int oldButtonMask; - rfb::Point cursorPos, oldCursorPos; + rfb::Point cursorPos; KeySym pressedKeys[256]; }; diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index b0d4601e..cd76d068 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -689,7 +689,11 @@ void XserverDesktop::wakeupHandler(fd_set* fds, int nfds) } } - inputDevice->PointerSync(); + // We are responsible for propagating mouse movement between clients + if (!oldCursorPos.equals(inputDevice->getPointerPos())) { + oldCursorPos = inputDevice->getPointerPos(); + server->setCursorPos(oldCursorPos); + } } // Then let the timers do some processing. Rescheduling is done in diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index fb247b04..ca6e8af9 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -153,5 +153,7 @@ private: typedef std::map OutputIdMap; OutputIdMap outputIdMap; #endif + + rfb::Point oldCursorPos; }; #endif -- cgit v1.2.3 From 8c8f85034b15d7d2a1589378f9d0ee236a98a3c8 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 14 Jul 2014 13:39:57 +0200 Subject: Move all functions that InputDevice uses into the class --- unix/xserver/hw/vnc/Input.cc | 6 ++---- unix/xserver/hw/vnc/Input.h | 5 +++++ unix/xserver/hw/vnc/InputCore.cc | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc index 46b02fd1..5497d97e 100644 --- a/unix/xserver/hw/vnc/Input.cc +++ b/unix/xserver/hw/vnc/Input.cc @@ -200,7 +200,7 @@ const rfb::Point &InputDevice::getPointerPos(void) return cursorPos; } -static int pointerProc(DeviceIntPtr pDevice, int onoff) +int InputDevice::pointerProc(DeviceIntPtr pDevice, int onoff) { BYTE map[BUTTONS + 1]; DevicePtr pDev = (DevicePtr)pDevice; @@ -267,9 +267,7 @@ static void keyboardBell(int percent, DeviceIntPtr device, pointer ctrl, vncBell(); } -extern void GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap); - -static int keyboardProc(DeviceIntPtr pDevice, int onoff) +int InputDevice::keyboardProc(DeviceIntPtr pDevice, int onoff) { #if XORG < 17 KeySymsRec keySyms; diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h index c996cb0b..8a3dd4f2 100644 --- a/unix/xserver/hw/vnc/Input.h +++ b/unix/xserver/hw/vnc/Input.h @@ -97,10 +97,15 @@ private: KeyCode addKeysym(KeySym keysym, unsigned state); private: + static int pointerProc(DeviceIntPtr pDevice, int onoff); + static int keyboardProc(DeviceIntPtr pDevice, int onoff); + #if XORG >= 17 static void vncXkbProcessDeviceEvent(int screenNum, InternalEvent *event, DeviceIntPtr dev); +#else + static void GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap); #endif private: diff --git a/unix/xserver/hw/vnc/InputCore.cc b/unix/xserver/hw/vnc/InputCore.cc index a880ca07..b565c734 100644 --- a/unix/xserver/hw/vnc/InputCore.cc +++ b/unix/xserver/hw/vnc/InputCore.cc @@ -174,7 +174,7 @@ KeySym keyboardMap[MAP_LEN * KEYSYMS_PER_KEY] = { XK_Menu, NoSymbol, }; -void GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap) +void InputDevice::GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap) { int i; -- cgit v1.2.3 From de0b3532320e088440bd7607f7d5d7e8fc720d94 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 14 Jul 2014 13:41:36 +0200 Subject: Make InputDevice into a singleton Xorg input devices are global so it doesn't make sense that we have one InputDevice object per XserverDesktop. --- unix/xserver/hw/vnc/Input.cc | 7 ++++++- unix/xserver/hw/vnc/Input.h | 32 +++++++++++++++++++++----------- unix/xserver/hw/vnc/XserverDesktop.cc | 17 +++++++---------- unix/xserver/hw/vnc/XserverDesktop.h | 1 - 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc index 5497d97e..1d875746 100644 --- a/unix/xserver/hw/vnc/Input.cc +++ b/unix/xserver/hw/vnc/Input.cc @@ -68,6 +68,9 @@ rfb::BoolParameter avoidShiftNumLock("AvoidShiftNumLock", "Avoid fake Shift pres #define BUTTONS 7 +class InputDevice *vncInputDevice; +InputDevice InputDevice::singleton; + /* Event queue is shared between all devices. */ #if XORG == 15 static xEvent *eventq = NULL; @@ -117,10 +120,12 @@ static void enqueueEvents(DeviceIntPtr dev, int n) #endif /* XORG < 111 */ InputDevice::InputDevice() - : initialized(false), oldButtonMask(0) + : oldButtonMask(0) { int i; + vncInputDevice = this; + #if XORG < 111 initEventq(); #endif diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h index 8a3dd4f2..029b80d1 100644 --- a/unix/xserver/hw/vnc/Input.h +++ b/unix/xserver/hw/vnc/Input.h @@ -40,12 +40,16 @@ extern "C" { #include "xorg-version.h" -/* Represents input device (keyboard + pointer) */ +/* + * Represents input device (keyboard + pointer) + * + * Is a singleton as input devices are global in the X server so + * we do not have one per desktop (i.e. per screen). + */ +extern class InputDevice *vncInputDevice; + class InputDevice { public: - /* Create new InputDevice instance */ - InputDevice(); - /* * Press or release buttons. Relationship between buttonMask and * buttons is specified in RFB protocol. @@ -63,17 +67,20 @@ public: void KeyboardRelease(rdr::U32 keysym) { keyEvent(keysym, false); } /* - * Init input device. This cannot be done in the constructor - * because constructor is called during X server extensions - * initialization. Devices must be initialized after core - * pointer/keyboard initialization which is actually after extesions - * initialization. Check InitExtensions(), InitCoreDevices() and - * InitInput() calls in dix/main.c. Instead it is called from - * XserverDesktop at an appropriate time. + * Init input device. + * This has to be called after core pointer/keyboard + * initialization which unfortunately is after extesions + * initialization (which means we cannot call it in + * vncExtensionInit(). Check InitExtensions(), + * InitCoreDevices() and InitInput() calls in dix/main.c. + * Instead we call it from XserverDesktop at an appropriate + * time. */ void InitInputDevice(void); private: + InputDevice(); + void keyEvent(rdr::U32 keysym, bool down); /* Backend dependent functions below here */ @@ -117,6 +124,9 @@ private: rfb::Point cursorPos; KeySym pressedKeys[256]; + +private: + static InputDevice singleton; }; #endif diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index cd76d068..8f426cce 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -158,15 +158,12 @@ XserverDesktop::XserverDesktop(ScreenPtr pScreen_, if (httpListener) httpServer = new FileHTTPServer(this); - - inputDevice = new InputDevice(server); } XserverDesktop::~XserverDesktop() { if (!directFbptr) delete [] data; - delete inputDevice; delete httpServer; delete server; } @@ -581,7 +578,7 @@ void XserverDesktop::blockHandler(fd_set* fds, OSTimePtr timeout) // so we abuse the fact that this routine will be called first thing // once the dix is done initialising. // [1] Technically Xvnc has InitInput(), but libvnc.so has nothing. - inputDevice->InitInputDevice(); + vncInputDevice->InitInputDevice(); try { int nextTimeout; @@ -690,8 +687,8 @@ void XserverDesktop::wakeupHandler(fd_set* fds, int nfds) } // We are responsible for propagating mouse movement between clients - if (!oldCursorPos.equals(inputDevice->getPointerPos())) { - oldCursorPos = inputDevice->getPointerPos(); + if (!oldCursorPos.equals(vncInputDevice->getPointerPos())) { + oldCursorPos = vncInputDevice->getPointerPos(); server->setCursorPos(oldCursorPos); } } @@ -820,8 +817,8 @@ void XserverDesktop::approveConnection(void* opaqueId, bool accept, void XserverDesktop::pointerEvent(const Point& pos, int buttonMask) { - inputDevice->PointerMove(pos); - inputDevice->PointerButtonAction(buttonMask); + vncInputDevice->PointerMove(pos); + vncInputDevice->PointerButtonAction(buttonMask); } void XserverDesktop::clientCutText(const char* str, int len) @@ -1138,7 +1135,7 @@ void XserverDesktop::lookup(int index, int* r, int* g, int* b) void XserverDesktop::keyEvent(rdr::U32 keysym, bool down) { if (down) - inputDevice->KeyboardPress(keysym); + vncInputDevice->KeyboardPress(keysym); else - inputDevice->KeyboardRelease(keysym); + vncInputDevice->KeyboardRelease(keysym); } diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index ca6e8af9..20c89dc5 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -133,7 +133,6 @@ private: #endif ScreenPtr pScreen; - InputDevice *inputDevice; rfb::VNCServerST* server; rfb::HTTPServer* httpServer; network::TcpListener* listener; -- cgit v1.2.3 From ac38a07d36f18f722295e26ff03391657e08a89c Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 14 Jul 2014 13:44:46 +0200 Subject: Remove private storage from InputDevice We don't need this anymore as we now only have a single InputDevice object and can easily refer to it directly. --- unix/xserver/hw/vnc/InputXKB.cc | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/unix/xserver/hw/vnc/InputXKB.cc b/unix/xserver/hw/vnc/InputXKB.cc index ed93afcc..92288aa4 100644 --- a/unix/xserver/hw/vnc/InputXKB.cc +++ b/unix/xserver/hw/vnc/InputXKB.cc @@ -42,18 +42,6 @@ extern "C" { #undef class } -#if XORG < 19 -static int vncXkbScreenPrivateKeyIndex; -static DevPrivateKey vncXkbScreenPrivateKey = &vncXkbScreenPrivateKeyIndex; -#else -static DevPrivateKeyRec vncXkbPrivateKeyRec; -#define vncXkbScreenPrivateKey (&vncXkbPrivateKeyRec) -#endif - -#define vncXkbScreenPrivate(pScreen) \ - (*(InputDevice**) dixLookupPrivate(&(pScreen)->devPrivates, \ - vncXkbScreenPrivateKey)) - #ifndef KEYBOARD_OR_FLOAT #define KEYBOARD_OR_FLOAT MASTER_KEYBOARD #endif @@ -209,18 +197,6 @@ static unsigned XkbKeyEffectiveGroup(XkbDescPtr xkb, KeyCode key, unsigned int m void InputDevice::PrepareInputDevices(void) { -#if XORG < 19 - if (!dixRequestPrivate(vncXkbScreenPrivateKey, sizeof(InputDevice*))) - FatalError("Failed to register TigerVNC XKB screen key\n"); -#else - if (!dixRegisterPrivateKey(vncXkbScreenPrivateKey, PRIVATE_SCREEN, - sizeof(InputDevice*))) - FatalError("Failed to register TigerVNC XKB screen key\n"); -#endif - - for (int scr = 0; scr < screenInfo.numScreens; scr++) - vncXkbScreenPrivate(screenInfo.screens[scr]) = this; - /* * Not ideal since these callbacks do not stack, but it's the only * decent way we can reliably catch events for both the slave and @@ -636,10 +612,9 @@ void InputDevice::vncXkbProcessDeviceEvent(int screenNum, InternalEvent *event, DeviceIntPtr dev) { - InputDevice *self = vncXkbScreenPrivate(screenInfo.screens[screenNum]); unsigned int backupctrls; - if (event->device_event.sourceid == self->keyboardDev->id) { + if (event->device_event.sourceid == singleton.keyboardDev->id) { XkbControlsPtr ctrls; /* @@ -661,7 +636,7 @@ void InputDevice::vncXkbProcessDeviceEvent(int screenNum, dev->c_public.processInputProc(event, dev); - if (event->device_event.sourceid == self->keyboardDev->id) { + if (event->device_event.sourceid == singleton.keyboardDev->id) { XkbControlsPtr ctrls; ctrls = dev->key->xkbInfo->desc->ctrls; -- cgit v1.2.3 From 5c6e64113d8ed7877d777fe6509c4566d48f2656 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 14 Jul 2014 13:46:48 +0200 Subject: Handle closing of input devices The core can decide to close an input device (e.g. during a server reset). Make sure we respect this by forgetting about the device and recreating it again later. --- unix/xserver/hw/vnc/Input.cc | 10 +++++----- unix/xserver/hw/vnc/Input.h | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc index 1d875746..28b84c71 100644 --- a/unix/xserver/hw/vnc/Input.cc +++ b/unix/xserver/hw/vnc/Input.cc @@ -256,10 +256,9 @@ int InputDevice::pointerProc(DeviceIntPtr pDevice, int onoff) case DEVICE_OFF: pDev->on = FALSE; break; -#if 0 case DEVICE_CLOSE: + singleton.pointerDev = NULL; break; -#endif } return Success; @@ -299,6 +298,9 @@ int InputDevice::keyboardProc(DeviceIntPtr pDevice, int onoff) case DEVICE_OFF: pDev->on = FALSE; break; + case DEVICE_CLOSE: + singleton.keyboardDev = NULL; + break; } return Success; @@ -306,11 +308,9 @@ int InputDevice::keyboardProc(DeviceIntPtr pDevice, int onoff) void InputDevice::InitInputDevice(void) { - if (initialized) + if ((pointerDev != NULL) || (keyboardDev != NULL)) return; - initialized = true; - #if XORG < 17 pointerDev = AddInputDevice( #if XORG >= 16 diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h index 029b80d1..90b392cf 100644 --- a/unix/xserver/hw/vnc/Input.h +++ b/unix/xserver/hw/vnc/Input.h @@ -116,7 +116,6 @@ private: #endif private: - bool initialized; DeviceIntPtr keyboardDev; DeviceIntPtr pointerDev; -- cgit v1.2.3