diff options
author | Adam Tkac <atkac@redhat.com> | 2009-08-28 12:04:20 +0000 |
---|---|---|
committer | Adam Tkac <atkac@redhat.com> | 2009-08-28 12:04:20 +0000 |
commit | 62de8d75d2611924d2ba04406464f31371b93d97 (patch) | |
tree | 6d86b358de26a4a3d1c9dd6a5e837d2daa258fb5 | |
parent | a7c223a2dc036f2ecb2c2045dd96237ca306a7a2 (diff) | |
download | tigervnc-62de8d75d2611924d2ba04406464f31371b93d97.tar.gz tigervnc-62de8d75d2611924d2ba04406464f31371b93d97.zip |
Add Input.h and Input.cc and move all mouse input related code there.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3886 3789f03b-4d11-0410-bbf8-ca57d06f2519
-rw-r--r-- | unix/xserver/hw/vnc/Input.cc | 167 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/Input.h | 61 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/Makefile.am | 6 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.cc | 142 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.h | 5 |
5 files changed, 240 insertions, 141 deletions
diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc new file mode 100644 index 00000000..ca279f0e --- /dev/null +++ b/unix/xserver/hw/vnc/Input.cc @@ -0,0 +1,167 @@ +/* Copyright (C) 2009 TightVNC Team + * Copyright (C) 2009 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "Input.h" +#include "xorg-version.h" + +extern "C" { +#include "mi.h" +} + +/* Event queue is shared between all devices. */ +#if XORG == 15 +static xEvent *eventq = NULL; +#else +static EventList *eventq = NULL; +#endif + +static void initEventq(void) +{ + /* eventq is never free()-ed because it exists during server life. */ + if (eventq == NULL) { +#if XORG == 15 + eventq = (xEvent *)xcalloc(sizeof(xEvent), + GetMaximumEventsNum()); + if (!eventq) + FatalError("Couldn't allocate eventq\n"); +#else + GetEventList(&eventq); +#endif + } +} + +static void enqueueEvents(DeviceIntPtr dev, int n) +{ + int i; + + for (i = 0; i < n; i++) { + /* + * Passing arguments in global variable eventq is probably not + * good programming practise but in this case it is safe and + * clear. + */ + mieqEnqueue(dev, +#if XORG == 15 + eventq + i +#else + (eventq + i)->event +#endif + ); + } +} + +/* Pointer device pre-declarations */ +#define BUTTONS 5 +static int pointerProc(DeviceIntPtr pDevice, int onoff); + +/* Pointer device methods */ + +PointerDevice::PointerDevice(rfb::VNCServerST *_server) + : server(_server), oldButtonMask(0) +{ + dev = AddInputDevice( +#if XORG >= 16 + serverClient, +#endif + pointerProc, TRUE); + RegisterPointerDevice(dev); + initEventq(); +} + +void PointerDevice::ButtonAction(int buttonMask) +{ + int i, n; + + for (i = 0; i < BUTTONS; i++) { + if ((buttonMask ^ oldButtonMask) & (1 << i)) { + int action = (buttonMask & (1<<i)) ? + ButtonPress : ButtonRelease; + n = GetPointerEvents(eventq, dev, action, i + 1, + POINTER_RELATIVE, 0, 0, NULL); + enqueueEvents(dev, n); + + } + } + + oldButtonMask = buttonMask; +} + +void PointerDevice::Move(const rfb::Point &pos) +{ + int n, valuators[2]; + + if (pos.equals(cursorPos)) + return; + + valuators[0] = pos.x; + valuators[1] = pos.y; + n = GetPointerEvents(eventq, dev, MotionNotify, 0, POINTER_ABSOLUTE, 0, + 2, valuators); + enqueueEvents(dev, n); + + cursorPos = pos; +} + +void PointerDevice::Sync(void) +{ + if (cursorPos.equals(oldCursorPos)) + return; + + oldCursorPos = cursorPos; + server->setCursorPos(cursorPos); + server->tryUpdate(); +} + +static int pointerProc(DeviceIntPtr pDevice, int onoff) +{ + BYTE map[BUTTONS + 1]; + DevicePtr pDev = (DevicePtr)pDevice; + int i; + + switch (onoff) { + case DEVICE_INIT: + for (i = 0; i < BUTTONS + 1; i++) + map[i] = i; + + InitPointerDeviceStruct(pDev, map, BUTTONS, +#if XORG == 15 + GetMotionHistory, +#endif + (PtrCtrlProcPtr)NoopDDA, + GetMotionHistorySize(), 2); + break; + case DEVICE_ON: + pDev->on = TRUE; + break; + case DEVICE_OFF: + pDev->on = FALSE; + break; +#if 0 + case DEVICE_CLOSE: + break; +#endif + } + + return Success; +} + diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h new file mode 100644 index 00000000..49cedf29 --- /dev/null +++ b/unix/xserver/hw/vnc/Input.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2009 TightVNC Team + * Copyright (C) 2009 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* Make sure macro doesn't conflict with macro in include/input.h. */ +#ifndef INPUT_H_ +#define INPUT_H_ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <rfb/VNCServerST.h> + +extern "C" { +#include "input.h" +}; + +/* Represents pointer device. */ +class PointerDevice { +public: + /* Create new PointerDevice instance. */ + PointerDevice(rfb::VNCServerST *_server); + + /* + * Press or release buttons. Relationship between buttonMask and + * buttons is specified in RFB protocol. + */ + void ButtonAction(int buttonMask); + + /* Move pointer to target location (point coords are absolute). */ + void Move(const rfb::Point &point); + + /* + * Send pointer position to clients. If not called then Move() calls + * won't be visible to clients. + */ + void Sync(void); +private: + rfb::VNCServerST *server; + DeviceIntPtr dev; + int oldButtonMask; + rfb::Point cursorPos, oldCursorPos; +}; + +#endif diff --git a/unix/xserver/hw/vnc/Makefile.am b/unix/xserver/hw/vnc/Makefile.am index a39a10d2..c2e78df7 100644 --- a/unix/xserver/hw/vnc/Makefile.am +++ b/unix/xserver/hw/vnc/Makefile.am @@ -9,9 +9,11 @@ COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(XREGION_LIB) noinst_LTLIBRARIES = libvnccommon.la -HDRS = RegionHelper.h vncExtInit.h vncHooks.h XserverDesktop.h xorg-version.h +HDRS = RegionHelper.h vncExtInit.h vncHooks.h XserverDesktop.h xorg-version.h \ + Input.h -libvnccommon_la_SOURCES = $(HDRS) vncExtInit.cc vncHooks.cc XserverDesktop.cc +libvnccommon_la_SOURCES = $(HDRS) vncExtInit.cc vncHooks.cc XserverDesktop.cc \ + Input.cc libvnccommon_la_CPPFLAGS = -DVENDOR_RELEASE="$(VENDOR_RELEASE)" \ -DVENDOR_STRING="\"$(VENDOR_STRING)\"" -I$(LIB_DIR) \ diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 533f31bd..58f70d97 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -42,6 +42,7 @@ #include "XserverDesktop.h" #include "vncExtInit.h" #include "xorg-version.h" +#include "Input.h" extern "C" { #define public c_public @@ -77,7 +78,6 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master); } static DeviceIntPtr vncKeyboardDevice = NULL; -static DeviceIntPtr vncPointerDevice = NULL; #if XORG == 15 static xEvent *eventq = NULL; #else @@ -85,7 +85,6 @@ static EventList *eventq = NULL; #endif static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff); -static int vfbMouseProc(DeviceIntPtr pDevice, int onoff); using namespace rfb; using namespace network; @@ -180,7 +179,6 @@ XserverDesktop::XserverDesktop(ScreenPtr pScreen_, listener(listener_), httpListener(httpListener_), cmap(0), deferredUpdateTimerSet(false), grabbing(false), ignoreHooks_(false), directFbptr(true), - oldButtonMask(0), queryConnectId(0) { format = pf; @@ -221,14 +219,7 @@ XserverDesktop::XserverDesktop(ScreenPtr pScreen_, RegisterKeyboardDevice(vncKeyboardDevice); } - if (vncPointerDevice == NULL) { - vncPointerDevice = AddInputDevice( -#if XORG >= 16 - serverClient, -#endif - vfbMouseProc, TRUE); - RegisterPointerDevice(vncPointerDevice); - } + pointerDevice = new PointerDevice(server); } XserverDesktop::~XserverDesktop() @@ -237,6 +228,7 @@ XserverDesktop::~XserverDesktop() delete [] data; TimerFree(deferredUpdateTimer); TimerFree(dummyTimer); + delete pointerDevice; delete httpServer; delete server; } @@ -555,43 +547,9 @@ void XserverDesktop::add_copied(RegionPtr dst, int dx, int dy) } } -void XserverDesktop::positionCursor() -{ - if (!cursorPos.equals(oldCursorPos)) { - oldCursorPos = cursorPos; - (*pScreen->SetCursorPosition) ( -#if XORG >= 16 - vncPointerDevice, -#endif - pScreen, cursorPos.x, cursorPos.y, FALSE); - server->setCursorPos(cursorPos); - server->tryUpdate(); - } -} - void XserverDesktop::blockHandler(fd_set* fds) { try { -#if XORG == 15 - ScreenPtr screenWithCursor = GetCurrentRootWindow()->drawable.pScreen; -#else - ScreenPtr screenWithCursor = - GetCurrentRootWindow(vncPointerDevice)->drawable.pScreen; -#endif - if (screenWithCursor == pScreen) { - int x, y; - GetSpritePosition( -#if XORG >= 16 - vncPointerDevice, -#endif - &x, &y); - if (x != cursorPos.x || y != cursorPos.y) { - cursorPos = oldCursorPos = Point(x, y); - server->setCursorPos(cursorPos); - server->tryUpdate(); - } - } - if (listener) FD_SET(listener->getFd(), fds); if (httpListener) @@ -678,7 +636,7 @@ void XserverDesktop::wakeupHandler(fd_set* fds, int nfds) } } - positionCursor(); + pointerDevice->Sync(); } int timeout = server->checkTimeouts(); @@ -737,63 +695,8 @@ void XserverDesktop::approveConnection(void* opaqueId, bool accept, void XserverDesktop::pointerEvent(const Point& pos, int buttonMask) { - int i, j, n, valuators[2]; - - // SetCursorPosition seems to be very expensive (at least on XFree86 3.3.6 - // for S3), so we delay calling it until positionCursor() is called at the - // end of processing a load of RFB. - //(*pScreen->SetCursorPosition) (pScreen, pos.x, pos.y, FALSE); - - NewCurrentScreen( -#if XORG >= 16 - vncPointerDevice, -#endif - pScreen, pos.x, pos.y); - - if (!pos.equals(cursorPos)) { - valuators[0] = pos.x; - valuators[1] = pos.y; - -#if XORG >= 16 - GetEventList(&eventq); -#endif - n = GetPointerEvents (eventq, vncPointerDevice, MotionNotify, 0, - POINTER_ABSOLUTE, 0, 2, valuators); - - for (i = 0; i < n; i++) { - mieqEnqueue (vncPointerDevice, -#if XORG == 15 - eventq + i -#else - (eventq + i)->event -#endif - ); - } - } - - for (i = 0; i < 5; i++) { - if ((buttonMask ^ oldButtonMask) & (1<<i)) { - // Do not use the pointer mapping. Treat VNC buttons as logical - // buttons. - n = GetPointerEvents (eventq, vncPointerDevice, - (buttonMask & (1<<i)) ? - ButtonPress : ButtonRelease, - i + 1, POINTER_RELATIVE, 0, 0, NULL); - - for (j = 0; j < n; j++) { - mieqEnqueue (vncPointerDevice, -#if XORG == 15 - eventq + j -#else - (eventq + j)->event -#endif - ); - } - } - } - - cursorPos = pos; - oldButtonMask = buttonMask; + pointerDevice->Move(pos); + pointerDevice->ButtonAction(buttonMask); } void XserverDesktop::clientCutText(const char* str, int len) @@ -1481,36 +1384,3 @@ static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff) return Success; } -static int vfbMouseProc(DeviceIntPtr pDevice, int onoff) -{ - BYTE map[6]; - DevicePtr pDev = (DevicePtr)pDevice; - - switch (onoff) - { - case DEVICE_INIT: - map[1] = 1; - map[2] = 2; - map[3] = 3; - map[4] = 4; - map[5] = 5; - InitPointerDeviceStruct(pDev, map, 5, -#if XORG == 15 - GetMotionHistory, -#endif - (PtrCtrlProcPtr)NoopDDA, GetMotionHistorySize(), 2); - break; - - case DEVICE_ON: - pDev->on = TRUE; - break; - - case DEVICE_OFF: - pDev->on = FALSE; - break; - - case DEVICE_CLOSE: - break; - } - return Success; -} diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index 7729d3f2..9f300f53 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -32,6 +32,7 @@ #include <rfb/Configuration.h> #include <rfb/VNCServerST.h> #include <rdr/SubstitutingInStream.h> +#include "Input.h" extern "C" { #define class c_class @@ -68,7 +69,6 @@ public: void setCursor(CursorPtr cursor); void add_changed(RegionPtr reg); void add_copied(RegionPtr dst, int dx, int dy); - void positionCursor(); void ignoreHooks(bool b) { ignoreHooks_ = b; } void blockHandler(fd_set* fds); void wakeupHandler(fd_set* fds, int nfds); @@ -122,6 +122,7 @@ private: pointer arg); void deferUpdate(); ScreenPtr pScreen; + PointerDevice *pointerDevice; OsTimerPtr deferredUpdateTimer, dummyTimer; rfb::VNCServerST* server; rfb::HTTPServer* httpServer; @@ -133,8 +134,6 @@ private: bool grabbing; bool ignoreHooks_; bool directFbptr; - int oldButtonMask; - rfb::Point cursorPos, oldCursorPos; void* queryConnectId; rfb::CharArray queryConnectAddress; |