rpms/tigervnc/F-12 tigervnc10-noexec.patch, NONE, 1.1 tigervnc10-r3925-revert.patch, NONE, 1.1 tigervnc11-r3883.patch, NONE, 1.1 tigervnc11-r3884.patch, NONE, 1.1 tigervnc11-r3885.patch, NONE, 1.1 tigervnc11-r3886.patch, NONE, 1.1 tigervnc11-r3887.patch, NONE, 1.1 tigervnc11-r3924-rh541559.patch, NONE, 1.1 tigervnc11-r3926.patch, NONE, 1.1 tigervnc11-r3927.patch, NONE, 1.1 tigervnc11-r3932.patch, NONE, 1.1 tigervnc11-r4007.patch, NONE, 1.1 tigervnc11-r4008.patch, NONE, 1.1 tigervnc11-r4024.patch, NONE, 1.1 tigervnc11-r4025.patch, NONE, 1.1 .cvsignore, 1.9, 1.10 sources, 1.9, 1.10 tigervnc-cookie.patch, 1.1, 1.2 tigervnc.spec, 1.22, 1.23 tigervnc10-compat.patch, 1.1, NONE tigervnc10-rh510185.patch, 1.1, NONE tigervnc10-rh516274.patch, 1.1, NONE tigervnc10-rh524340.patch, 1.1, NONE

Adam Tkac atkac at fedoraproject.org
Wed Apr 14 11:39:59 UTC 2010


Author: atkac

Update of /cvs/pkgs/rpms/tigervnc/F-12
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv10046

Modified Files:
	.cvsignore sources tigervnc-cookie.patch tigervnc.spec 
Added Files:
	tigervnc10-noexec.patch tigervnc10-r3925-revert.patch 
	tigervnc11-r3883.patch tigervnc11-r3884.patch 
	tigervnc11-r3885.patch tigervnc11-r3886.patch 
	tigervnc11-r3887.patch tigervnc11-r3924-rh541559.patch 
	tigervnc11-r3926.patch tigervnc11-r3927.patch 
	tigervnc11-r3932.patch tigervnc11-r4007.patch 
	tigervnc11-r4008.patch tigervnc11-r4024.patch 
	tigervnc11-r4025.patch 
Removed Files:
	tigervnc10-compat.patch tigervnc10-rh510185.patch 
	tigervnc10-rh516274.patch tigervnc10-rh524340.patch 
Log Message:
- update to 1.0.1 bugfix release
- patches merged
  - tigervnc10-rh510185.patch
  - tigervnc10-rh524340.patch
  - tigervnc10-compat.patch
- backport X.Org 1.7.X support from trunk (r3883, r3884, r3885, r3886,
  r3887, r3926, r3927, r3932, r4024, r4025)
  - tigervnc10-rh516274.patch is no longer needed
- modifiers might be stuck inside Xvnc (r3924, #541559)
- mark stack as non executable in JPEG code
- backport French translation (r4007, r4008)


tigervnc10-noexec.patch:
 jsimdext.inc |    3 +++
 1 file changed, 3 insertions(+)

--- NEW FILE tigervnc10-noexec.patch ---
diff -up tigervnc-1.0.1/common/jpeg/simd/jsimdext.inc.r3956 tigervnc-1.0.1/common/jpeg/simd/jsimdext.inc
--- tigervnc-1.0.1/common/jpeg/simd/jsimdext.inc.r3956	2009-03-16 14:34:18.000000000 +0100
+++ tigervnc-1.0.1/common/jpeg/simd/jsimdext.inc	2010-04-13 15:15:45.517416147 +0200
@@ -53,6 +53,9 @@
 ; * *BSD family Unix using elf format
 ; * Unix System V, including Solaris x86, UnixWare and SCO Unix
 
+; mark stack as non-executable
+section .note.GNU-stack noalloc noexec nowrite progbits
+
 ; -- segment definition --
 ;
 %define SEG_TEXT    .text   progbits alloc exec   nowrite align=16

tigervnc10-r3925-revert.patch:
 XserverDesktop.cc |   17 -----------------
 1 file changed, 17 deletions(-)

--- NEW FILE tigervnc10-r3925-revert.patch ---
Index: unix/xserver/hw/vnc/XserverDesktop.cc
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3925)
+++ unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3924)
@@ -1104,14 +1104,6 @@
   unsigned int i, n;
   int j, k;
 
-  /* 
-   * Since we are checking the current state to determine if we need
-   * to fake modifiers, we must make sure that everything put on the
-   * input queue is processed before we start. Otherwise, shift may be
-   * stuck down.
-   */ 
-  mieqProcessInputEvents();
-
   if (keysym == XK_Caps_Lock) {
     vlog.debug("Ignoring caps lock");
     return;
@@ -1228,15 +1220,6 @@
 #endif
     );
   }
-
-  /*
-   * When faking a modifier we are putting a keycode (which can
-   * currently activate the desired modifier) on the input
-   * queue. A future modmap change can change the mapping so
-   * that this keycode means something else entirely. Guard
-   * against this by processing the queue now.
-   */
-  mieqProcessInputEvents();
 }
 
 static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col)

tigervnc11-r3883.patch:
 XserverDesktop.cc |   38 +++++++++++++++++++-------------------
 XserverDesktop.h  |    4 ++--
 vncHooks.cc       |   12 ++++++------
 xvnc.cc           |   14 +++++++-------
 4 files changed, 34 insertions(+), 34 deletions(-)

--- NEW FILE tigervnc11-r3883.patch ---
Index: unix/xserver/hw/vnc/xvnc.cc
===================================================================
--- unix/xserver/hw/vnc/xvnc.cc	(revision 3882)
+++ unix/xserver/hw/vnc/xvnc.cc	(revision 3883)
@@ -736,7 +736,7 @@
 }
 
 static Bool vfbRealizeCursor(
-#ifdef XORG_16
+#if XORG >= 16
 			     DeviceIntPtr pDev,
 #endif
 			     ScreenPtr pScreen, CursorPtr pCursor) {
@@ -744,7 +744,7 @@
 }
 
 static Bool vfbUnrealizeCursor(
-#ifdef XORG_16
+#if XORG >= 16
 			       DeviceIntPtr pDev,
 #endif
 			       ScreenPtr pScreen, CursorPtr pCursor) {
@@ -752,7 +752,7 @@
 }
 
 static void vfbSetCursor(
-#ifdef XORG_16
+#if XORG >= 16
 			 DeviceIntPtr pDev,
 #endif
 			 ScreenPtr pScreen, CursorPtr pCursor, int x, int y) 
@@ -760,14 +760,14 @@
 }
 
 static void vfbMoveCursor(
-#ifdef XORG_16
+#if XORG >= 16
 			  DeviceIntPtr pDev,
 #endif
 			  ScreenPtr pScreen, int x, int y) 
 {
 }
 
-#ifdef XORG_16
+#if XORG >= 16
 static Bool
 vfbDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
 {   
@@ -785,7 +785,7 @@
     vfbUnrealizeCursor,
     vfbSetCursor,
     vfbMoveCursor
-#ifdef XORG_16
+#if XORG >= 16
     , vfbDeviceCursorInitialize,
     vfbDeviceCursorCleanup
 #endif
@@ -1303,7 +1303,7 @@
 void ProcessInputEvents()
 {
   mieqProcessInputEvents();
-#ifdef XORG_15
+#if XORG == 15
   miPointerUpdate();
 #endif
 }
Index: unix/xserver/hw/vnc/XserverDesktop.cc
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3882)
+++ unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3883)
@@ -63,7 +63,7 @@
 #ifdef XKB
 #include <xkbsrv.h>
 #endif
-#ifdef XORG_16
+#if XORG >= 16
 #include "exevents.h"
 extern void
 CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
@@ -77,7 +77,7 @@
 
 static DeviceIntPtr vncKeyboardDevice = NULL;
 static DeviceIntPtr vncPointerDevice = NULL;
-#ifdef XORG_15
+#if XORG == 15
 static xEvent *eventq = NULL;
 #else
 static EventList *eventq = NULL;
@@ -194,7 +194,7 @@
   if (httpListener)
     httpServer = new FileHTTPServer(this);
 
-#ifdef XORG_15
+#if XORG == 15
   /*
    * XXX eventq is never free()-ed because it has to exist during server life
    * */
