[libvirt] problem of escaped scancodes

Hi, Daniel P. Berrange, Our user found that some keycode can not be handled well when they try to map other keycode to xt_kbd keycode, when xt_kbd keycode is an escaped scancode. The xt_kbd keycode http://git.gnome.org/browse/gtk-vnc/plain/src/keymaps.csv are come from x86_keycodes[] of linux/drivers/char/keyboard.c. And x86_keycodes[] are: static const unsigned short x86_keycodes[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361, 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114, 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116, 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307, 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; There is no keycode in range [128, 256] in this table, which means all escaped scancode "e0 ??" are encoded as "0x100 | ??" in this table. Example, LeftCtrl is 0x1d, and RightCtrl is escaped: "e0 1d", RightCtrl is encoded as "0x100 | 0x1d"(=0x11d=285) in this table. The code also tell me the same information: code = x86_keycodes[keycode]; if (!code) return -1; if (code & 0x100) put_queue(vc, 0xe0); put_queue(vc, (code & 0x7f) | up_flag); But some other place, escaped scancode "e0 ??" are encoded as "0x80 | ??", this encoding is more commonly used, and qemu uses this encoding, RightCtrl is encoded as "0x80 | 0x1d"(=0x9d=157) in qemu: { 0x9d, "ctrl_r" }, keycode = keycodes[i]; if (keycode & 0x80) kbd_put_keycode(0xe0); kbd_put_keycode(keycode & 0x7f); The problem: keymaps.csv uses the first encoding while qemu uses the second one, it causes "virsh send-key" command can't work when it sends escaped scancodes. Example: When do "virsh send-key domain KEY_RIGHTCTRL", qemu will receive keycode=285 which is not expected. So I suggest to change keymaps.csv. Covert the old KEY_RIGHTCTRL,97,RightControl,0x3e,,,88,,285,228,VK_RCONTROL,0xa3,0x65,0x65 to new KEY_RIGHTCTRL,97,RightControl,0x3e,,,88,,157,228,VK_RCONTROL,0xa3,0x65,0x65 (ditto for other escaped scancodes) Or just add the new line to keymaps.csv followed by the old line, and make 285 and 157 can work at the same time. Thought? Thanks, Lai.

