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