]> source.dussan.org Git - tigervnc.git/commitdiff
Add Input.h and Input.cc and move all mouse input related code there.
authorAdam Tkac <atkac@redhat.com>
Fri, 28 Aug 2009 12:04:20 +0000 (12:04 +0000)
committerAdam Tkac <atkac@redhat.com>
Fri, 28 Aug 2009 12:04:20 +0000 (12:04 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3886 3789f03b-4d11-0410-bbf8-ca57d06f2519

unix/xserver/hw/vnc/Input.cc [new file with mode: 0644]
unix/xserver/hw/vnc/Input.h [new file with mode: 0644]
unix/xserver/hw/vnc/Makefile.am
unix/xserver/hw/vnc/XserverDesktop.cc
unix/xserver/hw/vnc/XserverDesktop.h

diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc
new file mode 100644 (file)
index 0000000..ca279f0
--- /dev/null
@@ -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 (file)
index 0000000..49cedf2
--- /dev/null
@@ -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
index a39a10d2235b70c074dc28571556de6a411fceb8..c2e78df79dbb41c6e44eec63b6ac2feb5388c7cb 100644 (file)
@@ -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) \
index 533f31bd2099fd43983bf2b923810d90e165a91d..58f70d97f23057950faab7b2d7fdabaa191deb12 100644 (file)
@@ -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;
-}
index 7729d3f2354535e3fde90920d840d43627079b2c..9f300f53fde3747d676e171bbb3b0dedfb6729e3 100644 (file)
@@ -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;