vnc: improve capslock handling.
authorGerd Hoffmann <kraxel@redhat.com>
Mon, 2 Nov 2009 11:47:06 +0000 (12:47 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Thu, 12 Nov 2009 17:23:56 +0000 (11:23 -0600)
When capslock is toggled while the vnc window hasn't the focus qemu
will miss the state change.  Add sanity checks for the capslock state
and toggle it if needed, so hosts and guests idea of capslock state
stay in sync.  Simliar logic for numlock is present in qemu already.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
vnc.c

diff --git a/vnc.c b/vnc.c
index 01e8e934895a54a0a8af1acf6f2c1d2384491101..2bb802469c545eea2804fa2acb98f20af8e27798 100644 (file)
--- a/vnc.c
+++ b/vnc.c
@@ -1377,6 +1377,27 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
         }
     }
 
+    if ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z')) {
+        /* If the capslock state needs to change then simulate an additional
+           keypress before sending this one.  This will happen if the user
+           toggles capslock away from the VNC window.
+        */
+        int uppercase = !!(sym >= 'A' && sym <= 'Z');
+        int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
+        int capslock = !!(vs->modifiers_state[0x3a]);
+        if (capslock) {
+            if (uppercase == shift) {
+                vs->modifiers_state[0x3a] = 0;
+                press_key(vs, 0xffe5);
+            }
+        } else {
+            if (uppercase != shift) {
+                vs->modifiers_state[0x3a] = 1;
+                press_key(vs, 0xffe5);
+            }
+        }
+    }
+
     if (is_graphic_console()) {
         if (keycode & 0x80)
             kbd_put_keycode(0xe0);