Index: unix/xserver/hw/vnc/Input.cc =================================================================== --- unix/xserver/hw/vnc/Input.cc (revision 0) +++ unix/xserver/hw/vnc/Input.cc (revision 3886) @@ -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 +#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<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; +} + Index: unix/xserver/hw/vnc/Input.h =================================================================== --- unix/xserver/hw/vnc/Input.h (revision 0) +++ unix/xserver/hw/vnc/Input.h (revision 3886) @@ -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 +#endif + +#include + +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 Index: unix/xserver/hw/vnc/Makefile.am =================================================================== --- unix/xserver/hw/vnc/Makefile.am (revision 3885) +++ unix/xserver/hw/vnc/Makefile.am (revision 3886) @@ -9,9 +9,11 @@ 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) \ Index: unix/xserver/hw/vnc/XserverDesktop.cc =================================================================== --- unix/xserver/hw/vnc/XserverDesktop.cc (revision 3885) +++ unix/xserver/hw/vnc/XserverDesktop.cc (revision 3886) @@ -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 @@ } static DeviceIntPtr vncKeyboardDevice = NULL; -static DeviceIntPtr vncPointerDevice = NULL; #if XORG == 15 static xEvent *eventq = NULL; #else @@ -85,7 +85,6 @@ #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 @@ listener(listener_), httpListener(httpListener_), cmap(0), deferredUpdateTimerSet(false), grabbing(false), ignoreHooks_(false), directFbptr(true), - oldButtonMask(0), queryConnectId(0) { format = pf; @@ -221,14 +219,7 @@ 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 @@ delete [] data; TimerFree(deferredUpdateTimer); TimerFree(dummyTimer); + delete pointerDevice; delete httpServer; delete server; } @@ -555,43 +547,9 @@ } } -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 @@ } } - positionCursor(); + pointerDevice->Sync(); } int timeout = server->checkTimeouts(); @@ -737,63 +695,8 @@ 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<event -#endif - ); - } - } - } - - cursorPos = pos; - oldButtonMask = buttonMask; + pointerDevice->Move(pos); + pointerDevice->ButtonAction(buttonMask); } void XserverDesktop::clientCutText(const char* str, int len) @@ -1481,36 +1384,3 @@ 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; -} Index: unix/xserver/hw/vnc/XserverDesktop.h =================================================================== --- unix/xserver/hw/vnc/XserverDesktop.h (revision 3885) +++ unix/xserver/hw/vnc/XserverDesktop.h (revision 3886) @@ -32,6 +32,7 @@ #include #include #include +#include "Input.h" extern "C" { #define class c_class @@ -68,7 +69,6 @@ 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 @@ pointer arg); void deferUpdate(); ScreenPtr pScreen; + PointerDevice *pointerDevice; OsTimerPtr deferredUpdateTimer, dummyTimer; rfb::VNCServerST* server; rfb::HTTPServer* httpServer; @@ -133,8 +134,6 @@ bool grabbing; bool ignoreHooks_; bool directFbptr; - int oldButtonMask; - rfb::Point cursorPos, oldCursorPos; void* queryConnectId; rfb::CharArray queryConnectAddress;