Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 604

kvm-83-164.el5_5.9.src.rpm

From 89b274767a2b10cf07ab3826d771049de6dc6b9d Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 5 Jan 2010 16:47:48 -0200
Subject: [PATCH 3/5] kvm/vnc: improve capslock handling

RH-Author: Gerd Hoffmann <kraxel@redhat.com>
Message-id: <1262710068-6415-1-git-send-email-kraxel@redhat.com>
Patchwork-id: 6077
O-Subject: [RHEL 5.5 PATCH] kvm/vnc: improve capslock handling
Bugzilla: 517814
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>

bz #517814

This patch squashes two related upstream commits together:

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.

The capslock tracking logic added by commit
6b1325029d80455b9da7cd7bd84a88cb915b867c doesn't work correctly for vnc
clients without EXT_KEY_EVENT support.  The reason is that qemu converts
keysyms for letters to lowercase for the keysym2scancode lookup.  It
then also passes the lowercase value down to do_key_event(), but the
capslock tracking code needs it with the correct case to work properly.

This patch adds a new variable for the lowercase keysym so we'll keep
the unmodified value for do_key_event().
---
 qemu/vnc.c |   29 ++++++++++++++++++++++++++---
 1 files changed, 26 insertions(+), 3 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/vnc.c |   29 ++++++++++++++++++++++++++---
 1 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/qemu/vnc.c b/qemu/vnc.c
index e72609d..160fd49 100644
--- a/qemu/vnc.c
+++ b/qemu/vnc.c
@@ -1173,6 +1173,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);
@@ -1238,11 +1259,13 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
 static void key_event(VncState *vs, int down, uint32_t sym)
 {
     int keycode;
+    int lsym = sym;
 
-    if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
-	sym = sym - 'A' + 'a';
+    if (lsym >= 'A' && lsym <= 'Z' && is_graphic_console()) {
+        lsym = lsym - 'A' + 'a';
+    }
 
-    keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF);
+    keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF);
     do_key_event(vs, down, keycode, sym);
 }
 
-- 
1.6.3.rc4.29.g8146