Adam Tkac 31632b3
diff -up tigervnc-1.0.90-20100813svn4123/unix/xserver/hw/vnc/Input.cc.rh633931 tigervnc-1.0.90-20100813svn4123/unix/xserver/hw/vnc/Input.cc
Adam Tkac 31632b3
--- tigervnc-1.0.90-20100813svn4123/unix/xserver/hw/vnc/Input.cc.rh633931	2010-09-16 11:29:33.670000097 +0200
Adam Tkac 31632b3
+++ tigervnc-1.0.90-20100813svn4123/unix/xserver/hw/vnc/Input.cc	2010-09-16 12:59:31.530002411 +0200
Adam Tkac 31632b3
@@ -271,6 +271,19 @@ void InputDevice::initInputDevice(void)
Adam Tkac 31632b3
 #endif
Adam Tkac 31632b3
 }
Adam Tkac 31632b3
 
Adam Tkac 31632b3
+static inline void pressKey(DeviceIntPtr dev, int kc, bool down, const char *msg)
Adam Tkac 31632b3
+{
Adam Tkac 31632b3
+	int action;
Adam Tkac 31632b3
+	unsigned int n;
Adam Tkac 31632b3
+
Adam Tkac 31632b3
+	if (msg != NULL)
Adam Tkac 31632b3
+		vlog.debug("%s %d %s", msg, kc, down ? "down" : "up");
Adam Tkac 31632b3
+
Adam Tkac 31632b3
+	action = down ? KeyPress : KeyRelease;
Adam Tkac 31632b3
+	n = GetKeyboardEvents(eventq, dev, action, kc);
Adam Tkac 31632b3
+	enqueueEvents(dev, n);
Adam Tkac 31632b3
+}
Adam Tkac 31632b3
+
Adam Tkac 31632b3
 #define IS_PRESSED(keyc, keycode) \
Adam Tkac 31632b3
 	((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
Adam Tkac 31632b3
 
Adam Tkac 31632b3
@@ -294,7 +307,7 @@ public:
Adam Tkac 31632b3
 	~ModifierState()
Adam Tkac 31632b3
 	{
Adam Tkac 31632b3
 		for (int i = 0; i < nKeys; i++)
Adam Tkac 31632b3
-			generateXKeyEvent(keys[i], !pressed);
Adam Tkac 31632b3
+			pressKey(dev, keys[i], !pressed, "fake keycode");
Adam Tkac 31632b3
 		delete [] keys;
Adam Tkac 31632b3
 	}
Adam Tkac 31632b3
 
Adam Tkac 31632b3
@@ -389,22 +402,10 @@ private:
Adam Tkac 31632b3
 		if (keycode) {
Adam Tkac 31632b3
 			if (!keys) keys = new int[maxKeysPerMod];
Adam Tkac 31632b3
 			keys[nKeys++] = keycode;
Adam Tkac 31632b3
-			generateXKeyEvent(keycode, down);
Adam Tkac 31632b3
+			pressKey(dev, keycode, down, "fake keycode");
Adam Tkac 31632b3
 		}
Adam Tkac 31632b3
 	}
Adam Tkac 31632b3
 
Adam Tkac 31632b3
-	void generateXKeyEvent(int keycode, bool down)
Adam Tkac 31632b3
-	{
Adam Tkac 31632b3
-		int n, action;
Adam Tkac 31632b3
-
Adam Tkac 31632b3
-		action = down ? KeyPress : KeyRelease;
Adam Tkac 31632b3
-		n = GetKeyboardEvents(eventq, dev, action, keycode);
Adam Tkac 31632b3
-		enqueueEvents(dev, n);
Adam Tkac 31632b3
-
Adam Tkac 31632b3
-		vlog.debug("fake keycode %d %s", keycode,
Adam Tkac 31632b3
-			   down ? "down" : "up");
Adam Tkac 31632b3
-	}
Adam Tkac 31632b3
-
Adam Tkac 31632b3
 	int modIndex;
Adam Tkac 31632b3
 	int nKeys;
Adam Tkac 31632b3
 	int *keys;
Adam Tkac 31632b3
@@ -503,8 +504,8 @@ void InputDevice::keyEvent(rdr::U32 keys
Adam Tkac 31632b3
 	KeyCode minKeyCode, maxKeyCode;
Adam Tkac 31632b3
 	KeyCode *modmap = NULL;
Adam Tkac 31632b3
 	int mapWidth;
Adam Tkac 31632b3
-	unsigned int i, n;
Adam Tkac 31632b3
-	int j, k, action, state, maxKeysPerMod;
Adam Tkac 31632b3
+	unsigned int i;
Adam Tkac 31632b3
+	int j, k, state, maxKeysPerMod;
Adam Tkac 31632b3
 
Adam Tkac 31632b3
 	initInputDevice();
Adam Tkac 31632b3
 
Adam Tkac 31632b3
@@ -691,12 +692,14 @@ ModeSwitchFound:
Adam Tkac 31632b3
 					modeSwitch.release();
Adam Tkac 31632b3
 			}
Adam Tkac 31632b3
 		}
Adam Tkac 31632b3
-	}
Adam Tkac 31632b3
+		/*
Adam Tkac 31632b3
+		 * Ensure ModifierState objects are not destroyed before
Adam Tkac 31632b3
+		 * pressKey call, otherwise fake modifier keypress can be lost.
Adam Tkac 31632b3
+		 */
Adam Tkac 31632b3
+		pressKey(keyboardDev, kc, down, "keycode");
Adam Tkac 31632b3
+	} else
Adam Tkac 31632b3
+		pressKey(keyboardDev, kc, down, "keycode");
Adam Tkac 31632b3
 
Adam Tkac 31632b3
-	vlog.debug("keycode %d %s", kc, down ? "down" : "up");
Adam Tkac 31632b3
-	action = down ? KeyPress : KeyRelease;
Adam Tkac 31632b3
-	n = GetKeyboardEvents(eventq, keyboardDev, action, kc);
Adam Tkac 31632b3
-	enqueueEvents(keyboardDev, n);
Adam Tkac 31632b3
 
Adam Tkac 31632b3
         FREE_MAPS;
Adam Tkac 31632b3