All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [IOEMU] Fix shift key for graphical vnc display
@ 2007-07-20  9:45 Kasai Takanori
  2007-07-20 13:40 ` Daniel P. Berrange
  0 siblings, 1 reply; 3+ messages in thread
From: Kasai Takanori @ 2007-07-20  9:45 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 1482 bytes --]

Hi All,

There is a problem in the input of the key in the VNC connection on the HVM
domain.
When client's keyboard is not the same as the kind of the keyboard of qemu-dm
and GuestOS, it is not possible to input it correctly.

   VNC client     qemu-dm & GuestOS
--------------+-----------------------
    ja             en-us               ==> NG
    en-us          en-us               ==> OK

Originally, the same keysym-code between client and qemu-dm is transmitted.
However, even if it is the same character, the state of shift is different
according to the kind of keyboard.

ex.
   "=" charactor
---------------------
en-us :  "="
ja    :  shift + "-"

Therefore, it is necessary to handle the state of the shift by setting
qemu-dm and GuestOS. There is information on whether shift is necessary
for each key for the keymap of qemu-dm.

ex.
 VNC client        : ja
 qemu-dm & GuestOS : en-us
 input key         : "="
 event client to qemu-dm :
  shift(push) >> "="(push) >> "="(release) >> shift(release)
 event qemu-dm to guest :
  shift(push) >> shift(release) >> "="(push) >> "="(release) >> shift(push) >> 
shift(release)

This patch handled the state of shift from the set keymap.
When client's keyboard is not same as the kind of qemu-dm/GuestOS,
it is possible to input it correctly.
It was confirmed to input it correctly mutually with this patch between en-us 
and ja.

Signed-off-by: Takanori Kasai <kasai.takanori@jp.fujitsu.com>

Best Regards,

--
Takanori Kasai

[-- Attachment #2: fix-ioemu-vnc-shift-key.patch --]
[-- Type: application/octet-stream, Size: 5710 bytes --]

# HG changeset patch
# User kasai.takanori@jp.fujitsu.com
# Date 1184920858 -32400
# Node ID 4fdd61d2134594aea67e9cc2450d8d15810358bc
# Parent  1f348e70a5affdea9b44c1e39cd5ef094ad4a0bf
[qemu] Fix shift key for graphical vnc displays

Signed-off-by: Takanori Kasai <kasai.takanori@jp.fujitsu.com>

diff -r 1f348e70a5af -r 4fdd61d21345 tools/ioemu/keymaps.c
--- a/tools/ioemu/keymaps.c	Tue Jul 10 11:10:38 2007 +0100
+++ b/tools/ioemu/keymaps.c	Fri Jul 20 17:40:58 2007 +0900
@@ -49,6 +49,7 @@ typedef struct {
     int extra_count;
     struct key_range *keypad_range;
     struct key_range *numlock_range;
+    struct key_range *shift_range;
 } kbd_layout_t;
 
 static void add_to_key_range(struct key_range **krp, int code) {
@@ -127,6 +128,10 @@ static kbd_layout_t *parse_keyboard_layo
 			add_to_key_range(&k->numlock_range, keysym);
 			fprintf(stderr, "keypad keysym %04x keycode %d\n", keysym, keycode);
 		    }
+		    if (rest && strstr(rest, "shift")) {
+			add_to_key_range(&k->shift_range, keysym);
+			fprintf(stderr, "shift keysym %04x keycode %d\n", keysym, keycode);
+		    }
 
 		    /* if(keycode&0x80)
 		       keycode=(keycode<<8)^0x80e0; */
@@ -205,3 +210,14 @@ static int keysymIsNumlock(void *kbd_lay
 	    return 1;
     return 0;
 }
+
+static int keysymIsShift(void *kbd_layout, int keysym)
+{
+    kbd_layout_t *k = kbd_layout;
+    struct key_range *kr;
+
+    for (kr = k->shift_range; kr; kr = kr->next)
+	if (keysym >= kr->start && keysym <= kr->end)
+	    return 1;
+    return 0;
+}
diff -r 1f348e70a5af -r 4fdd61d21345 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c	Tue Jul 10 11:10:38 2007 +0100
+++ b/tools/ioemu/vnc.c	Fri Jul 20 17:40:58 2007 +0900
@@ -915,12 +915,69 @@ static void press_key(VncState *vs, int 
     kbd_put_keycode(keysym2scancode(vs->kbd_layout, keysym) | 0x80);
 }
 
+static void press_key_shift_down(VncState *vs, int down, int keycode)
+{
+    if (down)
+        kbd_put_keycode(0x2a & 0x7f);
+
+    if (keycode & 0x80)
+        kbd_put_keycode(0xe0);
+    if (down)
+        kbd_put_keycode(keycode & 0x7f);
+    else
+        kbd_put_keycode(keycode | 0x80);
+
+    if (!down)
+        kbd_put_keycode(0x2a | 0x80);
+}
+
+static void press_key_shift_up(VncState *vs, int down, int keycode)
+{
+    if (down) {
+        if (vs->modifiers_state[0x2a])
+            kbd_put_keycode(0x2a | 0x80);
+        if (vs->modifiers_state[0x36]) 
+            kbd_put_keycode(0x36 | 0x80);
+    }
+
+    if (keycode & 0x80)
+        kbd_put_keycode(0xe0);
+    if (down)
+        kbd_put_keycode(keycode & 0x7f);
+    else
+        kbd_put_keycode(keycode | 0x80);
+
+    if (!down) {
+        if (vs->modifiers_state[0x2a])
+            kbd_put_keycode(0x2a & 0x7f);
+        if (vs->modifiers_state[0x36]) 
+            kbd_put_keycode(0x36 & 0x7f);
+    }
+}
+
 static void do_key_event(VncState *vs, int down, uint32_t sym)
 {
     int keycode;
+    int shift_keys = 0;
+    int shift = 0;
+
+    if (is_graphic_console()) {
+        if (sym >= 'A' && sym <= 'Z') {
+            sym = sym - 'A' + 'a';
+            shift = 1;
+        }
+        else {
+            shift = keysymIsShift(vs->kbd_layout, sym & 0xFFFF);
+        }
+    }
+    shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36];
 
     keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
-    
+    if (keycode == 0) {
+        fprintf(stderr, "Key lost : keysym=0x%x(%d)\n", sym, sym);
+        return;
+    }
+
     /* QEMU console switch */
     switch(keycode) {
     case 0x2a:                          /* Left Shift */
@@ -929,11 +986,15 @@ static void do_key_event(VncState *vs, i
     case 0x9d:                          /* Right CTRL */
     case 0x38:                          /* Left ALT */
     case 0xb8:                          /* Right ALT */
-        if (down)
+        if (down) {
             vs->modifiers_state[keycode] = 1;
-        else
+            kbd_put_keycode(keycode & 0x7f);
+        }
+        else {
             vs->modifiers_state[keycode] = 0;
-        break;
+            kbd_put_keycode(keycode | 0x80);
+        }
+        return;
     case 0x02 ... 0x0a: /* '1' to '9' keys */ 
         if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
             /* Reset the modifiers sent to the current console */
@@ -943,9 +1004,14 @@ static void do_key_event(VncState *vs, i
         }
         break;
     case 0x45:			/* NumLock */
-	if (!down)
+	if (down) {
+            kbd_put_keycode(keycode & 0x7f);
+        }
+        else {	
 	    vs->modifiers_state[keycode] ^= 1;
-	break;
+            kbd_put_keycode(keycode | 0x80);
+        }
+	return;
     }
 
     if (keycodeIsKeypad(vs->kbd_layout, keycode)) {
@@ -967,6 +1033,18 @@ static void do_key_event(VncState *vs, i
     }
 
     if (is_graphic_console()) {
+        /*  If the shift state needs to change then simulate an additional
+            keypress before sending this one.
+        */
+        if (shift && !shift_keys) {
+            press_key_shift_down(vs, down, keycode);
+            return;
+        }
+        else if (!shift && shift_keys) {
+            press_key_shift_up(vs, down, keycode);
+            return;
+        }
+
         if (keycode & 0x80)
             kbd_put_keycode(0xe0);
         if (down)
@@ -1021,8 +1099,6 @@ static void do_key_event(VncState *vs, i
 
 static void key_event(VncState *vs, int down, uint32_t sym)
 {
-    if (sym >= 'A' && sym <= 'Z' && is_graphic_console())
-	sym = sym - 'A' + 'a';
     do_key_event(vs, down, sym);
 }
 

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-07-23  2:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-20  9:45 [PATCH] [IOEMU] Fix shift key for graphical vnc display Kasai Takanori
2007-07-20 13:40 ` Daniel P. Berrange
2007-07-23  2:59   ` [PATCH] [IOEMU] Fix shift key for graphical vncdisplay Kasai Takanori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.