On Tue, Aug 23, 2011 at 03:32:51PM +0800, Lai Jiangshan wrote:
Hi, Daniel P. Berrange,
Our user found that some keycode can not be handled well when they try to map other keycode to xt_kbd keycode, when xt_kbd keycode is an escaped scancode.
The xt_kbd keycode http://git.gnome.org/browse/gtk-vnc/plain/src/keymaps.csv are come from x86_keycodes[] of linux/drivers/char/keyboard.c. And x86_keycodes[] are:
static const unsigned short x86_keycodes[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361, 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114, 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116, 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307, 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
There is no keycode in range [128, 256] in this table, which means all escaped scancode "e0 ??" are encoded as "0x100 | ??" in this table. Example, LeftCtrl is 0x1d, and RightCtrl is escaped: "e0 1d", RightCtrl is encoded as "0x100 | 0x1d"(=0x11d=285) in this table. The code also tell me the same information:
code = x86_keycodes[keycode]; if (!code) return -1;
if (code & 0x100) put_queue(vc, 0xe0); put_queue(vc, (code & 0x7f) | up_flag);
But some other place, escaped scancode "e0 ??" are encoded as "0x80 | ??", this encoding is more commonly used, and qemu uses this encoding, RightCtrl is encoded as "0x80 | 0x1d"(=0x9d=157) in qemu:
{ 0x9d, "ctrl_r" },
keycode = keycodes[i]; if (keycode & 0x80) kbd_put_keycode(0xe0); kbd_put_keycode(keycode & 0x7f);
The problem: keymaps.csv uses the first encoding while qemu uses the second one, it causes "virsh send-key" command can't work when it sends escaped scancodes.
What this acutally means is that we have 2 different scancode sets, each with their own different encoding for the extended scancodes. We are simply using the wrong set when talking to QEMU.
Example: When do "virsh send-key domain KEY_RIGHTCTRL", qemu will receive keycode=285 which is not expected.
So I suggest to change keymaps.csv. Covert the old KEY_RIGHTCTRL,97,RightControl,0x3e,,,88,,285,228,VK_RCONTROL,0xa3,0x65,0x65 to new KEY_RIGHTCTRL,97,RightControl,0x3e,,,88,,157,228,VK_RCONTROL,0xa3,0x65,0x65 (ditto for other escaped scancodes)
Or just add the new line to keymaps.csv followed by the old line, and make 285 and 157 can work at the same time.
No, we just need to switch to use the correct scancode set. The original keymap-gen.pl script in GTK-VNC has code for auto-generating the RFB scancode set, from the data for the XT KBD scancode set. It is a straighforward re-encoding for the extended keys: # RFB keycodes are XT kbd keycodes with a slightly # different encoding of 0xe0 scan codes. RFB uses # the high bit of the first byte, instead of the low # bit of the second byte. rfbkey = (xtkbdkey & 0x100) >> 1 | (ktkbdkey & 0x7f) Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Tue, 23 Aug 2011 14:54:11 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
No, we just need to switch to use the correct scancode set.
The original keymap-gen.pl script in GTK-VNC has code for auto-generating the RFB scancode set, from the data for the XT KBD scancode set. It is a straighforward re-encoding for the extended keys:
# RFB keycodes are XT kbd keycodes with a slightly # different encoding of 0xe0 scan codes. RFB uses # the high bit of the first byte, instead of the low # bit of the second byte. rfbkey = (xtkbdkey & 0x100) >> 1 | (ktkbdkey & 0x7f)
like this ? ==
From 7ea5214b7832acbb7bae81d7d8ceeaa19890e32b Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Date: Thu, 25 Aug 2011 10:29:57 +0900 Subject: [PATCH] fix to adjust xt_kbd scancode
The keycode in http://git.gnome.org/browse/gtk-vnc/plain/src/keymaps.csv handles escaped scancode in different way from qemu's one. all escaped scancode "e0 ??" are encoded as "0x100 | ??" in this csv. But qemu handles escaped scancode as "0x80 | ??" and this scancode is more common. --- src/util/virkeycode-mapgen.py | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/src/util/virkeycode-mapgen.py b/src/util/virkeycode-mapgen.py index acf7364..5d83a39 100755 --- a/src/util/virkeycode-mapgen.py +++ b/src/util/virkeycode-mapgen.py @@ -14,6 +14,7 @@ import sys import re namecolums = (0,2,10) +xtkbdkey_index = 8 def quotestring(str): if str[0] != '"': @@ -38,7 +39,18 @@ for line in sys.stdin.xreadlines(): for i in namecolums: b = b + (a[i] and quotestring(a[i]) or 'NULL') + ',' for i in [ x for x in range(12) if not x in namecolums ]: - b = b + (a[i] or '0') + ',' + if i != xtkbdkey_index : + b = b + (a[i] or '0') + ',' + elif a[i] == '' : + b = b + '0' + ',' + else : + # RFB keycodes are XT kbd keycodes with a slightly + # different encoding of 0xe0 scan codes. RFB uses + # the high bit of the first byte, instead of the low + # bit of the second byte. + code = int(a[i]) + code = (code & 0x100) >> 1 | (code & 0x7f) + b = b + str(code) + ',' print " { " + b + "}," print '};' -- 1.7.4.1

On Thu, Aug 25, 2011 at 10:25:57AM +0900, KAMEZAWA Hiroyuki wrote:
On Tue, 23 Aug 2011 14:54:11 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
No, we just need to switch to use the correct scancode set.
The original keymap-gen.pl script in GTK-VNC has code for auto-generating the RFB scancode set, from the data for the XT KBD scancode set. It is a straighforward re-encoding for the extended keys:
# RFB keycodes are XT kbd keycodes with a slightly # different encoding of 0xe0 scan codes. RFB uses # the high bit of the first byte, instead of the low # bit of the second byte. rfbkey = (xtkbdkey & 0x100) >> 1 | (ktkbdkey & 0x7f)
like this ?
== From 7ea5214b7832acbb7bae81d7d8ceeaa19890e32b Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Date: Thu, 25 Aug 2011 10:29:57 +0900 Subject: [PATCH] fix to adjust xt_kbd scancode
The keycode in http://git.gnome.org/browse/gtk-vnc/plain/src/keymaps.csv handles escaped scancode in different way from qemu's one.
all escaped scancode "e0 ??" are encoded as "0x100 | ??" in this csv. But qemu handles escaped scancode as "0x80 | ??" and this scancode is more common. --- src/util/virkeycode-mapgen.py | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/src/util/virkeycode-mapgen.py b/src/util/virkeycode-mapgen.py index acf7364..5d83a39 100755 --- a/src/util/virkeycode-mapgen.py +++ b/src/util/virkeycode-mapgen.py @@ -14,6 +14,7 @@ import sys import re
namecolums = (0,2,10) +xtkbdkey_index = 8
def quotestring(str): if str[0] != '"': @@ -38,7 +39,18 @@ for line in sys.stdin.xreadlines(): for i in namecolums: b = b + (a[i] and quotestring(a[i]) or 'NULL') + ',' for i in [ x for x in range(12) if not x in namecolums ]: - b = b + (a[i] or '0') + ',' + if i != xtkbdkey_index : + b = b + (a[i] or '0') + ',' + elif a[i] == '' : + b = b + '0' + ',' + else : + # RFB keycodes are XT kbd keycodes with a slightly + # different encoding of 0xe0 scan codes. RFB uses + # the high bit of the first byte, instead of the low + # bit of the second byte. + code = int(a[i]) + code = (code & 0x100) >> 1 | (code & 0x7f) + b = b + str(code) + ',' print " { " + b + "},"
print '};'
This is not quite right. We don't want to change the XT KBD codeset since that's defined that way by the Linux driver. We instead want to add a new RFB codeset and make the QEMU driver use that. Check out this patch https://www.redhat.com/archives/libvir-list/2011-August/msg01256.html In my tests it made 'virsh send-key f16x86_64 KEY_RIGHTCTRL KEY_C' work correctly Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Thu, 25 Aug 2011 17:51:49 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
On Thu, Aug 25, 2011 at 10:25:57AM +0900, KAMEZAWA Hiroyuki wrote:
On Tue, 23 Aug 2011 14:54:11 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
No, we just need to switch to use the correct scancode set.
The original keymap-gen.pl script in GTK-VNC has code for auto-generating the RFB scancode set, from the data for the XT KBD scancode set. It is a straighforward re-encoding for the extended keys:
# RFB keycodes are XT kbd keycodes with a slightly # different encoding of 0xe0 scan codes. RFB uses # the high bit of the first byte, instead of the low # bit of the second byte. rfbkey = (xtkbdkey & 0x100) >> 1 | (ktkbdkey & 0x7f)
like this ?
== From 7ea5214b7832acbb7bae81d7d8ceeaa19890e32b Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Date: Thu, 25 Aug 2011 10:29:57 +0900 Subject: [PATCH] fix to adjust xt_kbd scancode
The keycode in http://git.gnome.org/browse/gtk-vnc/plain/src/keymaps.csv handles escaped scancode in different way from qemu's one.
all escaped scancode "e0 ??" are encoded as "0x100 | ??" in this csv. But qemu handles escaped scancode as "0x80 | ??" and this scancode is more common. --- src/util/virkeycode-mapgen.py | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/src/util/virkeycode-mapgen.py b/src/util/virkeycode-mapgen.py index acf7364..5d83a39 100755 --- a/src/util/virkeycode-mapgen.py +++ b/src/util/virkeycode-mapgen.py @@ -14,6 +14,7 @@ import sys import re
namecolums = (0,2,10) +xtkbdkey_index = 8
def quotestring(str): if str[0] != '"': @@ -38,7 +39,18 @@ for line in sys.stdin.xreadlines(): for i in namecolums: b = b + (a[i] and quotestring(a[i]) or 'NULL') + ',' for i in [ x for x in range(12) if not x in namecolums ]: - b = b + (a[i] or '0') + ',' + if i != xtkbdkey_index : + b = b + (a[i] or '0') + ',' + elif a[i] == '' : + b = b + '0' + ',' + else : + # RFB keycodes are XT kbd keycodes with a slightly + # different encoding of 0xe0 scan codes. RFB uses + # the high bit of the first byte, instead of the low + # bit of the second byte. + code = int(a[i]) + code = (code & 0x100) >> 1 | (code & 0x7f) + b = b + str(code) + ',' print " { " + b + "},"
print '};'
This is not quite right. We don't want to change the XT KBD codeset since that's defined that way by the Linux driver. We instead want to add a new RFB codeset and make the QEMU driver use that. Check out this patch
https://www.redhat.com/archives/libvir-list/2011-August/msg01256.html
In my tests it made 'virsh send-key f16x86_64 KEY_RIGHTCTRL KEY_C' work correctly
Okay, thank you. -Kame
participants (3)
-
Daniel P. Berrange
-
KAMEZAWA Hiroyuki
-
Lai Jiangshan