]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix keymap used to talk with QEMU
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 25 Aug 2011 16:45:49 +0000 (17:45 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 26 Aug 2011 13:18:57 +0000 (14:18 +0100)
The QEMU 'sendkey' command expects keys to be encoded in the same
way as the RFB extended keycode set. Specifically it wants extended
keys to have the high bit of the first byte set, while the Linux
XT KBD driver codeset uses the low bit of the second byte. To deal
with this we introduce a new keymap 'RFB' and use that in the QEMU
driver

* include/libvirt/libvirt.h.in: Add VIR_KEYCODE_SET_RFB
* src/qemu/qemu_driver.c: Use RFB keycode set instead of XT KBD
* src/util/virkeycode-mapgen.py: Auto-generate the RFB keycode
  set from the XT KBD set
* src/util/virkeycode.c: Add RFB keycode entry to table. Add a
  verify check on cardinality of the codeOffset table

include/libvirt/libvirt.h.in
src/qemu/qemu_driver.c
src/util/virkeycode-mapgen.py
src/util/virkeycode.c

index aa29fb66946b5bb892e3e1b7962dfda3ddd9dc76..53a2f7d6f2d46415c39f51ed51a663c40bab1092 100644 (file)
@@ -1875,6 +1875,7 @@ typedef enum {
     VIR_KEYCODE_SET_XT_KBD         = 6,
     VIR_KEYCODE_SET_USB            = 7,
     VIR_KEYCODE_SET_WIN32          = 8,
+    VIR_KEYCODE_SET_RFB            = 9,
 
     VIR_KEYCODE_SET_LAST,
 } virKeycodeSet;
index b5268e4330f128d9acced3720da85848ee13f114..f21122d930dc8ae8b89d99eebbffac2930b4e069 100644 (file)
@@ -1889,17 +1889,17 @@ static int qemuDomainSendKey(virDomainPtr domain,
 
     virCheckFlags(0, -1);
 
-    /* translate the keycode to XT_KBD for qemu driver */
-    if (codeset != VIR_KEYCODE_SET_XT_KBD) {
+    /* translate the keycode to RFB for qemu driver */
+    if (codeset != VIR_KEYCODE_SET_RFB) {
         int i;
         int keycode;
 
         for (i = 0; i < nkeycodes; i++) {
-            keycode = virKeycodeValueTranslate(codeset, VIR_KEYCODE_SET_XT_KBD,
+            keycode = virKeycodeValueTranslate(codeset, VIR_KEYCODE_SET_RFB,
                                                keycodes[i]);
             if (keycode < 0) {
                 qemuReportError(VIR_ERR_INTERNAL_ERROR,
-             _("cannot translate keycode %u of %s codeset to xt_kbd keycode"),
+             _("cannot translate keycode %u of %s codeset to rfb keycode"),
                                 keycodes[i],
                                 virKeycodeSetTypeToString(codeset));
                 return -1;
index acf736421552dbf61aa1fa3eab526020eb74d991..d3d2aae1c01db7fca3fd4b95376013124c217d74 100755 (executable)
@@ -14,6 +14,7 @@ import sys
 import re
 
 namecolums = (0,2,10)
+xtkbdkey_index = 8
 
 def quotestring(str):
     if str[0] != '"':
@@ -35,10 +36,21 @@ sys.stdin.readline() # eat the fist line.
 for line in sys.stdin.xreadlines():
     a = re.match("([^,]*)," * 13 + "([^,]*)$", line[0:-1]).groups()
     b = ""
+    rfbkey = 0
     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:
+            # 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 = int(a[i] or '0')
+            rfbkey = (rfbkey & 0x100) >> 1 | (rfbkey & 0x7f)
+
+    # Append RFB keycode as the last column
+    b = b + str(rfbkey)
     print "    { " + b + "},"
 
 print '};'
index 0d427677d6023f61c679065c8c02db050cc3360f..f85fe4ac5d5e86b17febfc762ac8ae6fdde9c927 100644 (file)
@@ -38,6 +38,7 @@ struct keycode {
     unsigned short xt_kbd;
     unsigned short usb;
     unsigned short win32;
+    unsigned short rfb;
 };
 
 #define VIRT_KEY_INTERNAL
@@ -62,7 +63,10 @@ static unsigned int codeOffset[] = {
         offsetof(struct keycode, usb),
     [VIR_KEYCODE_SET_WIN32] =
         offsetof(struct keycode, win32),
+    [VIR_KEYCODE_SET_RFB] =
+        offsetof(struct keycode, rfb),
 };
+verify(ARRAY_CARDINALITY(codeOffset) == VIR_KEYCODE_SET_LAST);
 
 VIR_ENUM_IMPL(virKeycodeSet, VIR_KEYCODE_SET_LAST,
     "linux",
@@ -74,6 +78,7 @@ VIR_ENUM_IMPL(virKeycodeSet, VIR_KEYCODE_SET_LAST,
     "xt_kbd",
     "usb",
     "win32",
+    "rfb",
 );
 
 static int __virKeycodeValueFromString(unsigned int name_offset,