@@ -211,7 +211,7 @@
    */
   if (vncKeyboardDevice == NULL) {
     vncKeyboardDevice = AddInputDevice(
-#ifdef XORG_16
+#if XORG >= 16
 				       serverClient,
 #endif
 				       vfbKeybdProc, TRUE);
@@ -220,7 +220,7 @@
 
   if (vncPointerDevice == NULL) {
     vncPointerDevice = AddInputDevice(
-#ifdef XORG_16
+#if XORG >= 16
 				      serverClient,
 #endif
 				      vfbMouseProc, TRUE);
@@ -557,7 +557,7 @@
   if (!cursorPos.equals(oldCursorPos)) {
     oldCursorPos = cursorPos;
     (*pScreen->SetCursorPosition) (
-#ifdef XORG_16
+#if XORG >= 16
 				   vncPointerDevice,
 #endif
 				   pScreen, cursorPos.x, cursorPos.y, FALSE);
@@ -569,7 +569,7 @@
 void XserverDesktop::blockHandler(fd_set* fds)
 {
   try {
-#ifdef XORG_15
+#if XORG == 15
     ScreenPtr screenWithCursor = GetCurrentRootWindow()->drawable.pScreen;
 #else
     ScreenPtr screenWithCursor =
@@ -578,7 +578,7 @@
     if (screenWithCursor == pScreen) {
       int x, y;
       GetSpritePosition(
-#ifdef XORG_16
+#if XORG >= 16
 			vncPointerDevice,
 #endif
 			&x, &y);
@@ -742,7 +742,7 @@
   //(*pScreen->SetCursorPosition) (pScreen, pos.x, pos.y, FALSE);
 
   NewCurrentScreen(
-#ifdef XORG_16
+#if XORG >= 16
 		   vncPointerDevice,
 #endif
 		   pScreen, pos.x, pos.y);
@@ -751,7 +751,7 @@
     valuators[0] = pos.x;
     valuators[1] = pos.y;
 
-#ifdef XORG_16
+#if XORG >= 16
     GetEventList(&eventq);
 #endif
     n = GetPointerEvents (eventq, vncPointerDevice, MotionNotify, 0,
@@ -759,7 +759,7 @@
 
     for (i = 0; i < n; i++) {
       mieqEnqueue (vncPointerDevice,
-#ifdef XORG_15
+#if XORG == 15
 		   eventq + i
 #else
 		   (eventq + i)->event
@@ -779,7 +779,7 @@
 
       for (j = 0; j < n; j++) {
 	mieqEnqueue (vncPointerDevice,
-#ifdef XORG_15
+#if XORG == 15
 		     eventq + j
 #else
 		     (eventq + j)->event
@@ -809,7 +809,7 @@
   RRModePtr         mode;
 
   // Make sure all RandR tables are properly populated
-#ifdef XORG_15
+#if XORG == 15
   ret = RRGetInfo(pScreen);
 #else
   ret = RRGetInfo(pScreen, FALSE);
@@ -832,7 +832,7 @@
 
   // Then we have to call RRGetInfo again for it to copy the RandR
   // 1.0 information to the 1.2 structures.
-#ifdef XORG_15
+#if XORG == 15
   ret = RRGetInfo(pScreen);
 #else
   ret = RRGetInfo(pScreen, FALSE);
@@ -1008,7 +1008,7 @@
 			   down ? KeyPress : KeyRelease, keycode);
     for (i = 0; i < n; i++) {
       mieqEnqueue (vncKeyboardDevice,
-#ifdef XORG_15
+#if XORG == 15
 		   eventq + i
 #else
 		   (eventq + i)->event
@@ -1161,7 +1161,7 @@
 
 	vlog.info("Added unknown keysym 0x%x to keycode %d",keysym,kc);
 
-#ifdef XORG_15
+#if XORG == 15
 	master = inputInfo.keyboard;
 #else
 	master = vncKeyboardDevice->u.master;
@@ -1169,7 +1169,7 @@
 	if (vncKeyboardDevice ==
 	    dixLookupPrivate(&master->devPrivates, CoreDevicePrivateKey)) {
 	  dixSetPrivate(&master->devPrivates, CoreDevicePrivateKey, NULL);
-#ifdef XORG_15
+#if XORG == 15
 	  SwitchCoreKeyboard(vncKeyboardDevice);
 #else
 	  CopyKeyClass(vncKeyboardDevice, master);
@@ -1213,7 +1213,7 @@
 			 KeyPress : KeyRelease, kc);
   for (i = 0; i < n; i++) {
     mieqEnqueue (vncKeyboardDevice,
-#ifdef XORG_15
+#if XORG == 15
 		 eventq + i
 #else
 		 (eventq + i)->event
@@ -1492,7 +1492,7 @@
     map[4] = 4;
     map[5] = 5;
     InitPointerDeviceStruct(pDev, map, 5,
-#ifdef XORG_15
+#if XORG == 15
 			    GetMotionHistory,
 #endif
 			    (PtrCtrlProcPtr)NoopDDA, GetMotionHistorySize(), 2);
Index: unix/xserver/hw/vnc/XserverDesktop.h
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.h	(revision 3882)
+++ unix/xserver/hw/vnc/XserverDesktop.h	(revision 3883)
@@ -29,10 +29,10 @@
 #if XORG_VERSION_CURRENT < \
 	((1 * 10000000) + (5 * 100000) + (99 * 1000))
 /* Xorg 1.5 branch */
-#define XORG_15
+#define XORG 15
 #else
 /* Xorg 1.6 branch */
-#define XORG_16
+#define XORG 16
 #endif
 
 #include <rfb/SDesktop.h>
Index: unix/xserver/hw/vnc/vncHooks.cc
===================================================================
--- unix/xserver/hw/vnc/vncHooks.cc	(revision 3882)
+++ unix/xserver/hw/vnc/vncHooks.cc	(revision 3883)
@@ -89,7 +89,7 @@
     GCOps *wrappedOps;
 } vncHooksGCRec, *vncHooksGCPtr;
 
-#ifdef XORG_15
+#if XORG == 15
 static DevPrivateKey vncHooksScreenPrivateKey = &vncHooksScreenPrivateKey;
 static DevPrivateKey vncHooksGCPrivateKey = &vncHooksGCPrivateKey;
 #else
@@ -119,7 +119,7 @@
 static void vncHooksStoreColors(ColormapPtr pColormap, int ndef,
                                 xColorItem* pdef);
 static Bool vncHooksDisplayCursor(
-#ifdef XORG_16
+#if XORG >= 16
 				  DeviceIntPtr pDev,
 #endif
 				  ScreenPtr pScreen, CursorPtr cursor);
@@ -454,7 +454,7 @@
 // DisplayCursor - get the cursor shape
 
 static Bool vncHooksDisplayCursor(
-#ifdef XORG_16
+#if XORG >= 16
 				  DeviceIntPtr pDev,
 #endif
 				  ScreenPtr pScreen_, CursorPtr cursor)
@@ -462,11 +462,11 @@
   SCREEN_UNWRAP(pScreen_, DisplayCursor);
 
   Bool ret = (*pScreen->DisplayCursor) (
-#ifdef XORG_16
+#if XORG >= 16
 					pDev,
 #endif
 					pScreen, cursor);
-#ifdef XORG_16
+#if XORG >= 16
   /*
    * XXX DIX calls this function with NULL argument to remove cursor sprite from
    * screen. Should we handle this in setCursor as well?
@@ -474,7 +474,7 @@
   if (cursor != NullCursor) {
 #endif
     vncHooksScreen->desktop->setCursor(cursor);
-#ifdef XORG_16
+#if XORG >= 16
   }
 #endif
 

tigervnc11-r3884.patch:
 Makefile.am       |    2 +-
 XserverDesktop.cc |    1 +
 XserverDesktop.h  |    9 ---------
 vncHooks.cc       |    1 +
 xorg-version.h    |   33 +++++++++++++++++++++++++++++++++
 xvnc.cc           |    1 +
 6 files changed, 37 insertions(+), 10 deletions(-)

--- NEW FILE tigervnc11-r3884.patch ---
Index: unix/xserver/hw/vnc/xvnc.cc
===================================================================
--- unix/xserver/hw/vnc/xvnc.cc	(revision 3883)
+++ unix/xserver/hw/vnc/xvnc.cc	(revision 3884)
@@ -37,6 +37,7 @@
 #include <rfb/LogWriter.h>
 #include <network/TcpSocket.h>
 #include "vncExtInit.h"
+#include "xorg-version.h"
 
 extern "C" {
 #define class c_class
Index: unix/xserver/hw/vnc/xorg-version.h
===================================================================
--- unix/xserver/hw/vnc/xorg-version.h	(revision 0)
+++ unix/xserver/hw/vnc/xorg-version.h	(revision 3884)
@@ -0,0 +1,33 @@
+/* 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.
+ */
+
+#ifndef XORG_VERSION_H
+#define XORG_VERSION_H
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#if XORG_VERSION_CURRENT < ((1 * 10000000) + (5 * 100000) + (99 * 1000))
+#define XORG 15
+#else
+#define XORG 16
+#endif
+
+#endif
Index: unix/xserver/hw/vnc/Makefile.am
===================================================================
--- unix/xserver/hw/vnc/Makefile.am	(revision 3883)
+++ unix/xserver/hw/vnc/Makefile.am	(revision 3884)
@@ -9,7 +9,7 @@
 
 noinst_LTLIBRARIES = libvnccommon.la
 
-HDRS = RegionHelper.h vncExtInit.h vncHooks.h XserverDesktop.h
+HDRS = RegionHelper.h vncExtInit.h vncHooks.h XserverDesktop.h xorg-version.h
 
 libvnccommon_la_SOURCES = $(HDRS) vncExtInit.cc vncHooks.cc XserverDesktop.cc
 
Index: unix/xserver/hw/vnc/XserverDesktop.cc
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3883)
+++ unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3884)
@@ -41,6 +41,7 @@
 #include <rfb/Configuration.h>
 #include "XserverDesktop.h"
 #include "vncExtInit.h"
+#include "xorg-version.h"
 
 extern "C" {
 #define public c_public
Index: unix/xserver/hw/vnc/XserverDesktop.h
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.h	(revision 3883)
+++ unix/xserver/hw/vnc/XserverDesktop.h	(revision 3884)
@@ -26,15 +26,6 @@
 #include <dix-config.h>
 #endif
 
-#if XORG_VERSION_CURRENT < \
-	((1 * 10000000) + (5 * 100000) + (99 * 1000))
-/* Xorg 1.5 branch */
-#define XORG 15
-#else
-/* Xorg 1.6 branch */
-#define XORG 16
-#endif
-
 #include <rfb/SDesktop.h>
 #include <rfb/HTTPServer.h>
 #include <rfb/PixelBuffer.h>
Index: unix/xserver/hw/vnc/vncHooks.cc
===================================================================
--- unix/xserver/hw/vnc/vncHooks.cc	(revision 3883)
+++ unix/xserver/hw/vnc/vncHooks.cc	(revision 3884)
@@ -25,6 +25,7 @@
 #include "XserverDesktop.h"
 #include "vncHooks.h"
 #include "vncExtInit.h"
+#include "xorg-version.h"
 
 extern "C" {
 #define class c_class

tigervnc11-r3885.patch:
 XserverDesktop.cc |    2 ++
 1 file changed, 2 insertions(+)

--- NEW FILE tigervnc11-r3885.patch ---
Index: unix/xserver/hw/vnc/XserverDesktop.cc
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3884)
+++ unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3885)
@@ -203,6 +203,8 @@
     eventq = (xEvent *) xcalloc(sizeof(xEvent), GetMaximumEventsNum());
   if (!eventq)
     FatalError("Couldn't allocate eventq\n");
+#else
+  GetEventList(&eventq);
 #endif
 
   /*

tigervnc11-r3886.patch:
 Input.cc          |  167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Input.h           |   61 +++++++++++++++++++
 Makefile.am       |    6 +
 XserverDesktop.cc |  142 +--------------------------------------------
 XserverDesktop.h  |    5 -
 5 files changed, 240 insertions(+), 141 deletions(-)

--- NEW FILE tigervnc11-r3886.patch ---
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;

tigervnc11-r3887.patch:
 Input.cc          |  606 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 Input.h           |   13 +
 XserverDesktop.cc |  589 ----------------------------------------------------
 XserverDesktop.h  |    1 
 4 files changed, 622 insertions(+), 587 deletions(-)

--- NEW FILE tigervnc11-r3887.patch ---
Index: unix/xserver/hw/vnc/Input.cc
===================================================================
--- unix/xserver/hw/vnc/Input.cc	(revision 3886)
+++ unix/xserver/hw/vnc/Input.cc	(revision 3887)
@@ -21,13 +21,49 @@
 #include <dix-config.h>
 #endif
 
+#include <rfb/LogWriter.h>
 #include "Input.h"
 #include "xorg-version.h"
+#include "vncExtInit.h"
 
 extern "C" {
+#define public c_public
+#define class c_class
+#include "inputstr.h"
 #include "mi.h"
+#ifndef XKB_IN_SERVER
+#define XKB_IN_SERVER
+#endif
+#ifdef XKB
+/*
+ * This include is needed to use XkbConvertCase instead of XConvertCase even if
+ * we don't use XKB extension.
+ */
+#include <xkbsrv.h>
+#endif
+#if XORG >= 16
+#include "exevents.h"
+extern void
+CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
+#endif
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+#undef public
+#undef class
 }
 
+using namespace rdr;
+using namespace rfb;
+
+static LogWriter vlog("Input");
+
+#define BUTTONS 5
+static int pointerProc(DeviceIntPtr pDevice, int onoff);
+
+static int keyboardProc(DeviceIntPtr pDevice, int onoff);
+static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col);
+static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col);
+
 /* Event queue is shared between all devices. */
 #if XORG == 15
 static xEvent *eventq = NULL;
@@ -70,10 +106,6 @@
 	}
 }
 
-/* Pointer device pre-declarations */
-#define BUTTONS 5
-static int pointerProc(DeviceIntPtr pDevice, int onoff);
-
 /* Pointer device methods */
 
 PointerDevice::PointerDevice(rfb::VNCServerST *_server)
@@ -165,3 +197,569 @@
 	return Success;
 }
 
+/* KeyboardDevice methods */
+
+KeyboardDevice::KeyboardDevice(void)
+{
+	dev = AddInputDevice(
+#if XORG >= 16
+			     serverClient,
+#endif
+			     keyboardProc, TRUE);
+	RegisterKeyboardDevice(dev);
+	initEventq();
+}
+
+#define IS_PRESSED(keyc, keycode) \
+	((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
+
+/*
+ * ModifierState is a class which helps simplify generating a "fake" press or
+ * release of shift, ctrl, alt, etc.  An instance of the class is created for
+ * every modifier which may need to be pressed or released.  Then either
+ * press() or release() may be called to make sure that the corresponding keys
+ * are in the right state.  The destructor of the class automatically reverts
+ * to the previous state.  Each modifier may have multiple keys associated with
+ * it, so in the case of a fake release, this may involve releasing more than
+ * one key.
+ */
+
+class ModifierState {
+public:
+	ModifierState(DeviceIntPtr _dev, int _modIndex)
+		: modIndex(_modIndex), nKeys(0), keys(0), pressed(false),
+		  dev(_dev) {}
+
+	~ModifierState()
+	{
+		for (int i = 0; i < nKeys; i++)
+			generateXKeyEvent(keys[i], !pressed);
+		delete [] keys;
+	}
+
+	void press()
+	{
+		KeyClassPtr keyc = dev->key;
+		if (!(keyc->state & (1 << modIndex))) {
+			int index = modIndex * keyc->maxKeysPerModifier;
+			tempKeyEvent(keyc->modifierKeyMap[index], true);
+			pressed = true;
+		}
+	}
+
+	void release()
+	{
+		KeyClassPtr keyc = dev->key;
+		if ((keyc->state & (1 << modIndex)) == 0)
+			return;
+
+		for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
+			int index = modIndex * keyc->maxKeysPerModifier + k;
+			int keycode = keyc->modifierKeyMap[index];
+			if (keycode && IS_PRESSED(keyc, keycode))
+				tempKeyEvent(keycode, false);
+		}
+	}
+
+private:
+	void tempKeyEvent(int keycode, bool down)
+	{
+		if (keycode) {
+			if (!keys) keys = new int[dev->key->maxKeysPerModifier];
+			keys[nKeys++] = keycode;
+			generateXKeyEvent(keycode, down);
+		}
+	}
+
+	void generateXKeyEvent(int keycode, bool down)
+	{
+		int n, action;
+
+		action = down ? KeyPress : KeyRelease;
+		n = GetKeyboardEvents(eventq, dev, action, keycode);
+		enqueueEvents(dev, n);
+
+		vlog.debug("fake keycode %d %s", keycode,
+			   down ? "down" : "up");
+	}
+
+	int modIndex;
+	int nKeys;
+	int *keys;
+	bool pressed;
+	DeviceIntPtr dev;
+};
+
+
+/* altKeysym is a table of alternative keysyms which have the same meaning. */
+
+static struct altKeysym_t {
+	KeySym a, b;
+} altKeysym[] = {
+	{ XK_Shift_L,		XK_Shift_R },
+	{ XK_Control_L,		XK_Control_R },
+	{ XK_Meta_L,		XK_Meta_R },
+	{ XK_Alt_L,		XK_Alt_R },
+	{ XK_Super_L,		XK_Super_R },
+	{ XK_Hyper_L,		XK_Hyper_R },
+	{ XK_KP_Space,		XK_space },
+	{ XK_KP_Tab,		XK_Tab },
+	{ XK_KP_Enter,		XK_Return },
+	{ XK_KP_F1,		XK_F1 },
+	{ XK_KP_F2,		XK_F2 },
+	{ XK_KP_F3,		XK_F3 },
+	{ XK_KP_F4,		XK_F4 },
+	{ XK_KP_Home,		XK_Home },
+	{ XK_KP_Left,		XK_Left },
+	{ XK_KP_Up,		XK_Up },
+	{ XK_KP_Right,		XK_Right },
+	{ XK_KP_Down,		XK_Down },
+	{ XK_KP_Page_Up,	XK_Page_Up },
+	{ XK_KP_Page_Down,	XK_Page_Down },
+	{ XK_KP_End,		XK_End },
+	{ XK_KP_Begin,		XK_Begin },
+	{ XK_KP_Insert,		XK_Insert },
+	{ XK_KP_Delete,		XK_Delete },
+	{ XK_KP_Equal,		XK_equal },
+	{ XK_KP_Multiply,	XK_asterisk },
+	{ XK_KP_Add,		XK_plus },
+	{ XK_KP_Separator,	XK_comma },
+	{ XK_KP_Subtract,	XK_minus },
+	{ XK_KP_Decimal,	XK_period },
+	{ XK_KP_Divide,		XK_slash },
+	{ XK_KP_0,		XK_0 },
+	{ XK_KP_1,		XK_1 },
+	{ XK_KP_2,		XK_2 },
+	{ XK_KP_3,		XK_3 },
+	{ XK_KP_4,		XK_4 },
+	{ XK_KP_5,		XK_5 },
+	{ XK_KP_6,		XK_6 },
+	{ XK_KP_7,		XK_7 },
+	{ XK_KP_8,		XK_8 },
+	{ XK_KP_9,		XK_9 },
+};
+
+/*
+ * keyEvent() - work out the best keycode corresponding to the keysym sent by
+ * the viewer.  This is non-trivial because we can't assume much about the
+ * local keyboard layout.  We must also find out which column of the keyboard
+ * mapping the keysym is in, and alter the shift state appropriately.  Column 0
+ * means both shift and "mode_switch" (AltGr) must be released, column 1 means
+ * shift must be pressed and mode_switch released, column 2 means shift must be
+ * released and mode_switch pressed, and column 3 means both shift and
+ * mode_switch must be pressed.
+ *
+ * Magic, which dynamically adds keysym<->keycode mapping depends on X.Org
+ * version. Quick explanation of that "magic":
+ * 
+ * 1.5
+ * - has only one core keyboard so we have to keep core keyboard mapping
+ *   synchronized with vncKeyboardDevice. Do it via SwitchCoreKeyboard()
+ *
+ * 1.6 (aka MPX - Multi pointer X)
+ * - multiple master devices (= core devices) exists, keep vncKeyboardDevice
+ *   synchronized with proper master device
+ */
+
+void KeyboardDevice::keyEvent(rdr::U32 keysym, bool down)
+{
+	DeviceIntPtr master;
+	KeyClassPtr keyc = dev->key;
+	KeySymsPtr keymap = &keyc->curKeySyms;
+	KeySym *map = keymap->map;
+	KeyCode minKeyCode = keymap->minKeyCode;
+	KeyCode maxKeyCode = keymap->maxKeyCode;
+	int mapWidth = keymap->mapWidth;
+	unsigned int i, n;
+	int j, k, action;
+
+	if (keysym == XK_Caps_Lock) {
+		vlog.debug("Ignoring caps lock");
+		return;
+	}
+
+	/* find which modifier Mode_switch is on. */
+	int modeSwitchMapIndex = 0;
+	for (i = 3; i < 8; i++) {
+		for (k = 0; k < keyc->maxKeysPerModifier; k++) {
+			int index = i * keyc->maxKeysPerModifier + k;
+			int keycode = keyc->modifierKeyMap[index];
+
+			if (keycode == 0)
+				continue;
+
+			for (j = 0; j < mapWidth; j++) {
+				if (map[(keycode - minKeyCode) * mapWidth + j]
+				    == XK_Mode_switch) {
+					modeSwitchMapIndex = i;
+					goto ModeSwitchFound;
+				}
+			}
+		}
+	}
+ModeSwitchFound:
+
+	int col = 0;
+	if ((keyc->state & (1 << ShiftMapIndex)) != 0)
+		col |= 1;
+	if (modeSwitchMapIndex != 0 &&
+	    ((keyc->state & (1 << modeSwitchMapIndex))) != 0)
+		col |= 2;
+
+	int kc = KeysymToKeycode(keymap, keysym, &col);
+
+	/*
+	 * Sort out the "shifted Tab" mess.  If we are sent a shifted Tab,
+	 * generate a local shifted Tab regardless of what the "shifted Tab"
+	 * keysym is on the local keyboard (it might be Tab, ISO_Left_Tab or
+	 * HP's private BackTab keysym, and quite possibly some others too).
+	 * We never get ISO_Left_Tab here because it's already been translated
+	 * in VNCSConnectionST.
+	 */
+	if (keysym == XK_Tab && ((keyc->state & (1 << ShiftMapIndex))) != 0)
+		col |= 1;
+
+	if (kc == 0) {
+		/*
+		 * Not a direct match in the local keyboard mapping.  Check for
+		 * alternative keysyms with the same meaning.
+		 */
+		for (i = 0; i < sizeof(altKeysym) / sizeof(altKeysym_t); i++) {
+			if (keysym == altKeysym[i].a)
+				kc = KeysymToKeycode(keymap, altKeysym[i].b,
+						     &col);
+			else if (keysym == altKeysym[i].b)
+				kc = KeysymToKeycode(keymap, altKeysym[i].a,
+						     &col);
+			if (kc)
+				break;
+		}
+	}
+
+	if (kc == 0) {
+		/* Dynamically add a new key to the keyboard mapping. */
+		for (kc = maxKeyCode; kc >= minKeyCode; kc--) {
+			if (map[(kc - minKeyCode) * mapWidth] != 0)
+				continue;
+
+			map[(kc - minKeyCode) * mapWidth] = keysym;
+			col = 0;
+
+			vlog.info("Added unknown keysym 0x%x to keycode %d",
+				  keysym, kc);
+#if XORG == 15
+			master = inputInfo.keyboard;
+#else
+			master = dev->u.master;
+#endif
+			void *slave = dixLookupPrivate(&master->devPrivates,
+						       CoreDevicePrivateKey);
+			if (dev == slave) {
+				dixSetPrivate(&master->devPrivates,
+					      CoreDevicePrivateKey, NULL);
+#if XORG == 15
+				SwitchCoreKeyboard(dev);
+#else
+				CopyKeyClass(dev, master);
+#endif
+			}
+			break;
+		}
+	}
+
+	if (kc < minKeyCode) {
+		vlog.info("Keyboard mapping full - ignoring unknown keysym "
+			  "0x%x",keysym);
+		return;
+	}
+
+	/*
+	 * See if it's a modifier key.  If so, then don't do any auto-repeat,
+	 * because the X server will translate each press into a release
+	 * followed by a press.
+	 */
+	for (i = 0; i < 8; i++) {
+		for (k = 0; k < keyc->maxKeysPerModifier; k++) {
+			int index = i * keyc->maxKeysPerModifier + k;
+			if (kc == keyc->modifierKeyMap[index] &&
+			    IS_PRESSED(keyc,kc) && down)
+				return;
+		}
+	}
+
+	ModifierState shift(dev, ShiftMapIndex);
+	ModifierState modeSwitch(dev, modeSwitchMapIndex);
+	if (down) {
+		if (col & 1)
+			shift.press();
+		else
+			shift.release();
+		if (modeSwitchMapIndex) {
+			if (col & 2)
+				modeSwitch.press();
+			else
+				modeSwitch.release();
+		}
+	}
+
+	vlog.debug("keycode %d %s", kc, down ? "down" : "up");
+	action = down ? KeyPress : KeyRelease;
+	n = GetKeyboardEvents(eventq, dev, action, kc);
+	enqueueEvents(dev, n);
+}
+
+static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col)
+{
+	int per = keymap->mapWidth;
+	KeySym *syms;
+	KeySym lsym, usym;
+
+	if ((col < 0) || ((col >= per) && (col > 3)) ||
+	    (keycode < keymap->minKeyCode) || (keycode > keymap->maxKeyCode))
+		return NoSymbol;
+
+	syms = &keymap->map[(keycode - keymap->minKeyCode) * per];
+	if (col >= 4)
+		return syms[col];
+
+	if (col > 1) {
+		while ((per > 2) && (syms[per - 1] == NoSymbol))
+			per--;
+		if (per < 3)
+			col -= 2;
+	}
+
+	if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
+		XConvertCase(syms[col&~1], &lsym, &usym);
+		if (!(col & 1))
+			return lsym;
+		/*
+		 * I'm commenting out this logic because it's incorrect even
+		 * though it was copied from the Xlib sources.  The X protocol
+		 * book quite clearly states that where a group consists of
+		 * element 1 being a non-alphabetic keysym and element 2 being
+		 * NoSymbol that you treat the second element as being the
+		 * same as the first.  This also tallies with the behaviour
+		 * produced by the installed Xlib on my linux box (I believe
+		 * this is because it uses some XKB code rather than the
+		 * original Xlib code - compare XKBBind.c with KeyBind.c in
+		 * lib/X11).
+		 */
+#if 0
+		else if (usym == lsym)
+			return NoSymbol;
+#endif
+		else
+			return usym;
+	}
+
+	return syms[col];
+}
+
+/*
+ * KeysymToKeycode() - find the keycode and column corresponding to the given
+ * keysym.  The value of col passed in should be the column determined from the
+ * current shift state.  If the keysym can be found in that column we prefer
+ * that to finding it in a different column (which would require fake events to
+ * alter the shift state).
+ */
+static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col)
+{
+	int i, j;
+
+	j = *col;
+	for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
+		if (KeyCodetoKeySym(keymap, i, j) == ks)
+			return i;
+	}
+
+	for (j = 0; j < keymap->mapWidth; j++) {
+		for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
+			if (KeyCodetoKeySym(keymap, i, j) == ks) {
+				*col = j;
+				return i;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/* Fairly standard US PC Keyboard */
+
+#define MIN_KEY 8
+#define MAX_KEY 255
+#define MAP_LEN (MAX_KEY - MIN_KEY + 1)
+#define KEYSYMS_PER_KEY 2
+KeySym keyboardMap[MAP_LEN * KEYSYMS_PER_KEY] = {
+	NoSymbol, NoSymbol,
+	XK_Escape, NoSymbol,
+	XK_1, XK_exclam,
+	XK_2, XK_at,
+	XK_3, XK_numbersign,
+	XK_4, XK_dollar,
+	XK_5, XK_percent,
+	XK_6, XK_asciicircum,
+	XK_7, XK_ampersand,
+	XK_8, XK_asterisk,
+	XK_9, XK_parenleft,
+	XK_0, XK_parenright,
+	XK_minus, XK_underscore,
+	XK_equal, XK_plus,
+	XK_BackSpace, NoSymbol,
+	XK_Tab, NoSymbol,
+	XK_q, XK_Q,
+	XK_w, XK_W,
+	XK_e, XK_E,
+	XK_r, XK_R,
+	XK_t, XK_T,
+	XK_y, XK_Y,
+	XK_u, XK_U,
+	XK_i, XK_I,
+	XK_o, XK_O,
+	XK_p, XK_P,
+	XK_bracketleft, XK_braceleft,
+	XK_bracketright, XK_braceright,
+	XK_Return, NoSymbol,
+	XK_Control_L, NoSymbol,
+	XK_a, XK_A,
+	XK_s, XK_S,
+	XK_d, XK_D,
+	XK_f, XK_F,
+	XK_g, XK_G,
+	XK_h, XK_H,
+	XK_j, XK_J,
+	XK_k, XK_K,
+	XK_l, XK_L,
+	XK_semicolon, XK_colon,
+	XK_apostrophe, XK_quotedbl,
+	XK_grave, XK_asciitilde,
+	XK_Shift_L, NoSymbol,
+	XK_backslash, XK_bar,
+	XK_z, XK_Z,
+	XK_x, XK_X,
+	XK_c, XK_C,
+	XK_v, XK_V,
+	XK_b, XK_B,
+	XK_n, XK_N,
+	XK_m, XK_M,
+	XK_comma, XK_less,
+	XK_period, XK_greater,
+	XK_slash, XK_question,
+	XK_Shift_R, NoSymbol,
+	XK_KP_Multiply, NoSymbol,
+	XK_Alt_L, XK_Meta_L,
+	XK_space, NoSymbol,
+	/* XK_Caps_Lock */ NoSymbol, NoSymbol,
+	XK_F1, NoSymbol,
+	XK_F2, NoSymbol,
+	XK_F3, NoSymbol,
+	XK_F4, NoSymbol,
+	XK_F5, NoSymbol,
+	XK_F6, NoSymbol,
+	XK_F7, NoSymbol,
+	XK_F8, NoSymbol,
+	XK_F9, NoSymbol,
+	XK_F10, NoSymbol,
+	XK_Num_Lock, XK_Pointer_EnableKeys,
+	XK_Scroll_Lock, NoSymbol,
+	XK_KP_Home, XK_KP_7,
+	XK_KP_Up, XK_KP_8,
+	XK_KP_Prior, XK_KP_9,
+	XK_KP_Subtract, NoSymbol,
+	XK_KP_Left, XK_KP_4,
+	XK_KP_Begin, XK_KP_5,
+	XK_KP_Right, XK_KP_6,
+	XK_KP_Add, NoSymbol,
+	XK_KP_End, XK_KP_1,
+	XK_KP_Down, XK_KP_2,
+	XK_KP_Next, XK_KP_3,
+	XK_KP_Insert, XK_KP_0,
+	XK_KP_Delete, XK_KP_Decimal,
+	NoSymbol, NoSymbol,
+	NoSymbol, NoSymbol,
+	NoSymbol, NoSymbol,
+	XK_F11, NoSymbol,
+	XK_F12, NoSymbol,
+	XK_Home, NoSymbol,
+	XK_Up, NoSymbol,
+	XK_Prior, NoSymbol,
+	XK_Left, NoSymbol,
+	NoSymbol, NoSymbol,
+	XK_Right, NoSymbol,
+	XK_End, NoSymbol,
+	XK_Down, NoSymbol,
+	XK_Next, NoSymbol,
+	XK_Insert, NoSymbol,
+	XK_Delete, NoSymbol,
+	XK_KP_Enter, NoSymbol,
+	XK_Control_R, NoSymbol,
+	XK_Pause, XK_Break,
+	XK_Print, XK_Execute,
+	XK_KP_Divide, NoSymbol,
+	XK_Alt_R, XK_Meta_R,
+};
+
+static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
+{
+	int i;
+
+	for (i = 0; i < MAP_LENGTH; i++)
+		pModMap[i] = NoSymbol;
+
+	for (i = 0; i < MAP_LEN; i++) {
+		if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
+			pModMap[i + MIN_KEY] = LockMask;
+		else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
+			 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
+			pModMap[i + MIN_KEY] = ShiftMask;
+		else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
+			 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R)
+			pModMap[i + MIN_KEY] = ControlMask;
+		else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
+			 keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
+			pModMap[i + MIN_KEY] = Mod1Mask;
+	}
+
+	pKeySyms->minKeyCode = MIN_KEY;
+	pKeySyms->maxKeyCode = MAX_KEY;
+	pKeySyms->mapWidth = KEYSYMS_PER_KEY;
+	pKeySyms->map = keyboardMap;
+
+	return TRUE;
+}
+
+static void keyboardBell(int percent, DeviceIntPtr device, pointer ctrl,
+			 int class_)
+{
+	if (percent > 0)
+		vncBell();
+}
+
+static int keyboardProc(DeviceIntPtr pDevice, int onoff)
+{
+	KeySymsRec keySyms;
+	CARD8 modMap[MAP_LENGTH];
+	DevicePtr pDev = (DevicePtr)pDevice;
+
+	switch (onoff) {
+	case DEVICE_INIT:
+		GetMappings(&keySyms, modMap);
+		InitKeyboardDeviceStruct(pDev, &keySyms, modMap, keyboardBell,
+					 (KbdCtrlProcPtr)NoopDDA);
+		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 3886)
+++ unix/xserver/hw/vnc/Input.h	(revision 3887)
@@ -58,4 +58,17 @@
 	rfb::Point cursorPos, oldCursorPos;
 };
 
+/* Represents keyboard device. */
+class KeyboardDevice {
+public:
+	/* Create new Keyboard device instance. */
+	KeyboardDevice(void);
+
+	void Press(rdr::U32 keysym) { keyEvent(keysym, true); }
+	void Release(rdr::U32 keysym) { keyEvent(keysym, false); }
+private:
+	void keyEvent(rdr::U32 keysym, bool down);
+	DeviceIntPtr dev;
+};
+
 #endif
Index: unix/xserver/hw/vnc/XserverDesktop.cc
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3886)
+++ unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3887)
@@ -50,26 +50,7 @@
 
 extern char *display;
 
-#include "inputstr.h"
-#include "servermd.h"
 #include "colormapst.h"
-#include "resource.h"
-#include "cursorstr.h"
-#include "windowstr.h"
-#include "mi.h"
-#define XK_CYRILLIC
-#include <X11/keysym.h>
-#ifndef XKB_IN_SERVER
-#define XKB_IN_SERVER
-#endif
-#ifdef XKB
-#include <xkbsrv.h>
-#endif
-#if XORG >= 16
-#include "exevents.h"
-extern void
-CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
-#endif
 #ifdef RANDR
 #include "randrstr.h"
 #endif
@@ -77,15 +58,6 @@
 #undef class
 }
 
-static DeviceIntPtr vncKeyboardDevice = NULL;
-#if XORG == 15
-static xEvent *eventq = NULL;
-#else
-static EventList *eventq = NULL;
-#endif
-
-static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff);
-
 using namespace rfb;
 using namespace network;
 
