Make sure we release the same key we previously pressed for a
given keysym.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@5072 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/unix/xserver/hw/vnc/Input.cc b/unix/xserver/hw/vnc/Input.cc
index 80490e6..b23aeae 100644
--- a/unix/xserver/hw/vnc/Input.cc
+++ b/unix/xserver/hw/vnc/Input.cc
@@ -130,9 +130,14 @@
 InputDevice::InputDevice(rfb::VNCServerST *_server)
 	: server(_server), initialized(false), oldButtonMask(0)
 {
+	int i;
+
 #if XORG < 111
 	initEventq();
 #endif
+
+	for (i = 0;i < 256;i++)
+		pressedKeys[i] = NoSymbol;
 }
 
 void InputDevice::PointerButtonAction(int buttonMask)
@@ -614,6 +619,28 @@
 	KeybdCtrl ctrl;
 #endif
 
+	/*
+	 * Release events must match the press event, so look up what
+	 * keycode we sent for the press.
+	 */
+	if (!down) {
+		for (i = 0;i < 256;i++) {
+			if (pressedKeys[i] == keysym) {
+				pressedKeys[i] = NoSymbol;
+				pressKey(keyboardDev, i, false, "keycode");
+				mieqProcessInputEvents();
+				return;
+			}
+		}
+
+		/*
+		 * This can happen quite often as we ignore some
+		 * key presses.
+		 */
+		vlog.debug("Unexpected release of keysym 0x%x", keysym);
+		return;
+	}
+
 	/* 
 	 * Since we are checking the current state to determine if we need
 	 * to fake modifiers, we must make sure that everything put on the
@@ -856,11 +883,23 @@
 	} else {
 press:
 		pressKey(keyboardDev, kc, down, "keycode");
+
+		/* Store the mapping so that we can do a proper release later */
+		for (i = 0;i < 256;i++) {
+			if (i == kc)
+				continue;
+			if (pressedKeys[i] == keysym) {
+				vlog.error("Keysym 0x%x generated by both keys %d and %d", keysym, i, kc);
+				pressedKeys[i] = NoSymbol;
+			}
+		}
+
+		pressedKeys[kc] = keysym;
 	}
 
 
         FREE_MAPS;
-	
+
 	/*
 	 * When faking a modifier we are putting a keycode (which can
 	 * currently activate the desired modifier) on the input
diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h
index fd458a6..fafefde 100644
--- a/unix/xserver/hw/vnc/Input.h
+++ b/unix/xserver/hw/vnc/Input.h
@@ -74,8 +74,11 @@
 	bool initialized;
 	DeviceIntPtr keyboardDev;
 	DeviceIntPtr pointerDev;
+
 	int oldButtonMask;
 	rfb::Point cursorPos, oldCursorPos;
+
+	KeySym pressedKeys[256];
 };
 
 #endif