sharkcz / rpms / tigervnc

Forked from rpms/tigervnc 4 years ago
Clone
Blob Blame History Raw
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 <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;
+}
+
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 <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: 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<<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 @@
   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 <rfb/Configuration.h>
 #include <rfb/VNCServerST.h>
 #include <rdr/SubstitutingInStream.h>
+#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;