@@ -102,8 +74,6 @@
                                  "rejecting the connection",
                                  10);
 
-static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col);
-
 static rdr::U8 reverseBits[] = {
   0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
   0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
@@ -193,33 +163,8 @@
   if (httpListener)
     httpServer = new FileHTTPServer(this);
 
-#if XORG == 15
-  /*
-   * XXX eventq is never free()-ed because it has to exist during server life
-   * */
-  if (!eventq)
-    eventq = (xEvent *) xcalloc(sizeof(xEvent), GetMaximumEventsNum());
-  if (!eventq)
-    FatalError("Couldn't allocate eventq\n");
-#else
-  GetEventList(&eventq);
-#endif
-
-  /*
-   * NOTE:
-   * We _might_ have to call ActivateDevice function for both keyboard and
-   * mouse. For Xvnc it's not needed but I have to check libvnc.so module.
-   */
-  if (vncKeyboardDevice == NULL) {
-    vncKeyboardDevice = AddInputDevice(
-#if XORG >= 16
-				       serverClient,
-#endif
-				       vfbKeybdProc, TRUE);
-    RegisterKeyboardDevice(vncKeyboardDevice);
-  }
-
   pointerDevice = new PointerDevice(server);
+  keyboardDevice = new KeyboardDevice();
 }
 
 XserverDesktop::~XserverDesktop()
