]> git.proxmox.com Git - qemu.git/commitdiff
kbd keds: vnc
authorGerd Hoffmann <kraxel@redhat.com>
Fri, 26 Feb 2010 16:17:39 +0000 (17:17 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Tue, 9 Mar 2010 14:47:27 +0000 (08:47 -0600)
Use led status notification support in vnc.

The qemu vnc server keeps track of the capslock and numlock states based
on the key presses it receives from the vnc client.  But this fails in
case the guests idea of the capslock and numlock state changes for other
reasons.  One case is guest reboot (+ keyboard reset).  Another case are
more recent windows versions which reset capslock state before
presenting the login screen.

Usually guests use the keyboard leds to signal the capslock and numlock
state to the user, so we can use this to better keep track of capslock
and numlock state in the qemu vnc server.

Also toggle the numlock and capslock states on keydown events (instead
of keyup).  Guests do the same.

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

diff --git a/vnc.c b/vnc.c
index 01353a96c8bed576371543fb8d30ceb43fe86dbf..7ce73dca3d35f8363870e7b61c09e2179105c9f5 100644 (file)
--- a/vnc.c
+++ b/vnc.c
@@ -1111,6 +1111,7 @@ static void vnc_disconnect_finish(VncState *vs)
     }
 
     vnc_remove_timer(vs->vd);
+    qemu_remove_led_event_handler(vs->led);
     qemu_free(vs);
 }
 
@@ -1501,6 +1502,22 @@ static void press_key(VncState *vs, int keysym)
     kbd_put_keycode(keycode | SCANCODE_UP);
 }
 
+static void kbd_leds(void *opaque, int ledstate)
+{
+    VncState *vs = opaque;
+    int caps, num;
+
+    caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
+    num  = ledstate & QEMU_NUM_LOCK_LED  ? 1 : 0;
+
+    if (vs->modifiers_state[0x3a] != caps) {
+        vs->modifiers_state[0x3a] = caps;
+    }
+    if (vs->modifiers_state[0x45] != num) {
+        vs->modifiers_state[0x45] = num;
+    }
+}
+
 static void do_key_event(VncState *vs, int down, int keycode, int sym)
 {
     /* QEMU console switch */
@@ -1526,7 +1543,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
         break;
     case 0x3a:                        /* CapsLock */
     case 0x45:                        /* NumLock */
-        if (!down)
+        if (down)
             vs->modifiers_state[keycode] ^= 1;
         break;
     }
@@ -2412,6 +2429,7 @@ static void vnc_connect(VncDisplay *vd, int csock)
     vnc_flush(vs);
     vnc_read_when(vs, protocol_version, 12);
     reset_keys(vs);
+    vs->led = qemu_add_led_event_handler(kbd_leds, vs);
 
     vnc_init_timer(vd);
 
diff --git a/vnc.h b/vnc.h
index ff9a6993ad77f34caf50c47c09b9bc0290d14b04..0fc89bd0885dfb888fed0a4bc9087bf8c04f3126 100644 (file)
--- a/vnc.h
+++ b/vnc.h
@@ -161,6 +161,7 @@ struct VncState
     size_t read_handler_expect;
     /* input */
     uint8_t modifiers_state[256];
+    QEMUPutLEDEntry *led;
 
     Buffer zlib;
     Buffer zlib_tmp;