@@ -229,6 +174,7 @@
   TimerFree(deferredUpdateTimer);
   TimerFree(dummyTimer);
   delete pointerDevice;
+  delete keyboardDevice;
   delete httpServer;
   delete server;
 }
@@ -854,533 +800,10 @@
   }
 }
 
-//
-// Keyboard handling
-//
-
-#define IS_PRESSED(keyc, keycode) \
-  ((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
-
-// ModifierState is a class which helps simplify generating a "fake" press
-// or release of shift, ctrl, alt, etc.  An instance of the class is created
-// for every modifier which may need to be pressed or released.  Then either
-// press() or release() may be called to make sure that the corresponding keys
-// are in the right state.  The destructor of the class automatically reverts
-// to the previous state.  Each modifier may have multiple keys associated with
-// it, so in the case of a fake release, this may involve releasing more than
-// one key.
-
-class ModifierState {
-public:
-  ModifierState(int modIndex_)
-    : modIndex(modIndex_), nKeys(0), keys(0), pressed(false)
-  {
-  }
-  ~ModifierState() {
-    for (int i = 0; i < nKeys; i++)
-      generateXKeyEvent(keys[i], !pressed);
-    delete [] keys;
-  }
-  void press() {
-    KeyClassPtr keyc = vncKeyboardDevice->key;
-    if (!(keyc->state & (1<<modIndex))) {
-      tempKeyEvent(keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier],
-                   true);
-      pressed = true;
-    }
-  }
-  void release() {
-    KeyClassPtr keyc = vncKeyboardDevice->key;
-    if (keyc->state & (1<<modIndex)) {
-      for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
-        int keycode
-          = keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier + k];
-        if (keycode && IS_PRESSED(keyc, keycode))
-          tempKeyEvent(keycode, false);
-      }
-    }
-  }
-private:
-  void tempKeyEvent(int keycode, bool down) {
-    if (keycode) {
-      if (!keys) keys = new int[vncKeyboardDevice->key->maxKeysPerModifier];
-      keys[nKeys++] = keycode;
-      generateXKeyEvent(keycode, down);
-    }
-  }
-  void generateXKeyEvent(int keycode, bool down) {
-    int i, n;
-    n = GetKeyboardEvents (eventq, vncKeyboardDevice,
-			   down ? KeyPress : KeyRelease, keycode);
-    for (i = 0; i < n; i++) {
-      mieqEnqueue (vncKeyboardDevice,
-#if XORG == 15
-		   eventq + i
-#else
-		   (eventq + i)->event
-#endif
-      );
-    }
-    vlog.debug("fake keycode %d %s", keycode, down ? "down" : "up");
-  }
-  int modIndex;
-  int nKeys;
-  int* keys;
-  bool pressed;
-};
-
-
-// altKeysym is a table of alternative keysyms which have the same meaning.
-
-struct altKeysym_t {
-  KeySym a, b;
-};
-
-altKeysym_t altKeysym[] = {
-  { XK_Shift_L,        XK_Shift_R },
-  { XK_Control_L,      XK_Control_R },
-  { XK_Meta_L,         XK_Meta_R },
-  { XK_Alt_L,          XK_Alt_R },
-  { XK_Super_L,        XK_Super_R },
-  { XK_Hyper_L,        XK_Hyper_R },
-  { XK_KP_Space,       XK_space },
-  { XK_KP_Tab,         XK_Tab },
-  { XK_KP_Enter,       XK_Return },
-  { XK_KP_F1,          XK_F1 },
-  { XK_KP_F2,          XK_F2 },
-  { XK_KP_F3,          XK_F3 },
-  { XK_KP_F4,          XK_F4 },
-  { XK_KP_Home,        XK_Home },
-  { XK_KP_Left,        XK_Left },
-  { XK_KP_Up,          XK_Up },
-  { XK_KP_Right,       XK_Right },
-  { XK_KP_Down,        XK_Down },
-  { XK_KP_Page_Up,     XK_Page_Up },
-  { XK_KP_Page_Down,   XK_Page_Down },
-  { XK_KP_End,         XK_End },
-  { XK_KP_Begin,       XK_Begin },
-  { XK_KP_Insert,      XK_Insert },
-  { XK_KP_Delete,      XK_Delete },
-  { XK_KP_Equal,       XK_equal },
-  { XK_KP_Multiply,    XK_asterisk },
-  { XK_KP_Add,         XK_plus },
-  { XK_KP_Separator,   XK_comma },
-  { XK_KP_Subtract,    XK_minus },
-  { XK_KP_Decimal,     XK_period },
-  { XK_KP_Divide,      XK_slash },
-  { XK_KP_0,           XK_0 },
-  { XK_KP_1,           XK_1 },
-  { XK_KP_2,           XK_2 },
-  { XK_KP_3,           XK_3 },
-  { XK_KP_4,           XK_4 },
-  { XK_KP_5,           XK_5 },
-  { XK_KP_6,           XK_6 },
-  { XK_KP_7,           XK_7 },
-  { XK_KP_8,           XK_8 },
-  { XK_KP_9,           XK_9 },
-};
-
-/*
- * keyEvent() - work out the best keycode corresponding to the keysym sent by
- * the viewer.  This is non-trivial because we can't assume much about the
- * local keyboard layout.  We must also find out which column of the keyboard
- * mapping the keysym is in, and alter the shift state appropriately.  Column 0
- * means both shift and "mode_switch" (AltGr) must be released, column 1 means
- * shift must be pressed and mode_switch released, column 2 means shift must be
- * released and mode_switch pressed, and column 3 means both shift and
- * mode_switch must be pressed.
- *
- * Magic, which dynamically adds keysym<->keycode mapping depends on X.Org
- * version. Quick explanation of that "magic":
- * 
- * 1.5
- * - has only one core keyboard so we have to keep core keyboard mapping
- *   synchronized with vncKeyboardDevice. Do it via SwitchCoreKeyboard()
- *
- * 1.6 (aka MPX - Multi pointer X)
- * - multiple master devices (= core devices) exists, keep vncKeyboardDevice
- *   synchronized with proper master device
- */
-
 void XserverDesktop::keyEvent(rdr::U32 keysym, bool down)
 {
-  DeviceIntPtr master;
-  KeyClassPtr keyc = vncKeyboardDevice->key;
-  KeySymsPtr keymap = &keyc->curKeySyms;
-  unsigned int i, n;
-  int j, k;
-
-  if (keysym == XK_Caps_Lock) {
-    vlog.debug("Ignoring caps lock");
-    return;
-  }
-
-  // find which modifier Mode_switch is on.
-  int modeSwitchMapIndex = 0;
-  for (i = 3; i < 8; i++) {
-    for (k = 0; k < keyc->maxKeysPerModifier; k++) {
-      int keycode = keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k];
-      for (j = 0; j < keymap->mapWidth; j++) {
-        if (keycode != 0 &&
-            keymap->map[(keycode - keymap->minKeyCode)
-                        * keymap->mapWidth + j] == XK_Mode_switch)
-        {
-          modeSwitchMapIndex = i;
-          break;
-        }
-      }
-    }
-  }
-
-  int col = 0;
-  if (keyc->state & (1<<ShiftMapIndex)) col |= 1;
-  if (modeSwitchMapIndex && (keyc->state & (1<<modeSwitchMapIndex))) col |= 2;
-
-  int kc = KeysymToKeycode(keymap, keysym, &col);
-
-  // Sort out the "shifted Tab" mess.  If we are sent a shifted Tab, generate a
-  // local shifted Tab regardless of what the "shifted Tab" keysym is on the
-  // local keyboard (it might be Tab, ISO_Left_Tab or HP's private BackTab
-  // keysym, and quite possibly some others too).  We never get ISO_Left_Tab
-  // here because it's already been translated in VNCSConnectionST.
-  if (keysym == XK_Tab && (keyc->state & (1<<ShiftMapIndex)))
-    col |= 1;
-
-  if (kc == 0) {
-    // Not a direct match in the local keyboard mapping.  Check for alternative
-    // keysyms with the same meaning.
-    for (i = 0; i < sizeof(altKeysym) / sizeof(altKeysym_t); i++) {
-      if (keysym == altKeysym[i].a)
-        kc = KeysymToKeycode(keymap, altKeysym[i].b, &col);
-      else if (keysym == altKeysym[i].b)
-        kc = KeysymToKeycode(keymap, altKeysym[i].a, &col);
-      if (kc) break;
-    }
-  }
-
-  if (kc == 0) {
-    // Last resort - dynamically add a new key to the keyboard mapping.
-    for (kc = keymap->maxKeyCode; kc >= keymap->minKeyCode; kc--) {
-      if (!keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth]) {
-        keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth] = keysym;
-        col = 0;
-
-	vlog.info("Added unknown keysym 0x%x to keycode %d",keysym,kc);
-
-#if XORG == 15
-	master = inputInfo.keyboard;
-#else
-	master = vncKeyboardDevice->u.master;
-#endif
-	if (vncKeyboardDevice ==
-	    dixLookupPrivate(&master->devPrivates, CoreDevicePrivateKey)) {
-	  dixSetPrivate(&master->devPrivates, CoreDevicePrivateKey, NULL);
-#if XORG == 15
-	  SwitchCoreKeyboard(vncKeyboardDevice);
-#else
-	  CopyKeyClass(vncKeyboardDevice, master);
-#endif
-	}
-        break;
-      }
-    }
-    if (kc < keymap->minKeyCode) {
-      vlog.info("Keyboard mapping full - ignoring unknown keysym 0x%x",keysym);
-      return;
-    }
-  }
-
-  // See if it's a modifier key.  If so, then don't do any auto-repeat, because
-  // the X server will translate each press into a release followed by a press.
-  for (i = 0; i < 8; i++) {
-    for (k = 0; k < keyc->maxKeysPerModifier; k++) {
-      if (kc == keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k] &&
-          IS_PRESSED(keyc,kc) && down)
-        return;
-    }
-  }
-
-  ModifierState shift(ShiftMapIndex);
-  ModifierState modeSwitch(modeSwitchMapIndex);
-  if (down) {
-    if (col & 1)
-      shift.press();
-    else
-      shift.release();
-    if (modeSwitchMapIndex) {
-      if (col & 2)
-        modeSwitch.press();
-      else
-        modeSwitch.release();
-    }
-  }
-  vlog.debug("keycode %d %s", kc, down ? "down" : "up");
-  n = GetKeyboardEvents (eventq, vncKeyboardDevice, down ?
-			 KeyPress : KeyRelease, kc);
-  for (i = 0; i < n; i++) {
-    mieqEnqueue (vncKeyboardDevice,
-#if XORG == 15
-		 eventq + i
-#else
-		 (eventq + i)->event
-#endif
-    );
-  }
+	if (down)
+		keyboardDevice->Press(keysym);
+	else
+		keyboardDevice->Release(keysym);
 }
-
-static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col)
-{
-  register int per = keymap->mapWidth;
-  register KeySym *syms;
-  KeySym lsym, usym;
-
-  if ((col < 0) || ((col >= per) && (col > 3)) ||
-      (keycode < keymap->minKeyCode) || (keycode > keymap->maxKeyCode))
-    return NoSymbol;
-
-  syms = &keymap->map[(keycode - keymap->minKeyCode) * per];
-  if (col < 4) {
-    if (col > 1) {
-      while ((per > 2) && (syms[per - 1] == NoSymbol))
-        per--;
-      if (per < 3)
-        col -= 2;
-    }
-    if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
-      XConvertCase(syms[col&~1], &lsym, &usym);
-      if (!(col & 1))
-        return lsym;
-      // I'm commenting out this logic because it's incorrect even though it
-      // was copied from the Xlib sources.  The X protocol book quite clearly
-      // states that where a group consists of element 1 being a non-alphabetic
-      // keysym and element 2 being NoSymbol that you treat the second element
-      // as being the same as the first.  This also tallies with the behaviour
-      // produced by the installed Xlib on my linux box (I believe this is
-      // because it uses some XKB code rather than the original Xlib code -
-      // compare XKBBind.c with KeyBind.c in lib/X11).
-      // else if (usym == lsym)
-      //   return NoSymbol;
-      else
-        return usym;
-    }
-  }
-  return syms[col];
-}
-
-// KeysymToKeycode() - find the keycode and column corresponding to the given
-// keysym.  The value of col passed in should be the column determined from the
-// current shift state.  If the keysym can be found in that column we prefer
-// that to finding it in a different column (which would require fake events to
-// alter the shift state).
-
-static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col)
-{
-  register int i, j;
-
-  j = *col;
-  for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
-    if (KeyCodetoKeySym(keymap, i, j) == ks)
-      return i;
-  }
-
-  for (j = 0; j < keymap->mapWidth; j++) {
-    for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
-      if (KeyCodetoKeySym(keymap, i, j) == ks) {
-        *col = j;
-        return i;
-      }
-    }
-  }
-  return 0;
-}
-
-/* Fairly standard US PC Keyboard */
-
-#define VFB_MIN_KEY 8
-#define VFB_MAX_KEY 255
-#define VFB_MAP_LEN (VFB_MAX_KEY - VFB_MIN_KEY + 1)
-#define KEYSYMS_PER_KEY 2
-KeySym keyboardMap[VFB_MAP_LEN * KEYSYMS_PER_KEY] = {
-  NoSymbol, NoSymbol,
-  XK_Escape, NoSymbol,
-  XK_1, XK_exclam,
-  XK_2, XK_at,
-  XK_3, XK_numbersign,
-  XK_4, XK_dollar,
-  XK_5, XK_percent,
-  XK_6, XK_asciicircum,
-  XK_7, XK_ampersand,
-  XK_8, XK_asterisk,
-  XK_9, XK_parenleft,
-  XK_0, XK_parenright,
-  XK_minus, XK_underscore,
-  XK_equal, XK_plus,
-  XK_BackSpace, NoSymbol,
-  XK_Tab, NoSymbol,
-  XK_q, XK_Q,
-  XK_w, XK_W,
-  XK_e, XK_E,
-  XK_r, XK_R,
-  XK_t, XK_T,
-  XK_y, XK_Y,
-  XK_u, XK_U,
-  XK_i, XK_I,
-  XK_o, XK_O,
-  XK_p, XK_P,
-  XK_bracketleft, XK_braceleft,
-  XK_bracketright, XK_braceright,
-  XK_Return, NoSymbol,
-  XK_Control_L, NoSymbol,
-  XK_a, XK_A,
-  XK_s, XK_S,
-  XK_d, XK_D,
-  XK_f, XK_F,
-  XK_g, XK_G,
-  XK_h, XK_H,
-  XK_j, XK_J,
-  XK_k, XK_K,
-  XK_l, XK_L,
-  XK_semicolon, XK_colon,
-  XK_apostrophe, XK_quotedbl,
-  XK_grave, XK_asciitilde,
-  XK_Shift_L, NoSymbol,
-  XK_backslash, XK_bar,
-  XK_z, XK_Z,
-  XK_x, XK_X,
-  XK_c, XK_C,
-  XK_v, XK_V,
-  XK_b, XK_B,
-  XK_n, XK_N,
-  XK_m, XK_M,
-  XK_comma, XK_less,
-  XK_period, XK_greater,
-  XK_slash, XK_question,
-  XK_Shift_R, NoSymbol,
-  XK_KP_Multiply, NoSymbol,
-  XK_Alt_L, XK_Meta_L,
-  XK_space, NoSymbol,
-  /*XK_Caps_Lock*/ NoSymbol, NoSymbol,
-  XK_F1, NoSymbol,
-  XK_F2, NoSymbol,
-  XK_F3, NoSymbol,
-  XK_F4, NoSymbol,
-  XK_F5, NoSymbol,
-  XK_F6, NoSymbol,
-  XK_F7, NoSymbol,
-  XK_F8, NoSymbol,
-  XK_F9, NoSymbol,
-  XK_F10, NoSymbol,
-  XK_Num_Lock, XK_Pointer_EnableKeys,
-  XK_Scroll_Lock, NoSymbol,
-  XK_KP_Home, XK_KP_7,
-  XK_KP_Up, XK_KP_8,
-  XK_KP_Prior, XK_KP_9,
-  XK_KP_Subtract, NoSymbol,
-  XK_KP_Left, XK_KP_4,
-  XK_KP_Begin, XK_KP_5,
-  XK_KP_Right, XK_KP_6,
-  XK_KP_Add, NoSymbol,
-  XK_KP_End, XK_KP_1,
-  XK_KP_Down, XK_KP_2,
-  XK_KP_Next, XK_KP_3,
-  XK_KP_Insert, XK_KP_0,
-  XK_KP_Delete, XK_KP_Decimal,
-  NoSymbol, NoSymbol,
-  NoSymbol, NoSymbol,
-  NoSymbol, NoSymbol,
-  XK_F11, NoSymbol,
-  XK_F12, NoSymbol,
-  XK_Home, NoSymbol,
-  XK_Up, NoSymbol,
-  XK_Prior, NoSymbol,
-  XK_Left, NoSymbol,
-  NoSymbol, NoSymbol,
-  XK_Right, NoSymbol,
-  XK_End, NoSymbol,
-  XK_Down, NoSymbol,
-  XK_Next, NoSymbol,
-  XK_Insert, NoSymbol,
-  XK_Delete, NoSymbol,
-  XK_KP_Enter, NoSymbol,
-  XK_Control_R, NoSymbol,
-  XK_Pause, XK_Break,
-  XK_Print, XK_Execute,
-  XK_KP_Divide, NoSymbol,
-  XK_Alt_R, XK_Meta_R,
-};
-
-static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
-{
-  int i;
-
-  for (i = 0; i < MAP_LENGTH; i++)
-    pModMap[i] = NoSymbol;
-
-  for (i = 0; i < VFB_MAP_LEN; i++) {
-    if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
-      pModMap[i + VFB_MIN_KEY] = LockMask;
-    else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
-             keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
-      pModMap[i + VFB_MIN_KEY] = ShiftMask;
-    else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
-             keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R) {
-      pModMap[i + VFB_MIN_KEY] = ControlMask;
-    }
-    else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
-             keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
-      pModMap[i + VFB_MIN_KEY] = Mod1Mask;
-  }
-
-  pKeySyms->minKeyCode = VFB_MIN_KEY;
-  pKeySyms->maxKeyCode = VFB_MAX_KEY;
-  pKeySyms->mapWidth = KEYSYMS_PER_KEY;
-  pKeySyms->map = keyboardMap;
-
-  return TRUE;
-}
-
-static void vfbBell(int percent, DeviceIntPtr device, pointer ctrl, int class_)
-{
-  if (percent > 0)
-    vncBell();
-}
-
-static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff)
-{
-  KeySymsRec            keySyms;
-  CARD8                 modMap[MAP_LENGTH];
-  DevicePtr pDev = (DevicePtr)pDevice;
-#ifdef XKB
-  XkbComponentNamesRec names;
-#endif
-
-  switch (onoff)
-  {
-  case DEVICE_INIT:
-    GetMappings(&keySyms, modMap);
-#ifdef XKB
-    if (!noXkbExtension) {
-      memset(&names, 0, sizeof (names));
-      XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
-      XkbInitKeyboardDeviceStruct(pDevice, &names, &keySyms, modMap,
-				  (BellProcPtr)vfbBell,
-				  (KbdCtrlProcPtr)NoopDDA);
-    } else
-#endif
-    {
-      InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
-			      (BellProcPtr)vfbBell, (KbdCtrlProcPtr)NoopDDA);
-    }
-    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 3886)
+++ unix/xserver/hw/vnc/XserverDesktop.h	(revision 3887)
@@ -123,6 +123,7 @@
   void deferUpdate();
   ScreenPtr pScreen;
   PointerDevice *pointerDevice;
+  KeyboardDevice *keyboardDevice;
   OsTimerPtr deferredUpdateTimer, dummyTimer;
   rfb::VNCServerST* server;
   rfb::HTTPServer* httpServer;

tigervnc11-r3924-rh541559.patch:
 Input.cc |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

--- NEW FILE tigervnc11-r3924-rh541559.patch ---
Index: unix/xserver/hw/vnc/Input.cc
===================================================================
--- unix/xserver/hw/vnc/Input.cc	(revision 3923)
+++ unix/xserver/hw/vnc/Input.cc	(revision 3924)
@@ -373,6 +373,14 @@
 	unsigned int i, n;
 	int j, k, action;
 
+	/* 
+	 * Since we are checking the current state to determine if we need
+	 * to fake modifiers, we must make sure that everything put on the
+	 * input queue is processed before we start. Otherwise, shift may be
+	 * stuck down.
+	 */ 
+	mieqProcessInputEvents();
+
 	if (keysym == XK_Caps_Lock) {
 		vlog.debug("Ignoring caps lock");
 		return;
@@ -506,6 +514,15 @@
 	action = down ? KeyPress : KeyRelease;
 	n = GetKeyboardEvents(eventq, dev, action, kc);
 	enqueueEvents(dev, n);
+	
+	/*
+	 * When faking a modifier we are putting a keycode (which can
+	 * currently activate the desired modifier) on the input
+	 * queue. A future modmap change can change the mapping so
+	 * that this keycode means something else entirely. Guard
+	 * against this by processing the queue now.
+	 */
+	mieqProcessInputEvents();
 }
 
 static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col)

tigervnc11-r3926.patch:
 README          |    4 +-
 xserver17.patch |   83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 2 deletions(-)

--- NEW FILE tigervnc11-r3926.patch ---
Index: unix/README
===================================================================
--- unix/README	(revision 3925)
+++ unix/README	(revision 3926)
@@ -97,8 +97,8 @@
   % cd <path_to_tigervnc_source>/unix/xserver
   % patch -p1 < ../xserver15.patch
 
-- note: you can use server-1.6-branch. Simply checkout it as written above
-  and use xserver16.patch
+- note: you can use server-1.X-branch. Simply checkout it as written above
+  and use xserver1X.patch
 
 After that you have to regenerate configure script and Makefile.in:
 
Index: unix/xserver17.patch
===================================================================
--- unix/xserver17.patch	(revision 0)
+++ unix/xserver17.patch	(revision 3926)
@@ -0,0 +1,83 @@
+--- xserver/configure.ac.vnc	2009-12-16 18:53:17.208009726 +0000
++++ xserver/configure.ac	2009-12-16 19:00:56.624009167 +0000
+@@ -30,7 +30,6 @@ AC_INIT([xorg-server], 1.7.3.901, [https
+ RELEASE_DATE="2009-12-11"
+ AC_CONFIG_SRCDIR([Makefile.am])
+ AM_INIT_AUTOMAKE([dist-bzip2 foreign])
+-AM_MAINTAINER_MODE
+ 
+ AC_CONFIG_FILES([
+ 	shave
+@@ -64,6 +63,7 @@ dnl forcing an entire recompile.x
+ AC_CONFIG_HEADERS(include/version-config.h)
+ 
+ AC_PROG_CC
++AC_PROG_CXX
+ AM_PROG_AS
+ AC_PROG_INSTALL
+ AC_PROG_LN_S
+@@ -1383,6 +1383,9 @@ if test "x$XVFB" = xyes; then
+ 	AC_SUBST([XVFB_SYS_LIBS])
+ fi
+ 
++dnl Xvnc DDX
++AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XEXT_INC $FB_INC $MI_INC $RENDER_INC $RANDR_INC"])
++AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+ 
+ dnl Xnest DDX
+ 
+@@ -1421,6 +1424,8 @@ xorg_bus_linuxpci=no
+ xorg_bus_bsdpci=no
+ xorg_bus_sparc=no
+ 
++AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
++
+ if test "x$XORG" = xyes; then
+ 	XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
+ 	XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
+@@ -1649,7 +1654,6 @@ if test "x$XORG" = xyes; then
+ 	AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
+ 	AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
+ 	AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
+-	AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+ 	AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
+ 	AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
+ 	AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
+@@ -2094,6 +2098,7 @@ hw/dmx/input/Makefile
+ hw/dmx/glxProxy/Makefile
+ hw/dmx/Makefile
+ hw/vfb/Makefile
++hw/vnc/Makefile
+ hw/xnest/Makefile
+ hw/xwin/Makefile
+ hw/xquartz/Makefile
+--- xserver/mi/miinitext.c.vnc	2009-12-16 18:53:20.864010515 +0000
++++ xserver/mi/miinitext.c	2009-12-16 19:01:23.664009203 +0000
+@@ -274,6 +274,7 @@ extern void DamageExtensionInit(INITARGS
+ extern void CompositeExtensionInit(INITARGS);
+ #endif
+ extern void GEExtensionInit(INITARGS);
++extern void vncExtensionInit(INITARGS);
+ 
+ /* The following is only a small first step towards run-time
+  * configurable extensions.
+@@ -454,6 +455,7 @@ InitExtensions(int argc, char *argv[])
+ #ifdef XF86BIGFONT
+     if (!noXFree86BigfontExtension) XFree86BigfontExtensionInit();
+ #endif
++    vncExtensionInit();
+ #if !defined(NO_HW_ONLY_EXTS)
+ #if defined(XF86VIDMODE)
+     if (!noXFree86VidModeExtension) XFree86VidModeExtensionInit();
+--- xserver/hw/Makefile.am.vnc	2009-12-16 18:53:17.816009029 +0000
++++ xserver/hw/Makefile.am	2009-12-16 19:01:31.064009345 +0000
+@@ -33,7 +33,8 @@ SUBDIRS =			\
+ 	$(XNEST_SUBDIRS)	\
+ 	$(DMX_SUBDIRS)		\
+ 	$(KDRIVE_SUBDIRS)	\
+-	$(XQUARTZ_SUBDIRS)
++	$(XQUARTZ_SUBDIRS)	\
++	vnc
+ 
+ DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive
+ 

tigervnc11-r3927.patch:
 Input.cc          |  210 +++++++++++++++++++++++++++++++++++++++++++++---------
 XserverDesktop.cc |    7 +
 xorg-version.h    |    6 +
 xvnc.cc           |    6 +
 4 files changed, 195 insertions(+), 34 deletions(-)

--- NEW FILE tigervnc11-r3927.patch ---
Index: unix/xserver/hw/vnc/xvnc.cc
===================================================================
--- unix/xserver/hw/vnc/xvnc.cc	(revision 3926)
+++ unix/xserver/hw/vnc/xvnc.cc	(revision 3927)
@@ -81,6 +81,12 @@
 #endif /* RANDR */
 #include <X11/keysym.h>
   extern char buildtime[];
+#if XORG >= 17
+#undef VENDOR_RELEASE
+#undef VENDOR_STRING
+#include "version-config.h"
+#include "site.h"
+#endif
 #undef class
 #undef public
 }
Index: unix/xserver/hw/vnc/Input.cc
===================================================================
--- unix/xserver/hw/vnc/Input.cc	(revision 3926)
+++ unix/xserver/hw/vnc/Input.cc	(revision 3927)
@@ -43,9 +43,17 @@
 #endif
 #if XORG >= 16
 #include "exevents.h"
+#endif
+#if XORG == 16
 extern void
 CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
 #endif
+#if XORG >= 17
+#include "xkbsrv.h"
+#include "xkbstr.h"
+#include "xserver-properties.h"
+extern _X_EXPORT DevPrivateKey CoreDevicePrivateKey;
+#endif
 #include <X11/keysym.h>
 #include <X11/Xutil.h>
 #undef public
@@ -99,8 +107,10 @@
 		mieqEnqueue(dev,
 #if XORG == 15
 			    eventq + i
+#elif XORG == 16
+			    (eventq + i)->event
 #else
-			    (eventq + i)->event
+			    (InternalEvent *) (eventq + i)->event
 #endif
 			   );
 	}
@@ -169,18 +179,43 @@
 	BYTE map[BUTTONS + 1];
 	DevicePtr pDev = (DevicePtr)pDevice;
 	int i;
+#if XORG >= 17
+	/*
+	 * NOTE: map[] array is one element longer than btn_labels[] array. This
+	 * is not a bug.
+	 */
+	Atom btn_labels[BUTTONS];
+	Atom axes_labels[2];
+#endif
 
 	switch (onoff) {
 	case DEVICE_INIT:
 		for (i = 0; i < BUTTONS + 1; i++)
 			map[i] = i;
 
+#if XORG >= 17
+		btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+		btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+		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);
+
+		axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+		axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+#endif
+
 		InitPointerDeviceStruct(pDev, map, BUTTONS,
 #if XORG == 15
 					GetMotionHistory,
+#elif XORG >= 17
+					btn_labels,
 #endif
 					(PtrCtrlProcPtr)NoopDDA,
-					GetMotionHistorySize(), 2);
+					GetMotionHistorySize(), 2
+#if XORG >= 17
+					, axes_labels
+#endif
+					);
 		break;
 	case DEVICE_ON:
 		pDev->on = TRUE;
@@ -239,33 +274,84 @@
 
 	void press()
 	{
+		int state, index, maxKeysPerMod, keycode;
+#if XORG >= 17
+		int ret;
+		KeyCode *modmap = NULL;
+
+		state = XkbStateFieldFromRec(&dev->u.master->key->xkbInfo->state);
+#else
 		KeyClassPtr keyc = dev->key;
-		if (!(keyc->state & (1 << modIndex))) {
-			int index = modIndex * keyc->maxKeysPerModifier;
-			tempKeyEvent(keyc->modifierKeyMap[index], true);
-			pressed = true;
+		state = keyc->state;
+#endif
+		if ((state & (1 << modIndex)) != 0)
+			return;
+
+#if XORG >= 17
+		if (generate_modkeymap(serverClient, dev, &modmap,
+				       &maxKeysPerMod) != Success) {
+			vlog.error("generate_modkeymap failed");
+			return;
 		}
+
+		keycode = modmap[modIndex * maxKeysPerMod];
+		xfree(modmap);
+#else
+		maxKeysPerMod = keyc->maxKeysPerModifier;
+		keycode = keyc->modifierKeyMap[modIndex * maxKeysPerMod];
+#endif
+		tempKeyEvent(keycode, true, maxKeysPerMod);
+		pressed = true;
 	}
 
 	void release()
 	{
-		KeyClassPtr keyc = dev->key;
-		if ((keyc->state & (1 << modIndex)) == 0)
+		int state, maxKeysPerMod;
+		KeyClassPtr keyc;
+#if XORG >= 17
+		int ret;
+		KeyCode *modmap = NULL;
+
+		keyc = dev->u.master->key;
+		state = XkbStateFieldFromRec(&keyc->xkbInfo->state);
+#else
+		keyc = dev->key;
+		state = keyc->state;
+#endif
+		if ((state & (1 << modIndex)) == 0)
 			return;
 
-		for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
-			int index = modIndex * keyc->maxKeysPerModifier + k;
-			int keycode = keyc->modifierKeyMap[index];
+#if XORG >= 17
+		if (generate_modkeymap(serverClient, dev, &modmap,
+				       &maxKeysPerMod) != Success) {
+			vlog.error("generate_modkeymap failed");
+			return;
+		}
+#else
+		maxKeysPerMod = keyc->maxKeysPerModifier;
+#endif
+
+		for (int k = 0; k < maxKeysPerMod; k++) {
+			int keycode;
+			int index = modIndex * maxKeysPerMod + k;
+#if XORG >= 17
+			keycode = modmap[index];
+#else
+			keycode = keyc->modifierKeyMap[index];
+#endif
 			if (keycode && IS_PRESSED(keyc, keycode))
-				tempKeyEvent(keycode, false);
+				tempKeyEvent(keycode, false, maxKeysPerMod);
 		}
+#if XORG >= 17
+		xfree(modmap);
+#endif
 	}
 
 private:
-	void tempKeyEvent(int keycode, bool down)
+	void tempKeyEvent(int keycode, bool down, int maxKeysPerMod)
 	{
 		if (keycode) {
-			if (!keys) keys = new int[dev->key->maxKeysPerModifier];
+			if (!keys) keys = new int[maxKeysPerMod];
 			keys[nKeys++] = keycode;
 			generateXKeyEvent(keycode, down);
 		}
@@ -361,17 +447,28 @@
  *   synchronized with proper master device
  */
 
+#if XORG >= 17
+#define FREE_MAPS \
+	do { \
+	        xfree(modmap); \
+	        xfree(keymap->map); \
+	        xfree(keymap); \
+	} while (0);
+#else
+#define FREE_MAPS
+#endif
+
 void KeyboardDevice::keyEvent(rdr::U32 keysym, bool down)
 {
 	DeviceIntPtr master;
-	KeyClassPtr keyc = dev->key;
-	KeySymsPtr keymap = &keyc->curKeySyms;
-	KeySym *map = keymap->map;
-	KeyCode minKeyCode = keymap->minKeyCode;
-	KeyCode maxKeyCode = keymap->maxKeyCode;
-	int mapWidth = keymap->mapWidth;
+	KeyClassPtr keyc;
+	KeySymsPtr keymap = NULL;
+	KeySym *map = NULL;
+	KeyCode minKeyCode, maxKeyCode;
+	KeyCode *modmap = NULL;
+	int mapWidth;
 	unsigned int i, n;
-	int j, k, action;
+	int j, k, action, state, maxKeysPerMod;
 
 	/* 
 	 * Since we are checking the current state to determine if we need
@@ -385,13 +482,43 @@
 		vlog.debug("Ignoring caps lock");
 		return;
 	}
+vlog.debug("keysym %d", keysym);
+#if XORG >= 17
+	keyc = dev->u.master->key;
 
+	keymap = XkbGetCoreMap(dev);
+	if (!keymap) {
+		vlog.error("VNC keyboard device has no map");
+		return;
+	}
+
+	if (generate_modkeymap(serverClient, dev, &modmap, &maxKeysPerMod)
+	    != Success) {
+		vlog.error("generate_modkeymap failed");
+		xfree(keymap->map);
+		xfree(keymap);
+		return;
+	}
+
+	state = XkbStateFieldFromRec(&keyc->xkbInfo->state);
+#else
+	keyc = dev->key;
+	state = keyc->state;
+	maxKeysPerMod = keyc->maxKeysPerModifier;
+	keymap = &keyc->curKeySyms;
+	modmap = keyc->modifierKeyMap;
+#endif
+	map = keymap->map;
+	minKeyCode = keymap->minKeyCode;
+	maxKeyCode = keymap->maxKeyCode;
+	mapWidth = keymap->mapWidth;
+
 	/* find which modifier Mode_switch is on. */
 	int modeSwitchMapIndex = 0;
 	for (i = 3; i < 8; i++) {
-		for (k = 0; k < keyc->maxKeysPerModifier; k++) {
-			int index = i * keyc->maxKeysPerModifier + k;
-			int keycode = keyc->modifierKeyMap[index];
+		for (k = 0; k < maxKeysPerMod; k++) {
+			int index = i * maxKeysPerMod + k;
+			int keycode = modmap[index];
 
 			if (keycode == 0)
 				continue;
@@ -408,10 +535,10 @@
 ModeSwitchFound:
 
 	int col = 0;
-	if ((keyc->state & (1 << ShiftMapIndex)) != 0)
+	if ((state & (1 << ShiftMapIndex)) != 0)
 		col |= 1;
 	if (modeSwitchMapIndex != 0 &&
-	    ((keyc->state & (1 << modeSwitchMapIndex))) != 0)
+	    ((state & (1 << modeSwitchMapIndex))) != 0)
 		col |= 2;
 
 	int kc = KeysymToKeycode(keymap, keysym, &col);
@@ -424,7 +551,7 @@
 	 * We never get ISO_Left_Tab here because it's already been translated
 	 * in VNCSConnectionST.
 	 */
-	if (keysym == XK_Tab && ((keyc->state & (1 << ShiftMapIndex))) != 0)
+	if (keysym == XK_Tab && ((state & (1 << ShiftMapIndex))) != 0)
 		col |= 1;
 
 	if (kc == 0) {
@@ -455,6 +582,8 @@
 
 			vlog.info("Added unknown keysym 0x%x to keycode %d",
 				  keysym, kc);
+
+#if XORG < 17
 #if XORG == 15
 			master = inputInfo.keyboard;
 #else
@@ -471,6 +600,12 @@
 				CopyKeyClass(dev, master);
 #endif
 			}
+#else /* XORG < 17 */
+			XkbApplyMappingChange(dev, keymap, minKeyCode,
+					      maxKeyCode - minKeyCode + 1,
+					      NULL, serverClient);
+			XkbCopyDeviceKeymap(dev->u.master, dev);
+#endif /* XORG < 17 */
 			break;
 		}
 	}
@@ -478,6 +613,7 @@
 	if (kc < minKeyCode) {
 		vlog.info("Keyboard mapping full - ignoring unknown keysym "
 			  "0x%x",keysym);
+		FREE_MAPS;
 		return;
 	}
 
@@ -487,11 +623,12 @@
 	 * followed by a press.
 	 */
 	for (i = 0; i < 8; i++) {
-		for (k = 0; k < keyc->maxKeysPerModifier; k++) {
-			int index = i * keyc->maxKeysPerModifier + k;
-			if (kc == keyc->modifierKeyMap[index] &&
-			    IS_PRESSED(keyc,kc) && down)
+		for (k = 0; k < maxKeysPerMod; k++) {
+			int index = i * maxKeysPerMod + k;
+			if (kc == modmap[index] && IS_PRESSED(keyc,kc) && down) {
+				FREE_MAPS;
 				return;
+			}	
 		}
 	}
 
@@ -761,9 +898,16 @@
 
 	switch (onoff) {
 	case DEVICE_INIT:
+#if XORG < 17
 		GetMappings(&keySyms, modMap);
-		InitKeyboardDeviceStruct(pDev, &keySyms, modMap, keyboardBell,
-					 (KbdCtrlProcPtr)NoopDDA);
+#endif
+		InitKeyboardDeviceStruct(
+#if XORG >= 17
+					 pDevice, NULL,
+#else
+					 pDev, &keySyms, modMap,
+#endif
+					 keyboardBell, (KbdCtrlProcPtr)NoopDDA);
 		break;
 	case DEVICE_ON:
 		pDev->on = TRUE;
Index: unix/xserver/hw/vnc/xorg-version.h
===================================================================
--- unix/xserver/hw/vnc/xorg-version.h	(revision 3926)
+++ unix/xserver/hw/vnc/xorg-version.h	(revision 3927)
@@ -26,8 +26,12 @@
 
 #if XORG_VERSION_CURRENT < ((1 * 10000000) + (5 * 100000) + (99 * 1000))
 #define XORG 15
+#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (6 * 100000) + (99 * 1000))
+#define XORG 16
+#elif XORG_VERSION_CURRENT < ((1 * 10000000) + (7 * 100000) + (99 * 1000))
+#define XORG 17
 #else
-#define XORG 16
+#error "X.Org newer than 1.7 is not supported"
 #endif
 
 #endif
Index: unix/xserver/hw/vnc/XserverDesktop.cc
===================================================================
--- unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3926)
+++ unix/xserver/hw/vnc/XserverDesktop.cc	(revision 3927)
@@ -54,6 +54,10 @@
 #ifdef RANDR
 #include "randrstr.h"
 #endif
+#if XORG >= 17
+#include "cursorstr.h"
+#endif
+
 #undef public
 #undef class
 }
@@ -185,6 +189,9 @@
   int i;
   pointer retval;
 
+#if XORG >= 17
+#define dixLookupResource dixLookupResourceByType
+#endif
   i = dixLookupResource(&retval, pScreen->defColormap, RT_COLORMAP, NullClient,
 			DixReadAccess);
 

tigervnc11-r3932.patch:
 Input.cc |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE tigervnc11-r3932.patch ---
Index: unix/xserver/hw/vnc/Input.cc
===================================================================
--- unix/xserver/hw/vnc/Input.cc	(revision 3931)
+++ unix/xserver/hw/vnc/Input.cc	(revision 3932)
@@ -482,7 +482,7 @@
 		vlog.debug("Ignoring caps lock");
 		return;
 	}
-vlog.debug("keysym %d", keysym);
+
 #if XORG >= 17
 	keyc = dev->u.master->key;
 

tigervnc11-r4007.patch:
 LINGUAS |    2 
 fr.po   |  195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 196 insertions(+), 1 deletion(-)

--- NEW FILE tigervnc11-r4007.patch ---
Index: po/fr.po
===================================================================
--- po/fr.po	(revision 0)
+++ po/fr.po	(revision 4007)
@@ -0,0 +1,195 @@
+# Copyright (C) YEAR RealVNC Ltd, Constantin Kaplinsky, Peter Astrand, Cendio AB
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Alain Portal <alain.portal at free.fr>, 2010.
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: tigervnc-devel at lists.sourceforge.net\n"
+"POT-Creation-Date: 2009-06-12 12:18+0200\n"
+"PO-Revision-Date: 2010-03-13 09:47+0100\n"
+"Last-Translator: Alain Portal <alain.portal at free.fr>\n"
+"Language-Team: French <kde-francophone at kde.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Lokalize 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgid "About VNC Viewer"
+msgstr "À propos du visionneur VNC"
+
+msgid "VNC authentication"
+msgstr "Authentification VNC"
+
+#, c-format
+msgid "TigerVNC: %.240s"
+msgstr "TigerVNC : %.240s"
+
+msgid "Exit viewer"
+msgstr "Quitte le visionneur"
+
+msgid "Full screen"
+msgstr "Plein écran"
+
+msgid "Ctrl"
+msgstr "Ctrl"
+
+msgid "Alt"
+msgstr "Alt"
+
+#, c-format
+msgid "Send %s"
+msgstr "Envoi de %s"
+
+msgid "Send Ctrl-Alt-Del"
+msgstr "Envoyer Ctrl-Alt-Sup"
+
+msgid "Refresh screen"
+msgstr "Rafraîchir l'écran"
+
+msgid "New connection..."
+msgstr "Nouvelle connexion..."
+
+msgid "Options..."
+msgstr "Options..."
+
+msgid "Connection info..."
+msgstr "Informations de la connexion..."
+
+msgid "About VNCviewer..."
+msgstr "À propos de VNCviewer..."
+
+msgid "Dismiss menu"
+msgstr "Rejeter le menu"
+
+msgid "VNC Menu"
+msgstr "Menu VNC"
+
+#, c-format
+msgid ""
+"Desktop name: %.80s\n"
+"Host: %.80s port: %d\n"
+"Size: %d x %d\n"
+"Pixel format: %s\n"
+"(server default %s)\n"
+"Requested encoding: %s\n"
+"Last used encoding: %s\n"
+"Line speed estimate: %d kbit/s\n"
+"Protocol version: %d.%d\n"
+"Security method: %s\n"
+msgstr ""
+"Nom du bureau : %.80s\n"
+"Hôte : %.80s port : %d\n"
+"Taille : %d x %d\n"
+"Format des pixels : %s\n"
+"(Valeur du serveur par défaut %s)\n"
+"Jeu de caractères demandé : %s\n"
+"Dernier jeu de caractères utilisé : %s\n"
+"Estimation du débit : %d kbit/s\n"
+"Version du protocole : %d.%d\n"
+"Méthode de sécurité : %s\n"
+
+msgid "VNC connection info"
+msgstr "Informations de la connexion VNC"
+
+msgid "VNC Viewer: Connection Options"
+msgstr "Visionneur VNC : options de la connexion"
+
+msgid "Encoding and Color Level:"
+msgstr "Jeu de caractères et niveau de couleurs :"
+
+msgid "Inputs:"
+msgstr "Entrée :"
+
+msgid "Misc:"
+msgstr "Divers :"
+
+msgid "Auto select"
+msgstr "Sélection automatique"
+
+msgid "Full (all available colors)"
+msgstr "Complet (toutes les couleurs disponibles)"
+
+msgid "Medium (256 colors)"
+msgstr "Moyen (256 couleurs)"
+
+msgid "Low (64 colors)"
+msgstr "Faible (64 couleurs)"
+
+msgid "Very low (8 colors)"
+msgstr "Très faible (8 couleurs)"
+
+msgid "Custom compression level:"
+msgstr "Niveau de compression personnalisé :"
+
+msgid "level (1=fast, 9=best)"
+msgstr "niveau (1=rapide, 9=le meilleur)"
+
+msgid "Allow JPEG compression:"
+msgstr "Autoriser la compression JPEG :"
+
+msgid "quality (1=poor, 9=best)"
+msgstr "qualité (1=pauvre, 9=la meilleure)"
+
+msgid "View only (ignore mouse & keyboard)"
+msgstr "Voir seulement (ignorer la souris et le clavier)"
+
+msgid "Accept clipboard from server"
+msgstr "Accepter le presse-papier du serveur"
+
+msgid "Send clipboard to server"
+msgstr "Envoyer le presse-papier au serveur"
+
+msgid "Send primary selection & cut buffer as clipboard"
+msgstr "Exporter les données vers le presse-papiers"
+
+msgid "Shared (don't disconnect other viewers)"
+msgstr "Partagé (ne pas déconnecter les autres visionneurs)"
+
+msgid "Full-screen mode"
+msgstr "Mode plein écran"
+
+msgid "Render cursor locally"
+msgstr "Restituer le curseur localement"
+
+msgid "Show dot when no cursor"
+msgstr "Afficher un point s'il n'y a pas de curseur"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Annuler"
+
+msgid "Username:"
+msgstr "Nom d'utilisateur :"
+
+msgid "Password:"
+msgstr "Mot de passe :"
+
+msgid "VNC Viewer: Connection Details"
+msgstr "Visionneur VNC : détails de la connection"
+
+msgid "VNC server:"
+msgstr "Serveur VNC :"
+
+msgid "About..."
+msgstr "À propos..."
+
+#, c-format
+msgid ""
+"TigerVNC Viewer for X version %s - built %s\n"
+"Copyright (C) 2002-2005 RealVNC Ltd.\n"
+"Copyright (C) 2000-2006 TightVNC Group\n"
+"Copyright (C) 2004-2009 Peter Astrand for Cendio AB\n"
+"See http://www.tigervnc.org for information on TigerVNC."
+msgstr ""
+"Visionneur TigerVNC pour la version %s du serveur X - Paquetage "
+"construit le « %s »\n"
+"Copyright (C) 2002-2005 RealVNC Ltd.\n"
+"Copyright (C) 2000-2006 TightVNC Group\n"
+"Copyright (C) 2004-2009 Peter Astrand pour Cendio AB\n"
+"Voir http://www.tigervnc.org pour plus d'informations sur TigerVNC."
+
+
Index: po/LINGUAS
===================================================================
--- po/LINGUAS	(revision 4006)
+++ po/LINGUAS	(revision 4007)
@@ -1 +1 @@
-de pl sk sv
+de fr pl sk sv

tigervnc11-r4008.patch:
 OptionsDialog.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE tigervnc11-r4008.patch ---
Index: unix/vncviewer/OptionsDialog.h
===================================================================
--- unix/vncviewer/OptionsDialog.h	(revision 4007)
+++ unix/vncviewer/OptionsDialog.h	(revision 4008)
@@ -39,7 +39,7 @@
                       public TXCheckboxCallback, public TXEntryCallback  {
 public:
   OptionsDialog(Display* dpy, OptionsDialogCallback* cb_)
-    : TXDialog(dpy, 400, 450, _("VNC Viewer: Connection Options")), cb(cb_),
+    : TXDialog(dpy, 450, 450, _("VNC Viewer: Connection Options")), cb(cb_),
       formatAndEnc(dpy, _("Encoding and Color Level:"), this),
       inputs(dpy, _("Inputs:"), this),
       misc(dpy, _("Misc:"), this),

tigervnc11-r4024.patch:
 Input.cc          |   79 ++++++++++++++++++++++++------------------------------
 Input.h           |   40 +++++++++++----------------
 XserverDesktop.cc |   16 ++++------
 XserverDesktop.h  |    4 --
 4 files changed, 61 insertions(+), 78 deletions(-)

--- NEW FILE tigervnc11-r4024.patch ---
>From f058349ae6b31424751ea6b3d773bb5d6dae07d5 Mon Sep 17 00:00:00 2001
From: Adam Tkac <atkac at redhat.com>
Date: Wed, 10 Mar 2010 17:38:52 +0100
Subject: [PATCH 1/2] Merge KeyboardDevice and PointerDevice classes.

---
 unix/xserver/hw/vnc/Input.cc          |   79 +++++++++++++++------------------
 unix/xserver/hw/vnc/Input.h           |   40 +++++++----------
 unix/xserver/hw/vnc/XserverDesktop.cc |   16 +++----
 unix/xserver/hw/vnc/XserverDesktop.h  |    3 +-
 4 files changed, 61 insertions(+), 77 deletions(-)

diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc
index 0596c64..3b60a5f 100644
--- a/unix/xserver/hw/vnc/Input.cc
+++ b/unix/xserver/hw/vnc/Input.cc
@@ -116,21 +116,27 @@ static void enqueueEvents(DeviceIntPtr dev, int n)
 	}
 }
 
-/* Pointer device methods */
-
-PointerDevice::PointerDevice(rfb::VNCServerST *_server)
+InputDevice::InputDevice(rfb::VNCServerST *_server)
 	: server(_server), oldButtonMask(0)
 {
-	dev = AddInputDevice(
+	pointerDev = AddInputDevice(
+#if XORG >= 16
+				    serverClient,
+#endif
+				    pointerProc, TRUE);
+	RegisterPointerDevice(pointerDev);
+
+	keyboardDev = AddInputDevice(
 #if XORG >= 16
-			     serverClient,
+				     serverClient,
 #endif
-			     pointerProc, TRUE);
-	RegisterPointerDevice(dev);
+				     keyboardProc, TRUE);
+	RegisterKeyboardDevice(keyboardDev);
+
 	initEventq();
 }
 
-void PointerDevice::ButtonAction(int buttonMask)
+void InputDevice::PointerButtonAction(int buttonMask)
 {
 	int i, n;
 
@@ -138,9 +144,9 @@ void PointerDevice::ButtonAction(int buttonMask)
 		if ((buttonMask ^ oldButtonMask) & (1 << i)) {
 			int action = (buttonMask & (1<<i)) ?
 				     ButtonPress : ButtonRelease;
-			n = GetPointerEvents(eventq, dev, action, i + 1,
+			n = GetPointerEvents(eventq, pointerDev, action, i + 1,
 					     POINTER_RELATIVE, 0, 0, NULL);
-			enqueueEvents(dev, n);
+			enqueueEvents(pointerDev, n);
 
 		}
 	}
@@ -148,7 +154,7 @@ void PointerDevice::ButtonAction(int buttonMask)
 	oldButtonMask = buttonMask;
 }
 
-void PointerDevice::Move(const rfb::Point &pos)
+void InputDevice::PointerMove(const rfb::Point &pos)
 {
 	int n, valuators[2];
 
@@ -157,14 +163,14 @@ void PointerDevice::Move(const rfb::Point &pos)
 
 	valuators[0] = pos.x;
 	valuators[1] = pos.y;
-	n = GetPointerEvents(eventq, dev, MotionNotify, 0, POINTER_ABSOLUTE, 0,
+	n = GetPointerEvents(eventq, pointerDev, MotionNotify, 0, POINTER_ABSOLUTE, 0,
 			     2, valuators);
-	enqueueEvents(dev, n);
+	enqueueEvents(pointerDev, n);
 
 	cursorPos = pos;
 }
 
-void PointerDevice::Sync(void)
+void InputDevice::PointerSync(void)
 {
 	if (cursorPos.equals(oldCursorPos))
 		return;
@@ -232,19 +238,6 @@ static int pointerProc(DeviceIntPtr pDevice, int onoff)
 	return Success;
 }
 
-/* KeyboardDevice methods */
-
-KeyboardDevice::KeyboardDevice(void)
-{
-	dev = AddInputDevice(
-#if XORG >= 16
-			     serverClient,
-#endif
-			     keyboardProc, TRUE);
-	RegisterKeyboardDevice(dev);
-	initEventq();
-}
-
 #define IS_PRESSED(keyc, keycode) \
 	((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
 
@@ -458,7 +451,7 @@ static struct altKeysym_t {
 #define FREE_MAPS
 #endif
 
-void KeyboardDevice::keyEvent(rdr::U32 keysym, bool down)
+void InputDevice::keyEvent(rdr::U32 keysym, bool down)
 {
 	DeviceIntPtr master;
 	KeyClassPtr keyc;
@@ -484,16 +477,16 @@ void KeyboardDevice::keyEvent(rdr::U32 keysym, bool down)
 	}
 
 #if XORG >= 17
-	keyc = dev->u.master->key;
+	keyc = keyboardDev->u.master->key;
 
-	keymap = XkbGetCoreMap(dev);
+	keymap = XkbGetCoreMap(keyboardDev);
 	if (!keymap) {
 		vlog.error("VNC keyboard device has no map");
 		return;
 	}
 
-	if (generate_modkeymap(serverClient, dev, &modmap, &maxKeysPerMod)
-	    != Success) {
+	if (generate_modkeymap(serverClient, keyboardDev, &modmap,
+	    		       &maxKeysPerMod) != Success) {
 		vlog.error("generate_modkeymap failed");
 		xfree(keymap->map);
 		xfree(keymap);
@@ -502,7 +495,7 @@ void KeyboardDevice::keyEvent(rdr::U32 keysym, bool down)
 
 	state = XkbStateFieldFromRec(&keyc->xkbInfo->state);
 #else
-	keyc = dev->key;
+	keyc = keyboardDev->key;
 	state = keyc->state;
 	maxKeysPerMod = keyc->maxKeysPerModifier;
 	keymap = &keyc->curKeySyms;
@@ -587,24 +580,24 @@ ModeSwitchFound:
 #if XORG == 15
 			master = inputInfo.keyboard;
 #else
-			master = dev->u.master;
+			master = keyboardDev->u.master;
 #endif
 			void *slave = dixLookupPrivate(&master->devPrivates,
 						       CoreDevicePrivateKey);
-			if (dev == slave) {
+			if (keyboardDev == slave) {
 				dixSetPrivate(&master->devPrivates,
 					      CoreDevicePrivateKey, NULL);
 #if XORG == 15
-				SwitchCoreKeyboard(dev);
+				SwitchCoreKeyboard(keyboardDev);
 #else
-				CopyKeyClass(dev, master);
+				CopyKeyClass(keyboardDev, master);
 #endif
 			}
 #else /* XORG < 17 */
-			XkbApplyMappingChange(dev, keymap, minKeyCode,
+			XkbApplyMappingChange(keyboardDev, keymap, minKeyCode,
 					      maxKeyCode - minKeyCode + 1,
 					      NULL, serverClient);
-			XkbCopyDeviceKeymap(dev->u.master, dev);
+			XkbCopyDeviceKeymap(keyboardDev->u.master, keyboardDev);
 #endif /* XORG < 17 */
 			break;
 		}
@@ -632,8 +625,8 @@ ModeSwitchFound:
 		}
 	}
 
-	ModifierState shift(dev, ShiftMapIndex);
-	ModifierState modeSwitch(dev, modeSwitchMapIndex);
+	ModifierState shift(keyboardDev, ShiftMapIndex);
+	ModifierState modeSwitch(keyboardDev, modeSwitchMapIndex);
 	if (down) {
 		if (col & 1)
 			shift.press();
@@ -649,8 +642,8 @@ ModeSwitchFound:
 
 	vlog.debug("keycode %d %s", kc, down ? "down" : "up");
 	action = down ? KeyPress : KeyRelease;
-	n = GetKeyboardEvents(eventq, dev, action, kc);
-	enqueueEvents(dev, n);
+	n = GetKeyboardEvents(eventq, keyboardDev, action, kc);
+	enqueueEvents(keyboardDev, n);
 	
 	/*
 	 * When faking a modifier we are putting a keycode (which can
diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h
index 1bfec92..8987085 100644
--- a/unix/xserver/hw/vnc/Input.h
+++ b/unix/xserver/hw/vnc/Input.h
@@ -1,5 +1,6 @@
 /* Copyright (C) 2009 TightVNC Team
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009, 2010 Red Hat, Inc.
+ * Copyright (C) 2009, 2010 TigerVNC Team
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,44 +32,37 @@ extern "C" {
 #include "input.h"
 };
 
-/* Represents pointer device. */
-class PointerDevice {
+/* Represents input device (keyboard + pointer) */
+class InputDevice {
 public:
-	/* Create new PointerDevice instance. */
-	PointerDevice(rfb::VNCServerST *_server);
+	/* Create new InputDevice instance */
+	InputDevice(rfb::VNCServerST *_server);
 
 	/*
 	 * Press or release buttons. Relationship between buttonMask and
 	 * buttons is specified in RFB protocol.
 	 */
-	void ButtonAction(int buttonMask);
+	void PointerButtonAction(int buttonMask);
 
 	/* Move pointer to target location (point coords are absolute). */
-	void Move(const rfb::Point &point);
+	void PointerMove(const rfb::Point &point);
 
 	/*
 	 * Send pointer position to clients. If not called then Move() calls
-	 * won't be visible to clients.
+	 * won't be visible to VNC clients.
 	 */
-	void Sync(void);
+	void PointerSync(void);
+
+	void KeyboardPress(rdr::U32 keysym) { keyEvent(keysym, true); }
+	void KeyboardRelease(rdr::U32 keysym) { keyEvent(keysym, false); }
 private:
+	void keyEvent(rdr::U32 keysym, bool down);
+
 	rfb::VNCServerST *server;
-	DeviceIntPtr dev;
+	DeviceIntPtr keyboardDev;
+	DeviceIntPtr pointerDev;
 	int oldButtonMask;
 	rfb::Point cursorPos, oldCursorPos;
 };
 
-/* Represents keyboard device. */
-class KeyboardDevice {
-public:
-	/* Create new Keyboard device instance. */
-	KeyboardDevice(void);
-
-	void Press(rdr::U32 keysym) { keyEvent(keysym, true); }
-	void Release(rdr::U32 keysym) { keyEvent(keysym, false); }
-private:
-	void keyEvent(rdr::U32 keysym, bool down);
-	DeviceIntPtr dev;
-};
-
 #endif
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
index ce8f66b..5971077 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -164,8 +164,7 @@ XserverDesktop::XserverDesktop(ScreenPtr pScreen_,
   if (httpListener)
     httpServer = new FileHTTPServer(this);
 
-  pointerDevice = new PointerDevice(server);
-  keyboardDevice = new KeyboardDevice();
+  inputDevice = new InputDevice(server);
 }
 
 XserverDesktop::~XserverDesktop()
@@ -174,8 +173,7 @@ XserverDesktop::~XserverDesktop()
     delete [] data;
   TimerFree(deferredUpdateTimer);
   TimerFree(dummyTimer);
-  delete pointerDevice;
-  delete keyboardDevice;
+  delete inputDevice;
   delete httpServer;
   delete server;
 }
@@ -586,7 +584,7 @@ void XserverDesktop::wakeupHandler(fd_set* fds, int nfds)
         }
       }
 
-      pointerDevice->Sync();
+      inputDevice->PointerSync();
     }
 
     int timeout = server->checkTimeouts();
@@ -645,8 +643,8 @@ void XserverDesktop::approveConnection(void* opaqueId, bool accept,
 
 void XserverDesktop::pointerEvent(const Point& pos, int buttonMask)
 {
-  pointerDevice->Move(pos);
-  pointerDevice->ButtonAction(buttonMask);
+  inputDevice->PointerMove(pos);
+  inputDevice->PointerButtonAction(buttonMask);
 }
 
 void XserverDesktop::clientCutText(const char* str, int len)
@@ -807,7 +805,7 @@ void XserverDesktop::lookup(int index, int* r, int* g, int* b)
 void XserverDesktop::keyEvent(rdr::U32 keysym, bool down)
 {
 	if (down)
-		keyboardDevice->Press(keysym);
+		inputDevice->KeyboardPress(keysym);
 	else
-		keyboardDevice->Release(keysym);
+		inputDevice->KeyboardRelease(keysym);
 }
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
index 6e4f609..1c03705 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.h
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
@@ -122,8 +122,7 @@ private:
                                             pointer arg);
   void deferUpdate();
   ScreenPtr pScreen;
-  PointerDevice *pointerDevice;
-  KeyboardDevice *keyboardDevice;
+  InputDevice *inputDevice;
   OsTimerPtr deferredUpdateTimer, dummyTimer;
   rfb::VNCServerST* server;
   rfb::HTTPServer* httpServer;
-- 
1.7.0.1


tigervnc11-r4025.patch:
 Input.cc |   37 ++++++++++++++++++++++++++++++++++++-
 Input.h  |   11 ++++++++++-
 2 files changed, 46 insertions(+), 2 deletions(-)

--- NEW FILE tigervnc11-r4025.patch ---
>From d400267b6f170b82ba826d598df78e0f5519481c Mon Sep 17 00:00:00 2001
From: Adam Tkac <atkac at redhat.com>
Date: Wed, 14 Apr 2010 11:15:07 +0200
Subject: [PATCH 2/2] Use AllocDevicePair instead of AddDevice/RegisterDevice functions and initialize
 TigerVNC input devices after core devices initialization.

---
 unix/xserver/hw/vnc/Input.cc |   37 ++++++++++++++++++++++++++++++++++++-
 unix/xserver/hw/vnc/Input.h  |   10 ++++++++++
 2 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc
index 3b60a5f..d108763 100644
--- a/unix/xserver/hw/vnc/Input.cc
+++ b/unix/xserver/hw/vnc/Input.cc
@@ -119,6 +119,7 @@ static void enqueueEvents(DeviceIntPtr dev, int n)
 InputDevice::InputDevice(rfb::VNCServerST *_server)
 	: server(_server), oldButtonMask(0)
 {
+#if XORG < 17
 	pointerDev = AddInputDevice(
 #if XORG >= 16
 				    serverClient,
@@ -132,7 +133,7 @@ InputDevice::InputDevice(rfb::VNCServerST *_server)
 #endif
 				     keyboardProc, TRUE);
 	RegisterKeyboardDevice(keyboardDev);
-
+#endif
 	initEventq();
 }
 
@@ -140,6 +141,8 @@ void InputDevice::PointerButtonAction(int buttonMask)
 {
 	int i, n;
 
+	initInputDevice();
+
 	for (i = 0; i < BUTTONS; i++) {
 		if ((buttonMask ^ oldButtonMask) & (1 << i)) {
 			int action = (buttonMask & (1<<i)) ?
@@ -161,6 +164,8 @@ void InputDevice::PointerMove(const rfb::Point &pos)
 	if (pos.equals(cursorPos))
 		return;
 
+	initInputDevice();
+
 	valuators[0] = pos.x;
 	valuators[1] = pos.y;
 	n = GetPointerEvents(eventq, pointerDev, MotionNotify, 0, POINTER_ABSOLUTE, 0,
@@ -238,6 +243,34 @@ static int pointerProc(DeviceIntPtr pDevice, int onoff)
 	return Success;
 }
 
+void InputDevice::initInputDevice(void)
+{
+#if XORG >= 17
+	int ret;
+	static int initialized = 0;
+
+	if (initialized != 0)
+		return;
+
+	initialized = 1;
+
+	ret = AllocDevicePair(serverClient, "TigerVNC", &pointerDev,
+			      &keyboardDev, pointerProc, keyboardProc,
+			      FALSE);
+
+	if (ret != Success)
+		FatalError("Failed to initialize TigerVNC input devices\n");
+
+	if (ActivateDevice(pointerDev, TRUE) != Success ||
+	    ActivateDevice(keyboardDev, TRUE) != Success)
+		FatalError("Failed to activate TigerVNC devices\n");
+
+	if (!EnableDevice(pointerDev, TRUE) ||
+	    !EnableDevice(keyboardDev, TRUE))
+		FatalError("Failed to activate TigerVNC devices\n");
+#endif
+}
+
 #define IS_PRESSED(keyc, keycode) \
 	((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
 
@@ -463,6 +496,8 @@ void InputDevice::keyEvent(rdr::U32 keysym, bool down)
 	unsigned int i, n;
 	int j, k, action, state, maxKeysPerMod;
 
+	initInputDevice();
+
 	/* 
 	 * Since we are checking the current state to determine if we need
 	 * to fake modifiers, we must make sure that everything put on the
diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h
index 8987085..dbc78f8 100644
--- a/unix/xserver/hw/vnc/Input.h
+++ b/unix/xserver/hw/vnc/Input.h
@@ -56,6 +56,16 @@ public:
 	void KeyboardPress(rdr::U32 keysym) { keyEvent(keysym, true); }
 	void KeyboardRelease(rdr::U32 keysym) { keyEvent(keysym, false); }
 private:
+	/*
+	 * 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
+	 */
+	void initInputDevice(void);
+
 	void keyEvent(rdr::U32 keysym, bool down);
 
 	rfb::VNCServerST *server;
-- 
1.7.0.1



Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/tigervnc/F-12/.cvsignore,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -p -r1.9 -r1.10
--- .cvsignore	8 Oct 2009 13:39:32 -0000	1.9
+++ .cvsignore	14 Apr 2010 11:39:57 -0000	1.10
@@ -1,2 +1 @@
-tigervnc-1.0.0.tar.gz
-xorg-x11-server-source-1.6.4-0.3.fc11.x86_64.rpm
+tigervnc-1.0.1.tar.gz


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/tigervnc/F-12/sources,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -p -r1.9 -r1.10
--- sources	8 Oct 2009 13:39:32 -0000	1.9
+++ sources	14 Apr 2010 11:39:57 -0000	1.10
@@ -1,2 +1 @@
-622c6689a66651419b5431efdee99d5a  tigervnc-1.0.0.tar.gz
-bc5cb09b51297251c9f2e25e5719a735  xorg-x11-server-source-1.6.4-0.3.fc11.x86_64.rpm
+daca3eb16afe65253b766eccb8bfdbc5  tigervnc-1.0.1.tar.gz

tigervnc-cookie.patch:
 vncserver |   27 ++++++---------------------
 1 file changed, 6 insertions(+), 21 deletions(-)

Index: tigervnc-cookie.patch
===================================================================
RCS file: /cvs/pkgs/rpms/tigervnc/F-12/tigervnc-cookie.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- tigervnc-cookie.patch	3 Mar 2009 21:02:04 -0000	1.1
+++ tigervnc-cookie.patch	14 Apr 2010 11:39:57 -0000	1.2
@@ -1,19 +1,29 @@
---- vnc-4_1-unixsrc/unix/vncserver.cookie	2005-02-23 12:28:18.000000000 +0000
-+++ vnc-4_1-unixsrc/unix/vncserver	2005-03-03 22:04:28.000000000 +0000
-@@ -116,18 +116,12 @@
+diff -up tigervnc-1.0.90-20091221svn3929/unix/vncserver.cookie tigervnc-1.0.90-20091221svn3929/unix/vncserver
+--- tigervnc-1.0.90-20091221svn3929/unix/vncserver.cookie	2009-11-12 11:39:54.000000000 +0100
++++ tigervnc-1.0.90-20091221svn3929/unix/vncserver	2009-12-21 16:15:01.907799091 +0100
+@@ -189,27 +189,12 @@ $vncPort = 5900 + $displayNumber;
  $desktopLog = "$vncUserDir/$host:$displayNumber.log";
  unlink($desktopLog);
  
--# Make an X server cookie - use as the seed the sum of the current time, our
--# PID and part of the encrypted form of the password.  Ideally we'd use
--# /dev/urandom, but that's only available on Linux.
+-# Make an X server cookie - use /dev/urandom on systems that have it,
+-# otherwise use perl's random number generator, seeded with the sum
+-# of the current time, our PID and part of the encrypted form of the password.
 -
--srand(time+$$+unpack("L",`cat $vncUserDir/passwd`));
--$cookie = "";
--for (1..16) {
+-my $cookie = "";
+-if (open(URANDOM, '<', '/dev/urandom')) {
+-  my $randata;
+-  if (sysread(URANDOM, $randata, 16) == 16) {
+-    $cookie = unpack 'h*', $randata;
+-  }
+-  close(URANDOM);
+-}
+-if ($cookie eq "") {
+-  srand(time+$$+unpack("L",`cat $vncUserDir/passwd`));
+-  for (1..16) {
 -    $cookie .= sprintf("%02x", int(rand(256)) % 256);
+-  }
 -}
--    
+-
 -system("xauth -f $xauthorityFile add $host:$displayNumber . $cookie");
 -system("xauth -f $xauthorityFile add $host/unix:$displayNumber . $cookie"); 
 +# Make an X server cookie - use mcookie


Index: tigervnc.spec
===================================================================
RCS file: /cvs/pkgs/rpms/tigervnc/F-12/tigervnc.spec,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -p -r1.22 -r1.23
--- tigervnc.spec	26 Oct 2009 14:51:01 -0000	1.22
+++ tigervnc.spec	14 Apr 2010 11:39:57 -0000	1.23
@@ -1,6 +1,6 @@
 Name:		tigervnc
-Version:	1.0.0
-Release:	3%{?dist}
+Version:	1.0.1
+Release:	1%{?dist}
 Summary:	A TigerVNC remote display system
 
 Group:		User Interface/Desktops
@@ -11,7 +11,6 @@ Source0:	%{name}-%{version}.tar.gz
 Source1:	vncserver.init
 Source2:	vncserver.sysconfig
 Source6:	vncviewer.desktop
-Source7:	xorg-x11-server-source-1.6.4-0.3.fc11.x86_64.rpm
 BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 BuildRequires:	libX11-devel, automake, autoconf, libtool, gettext, cvs
@@ -39,10 +38,21 @@ Obsoletes:	tightvnc < 1.5.0-0.15.2009020
 Patch0:		tigervnc-102434.patch
 Patch4:		tigervnc-cookie.patch
 Patch8:		tigervnc-viewer-reparent.patch
-Patch10:	tigervnc10-compat.patch
-Patch11:	tigervnc10-rh510185.patch
-Patch12:	tigervnc10-rh524340.patch
-Patch13:	tigervnc10-rh516274.patch
+Patch14:	tigervnc11-r3883.patch
+Patch15:	tigervnc11-r3884.patch
+Patch16:	tigervnc11-r3885.patch
+Patch17:	tigervnc11-r3886.patch
+Patch18:	tigervnc10-r3925-revert.patch
+Patch19:	tigervnc11-r3887.patch
+Patch20:	tigervnc11-r3924-rh541559.patch
+Patch21:	tigervnc11-r3926.patch
+Patch22:	tigervnc11-r3927.patch
+Patch23:	tigervnc11-r3932.patch
+Patch24:	tigervnc10-noexec.patch
+Patch25:	tigervnc11-r4007.patch
+Patch26:	tigervnc11-r4008.patch
+Patch27:	tigervnc11-r4024.patch
+Patch28:	tigervnc11-r4025.patch
 
 %description
 Virtual Network Computing (VNC) is a remote display system which
@@ -90,26 +100,35 @@ to access the desktop on your machine.
 %prep
 %setup -q -n %{name}-%{version}
 
-rpm2cpio %{SOURCE7} > cpio
-cpio -id < cpio
+%patch0 -p1 -b .102434
+%patch4 -p1 -b .cookie
+%patch8 -p1 -b .viewer-reparent
+%patch14 -p0 -b .r3883
+%patch15 -p0 -b .r3884
+%patch16 -p0 -b .r3885
+%patch17 -p0 -b .r3886
+%patch18 -p0 -b .r3925-revert
+%patch19 -p0 -b .r3887
+%patch20 -p0 -b .r3924-rh541559
+%patch21 -p0 -b .r3926
+%patch22 -p0 -b .r3927
+%patch23 -p0 -b .r3932
+%patch24 -p1 -b .noexec
+pushd unix
+%patch25 -p0 -b .r4007
+popd
+%patch26 -p0 -b .r4008
+%patch27 -p1 -b .r4024
+%patch28 -p1 -b .r4025
 
-cp -r usr/share/xorg-x11-server-source/* unix/xserver
+cp -r /usr/share/xorg-x11-server-source/* unix/xserver
 pushd unix/xserver
 for all in `find . -type f -perm -001`; do
 	chmod -x "$all"
 done
-patch -p1 -b --suffix .vnc < ../xserver16.patch
+patch -p1 -b --suffix .vnc < ../xserver17.patch
 popd
 
-
-%patch0 -p1 -b .102434
-%patch4 -p1 -b .cookie
-%patch8 -p1 -b .viewer-reparent
-%patch10 -p1 -b .compat
-%patch11 -p0 -b .rh510185
-%patch12 -p0 -b .rh524340
-%patch13 -p1 -b .rh516274
-
 # Use newer gettext
 sed -i 's/AM_GNU_GETTEXT_VERSION.*/AM_GNU_GETTEXT_VERSION([0.17])/' \
 	unix/configure.ac
@@ -143,7 +162,7 @@ autoreconf -fiv
 	--disable-config-hal \
 	--with-dri-driver-path=%{_libdir}/dri
 
-make %{?_smp_mflags}
+make V=1 %{?_smp_mflags}
 popd
 
 # Build icons
@@ -250,6 +269,19 @@ fi
 %endif
 
 %changelog
+* Wed Apr 14 2010 Adam Tkac <atkac redhat com> 1.0.1-1
+- update to 1.0.1 bugfix release
+- patches merged
+  - tigervnc10-rh510185.patch
+  - tigervnc10-rh524340.patch
+  - tigervnc10-compat.patch
+- backport X.Org 1.7.X support from trunk (r3883, r3884, r3885, r3886,
+  r3887, r3926, r3927, r3932, r4024, r4025)
+  - tigervnc10-rh516274.patch is no longer needed
+- modifiers might be stuck inside Xvnc (r3924, #541559)
+- mark stack as non executable in JPEG code
+- backport French translation (r4007, r4008)
+  
 * Mon Oct 26 2009 Adam Tkac <atkac redhat com> 1.0.0-3
 - create Xvnc keyboard mapping before first keypress (#516274)
 


--- tigervnc10-compat.patch DELETED ---


--- tigervnc10-rh510185.patch DELETED ---


--- tigervnc10-rh516274.patch DELETED ---


--- tigervnc10-rh524340.patch DELETED ---



More information about the scm-commits mailing list