aboutsummaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2017-05-16 14:42:07 +0200
committerPierre Ossman <ossman@cendio.se>2017-09-11 16:40:12 +0200
commit22348f22266d5552711da38dd562300696df9a95 (patch)
tree0928da474e8626a3ad14927988019217820cf1e5 /unix
parent7423417f7a4da1da90b4d31b9cbeadce83668126 (diff)
downloadtigervnc-22348f22266d5552711da38dd562300696df9a95.tar.gz
tigervnc-22348f22266d5552711da38dd562300696df9a95.zip
Add support for raw key codes to Xvnc/libvnc.so
Diffstat (limited to 'unix')
-rw-r--r--unix/xserver/hw/vnc/Input.c79
-rw-r--r--unix/xserver/hw/vnc/Input.h2
-rw-r--r--unix/xserver/hw/vnc/Makefile.am2
-rw-r--r--unix/xserver/hw/vnc/XserverDesktop.cc10
-rw-r--r--unix/xserver/hw/vnc/Xvnc.man7
-rw-r--r--unix/xserver/hw/vnc/qnum_to_xorgevdev.c245
-rw-r--r--unix/xserver/hw/vnc/qnum_to_xorgkbd.c121
7 files changed, 456 insertions, 10 deletions
diff --git a/unix/xserver/hw/vnc/Input.c b/unix/xserver/hw/vnc/Input.c
index 998121b4..a50f33a8 100644
--- a/unix/xserver/hw/vnc/Input.c
+++ b/unix/xserver/hw/vnc/Input.c
@@ -44,6 +44,11 @@ extern _X_EXPORT DevPrivateKey CoreDevicePrivateKey;
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+extern const unsigned short code_map_qnum_to_xorgevdev[];
+extern const unsigned int code_map_qnum_to_xorgevdev_len;
+extern const unsigned short code_map_qnum_to_xorgkbd[];
+extern const unsigned int code_map_qnum_to_xorgkbd_len;
+
#define BUTTONS 7
/* Event queue is shared between all devices. */
@@ -57,6 +62,9 @@ DeviceIntPtr vncPointerDev;
static int oldButtonMask;
static int cursorPosX, cursorPosY;
+static const unsigned short *codeMap;
+static unsigned int codeMapLen;
+
static KeySym pressedKeys[256];
static int vncPointerProc(DeviceIntPtr pDevice, int onoff);
@@ -64,6 +72,8 @@ static void vncKeyboardBell(int percent, DeviceIntPtr device,
void * ctrl, int class);
static int vncKeyboardProc(DeviceIntPtr pDevice, int onoff);
+static void vncKeysymKeyboardEvent(KeySym keysym, int down);
+
#define LOG_NAME "Input"
#define LOG_ERROR(...) vncLogError(LOG_NAME, __VA_ARGS__)
@@ -88,6 +98,19 @@ void vncInitInputDevice(void)
if ((vncPointerDev != NULL) || (vncKeyboardDev != NULL))
return;
+ /*
+ * On Linux we try to provide the same key codes as Xorg with
+ * the evdev driver. On other platforms we mimic the older
+ * Xorg KBD driver.
+ */
+#ifdef __linux__
+ codeMap = code_map_qnum_to_xorgevdev;
+ codeMapLen = code_map_qnum_to_xorgevdev_len;
+#else
+ codeMap = code_map_qnum_to_xorgkbd;
+ codeMapLen = code_map_qnum_to_xorgkbd_len;
+#endif
+
for (i = 0;i < 256;i++)
pressedKeys[i] = NoSymbol;
@@ -322,6 +345,48 @@ static inline void pressKey(DeviceIntPtr dev, int kc, Bool down, const char *msg
#endif
}
+/*
+ * vncKeyboardEvent() - add X11 events for the given RFB key event
+ */
+void vncKeyboardEvent(KeySym keysym, unsigned xtcode, int down)
+{
+ /* Simple case: the client has specified the key */
+ if (xtcode && xtcode < codeMapLen) {
+ int keycode;
+
+ keycode = codeMap[xtcode];
+ if (!keycode) {
+ /*
+ * Figure something out based on keysym if we
+ * cannot find a mapping.
+ */
+ if (keysym)
+ vncKeysymKeyboardEvent(keysym, down);
+ return;
+ }
+
+ /*
+ * We update the state table in case we get a mix of
+ * events with and without key codes.
+ */
+ if (down)
+ pressedKeys[keycode] = keysym;
+ else
+ pressedKeys[keycode] = NoSymbol;
+
+ pressKey(vncKeyboardDev, keycode, down, "raw keycode");
+ mieqProcessInputEvents();
+ return;
+ }
+
+ /*
+ * Advanced case: We have to figure out a sequence of keys that
+ * result in the given keysym
+ */
+ if (keysym)
+ vncKeysymKeyboardEvent(keysym, down);
+}
+
/* altKeysym is a table of alternative keysyms which have the same meaning. */
static struct altKeysym_t {
@@ -372,14 +437,14 @@ static struct altKeysym_t {
};
/*
- * vncKeyboardEvent() - work out the best keycode corresponding to the keysym
- * sent by the viewer. This is basically impossible in the general case, but
- * we make a best effort by assuming that all useful keysyms can be reached
- * using just the Shift and Level 3 (AltGr) modifiers. For core keyboards this
- * is basically always true, and should be true for most sane, western XKB
- * layouts.
+ * vncKeysymKeyboardEvent() - work out the best keycode corresponding
+ * to the keysym sent by the viewer. This is basically impossible in
+ * the general case, but we make a best effort by assuming that all
+ * useful keysyms can be reached using just the Shift and
+ * Level 3 (AltGr) modifiers. For core keyboards this is basically
+ * always true, and should be true for most sane, western XKB layouts.
*/
-void vncKeyboardEvent(KeySym keysym, int down)
+static void vncKeysymKeyboardEvent(KeySym keysym, int down)
{
int i;
unsigned state, new_state;
diff --git a/unix/xserver/hw/vnc/Input.h b/unix/xserver/hw/vnc/Input.h
index 67b9c8db..a9d067f2 100644
--- a/unix/xserver/hw/vnc/Input.h
+++ b/unix/xserver/hw/vnc/Input.h
@@ -36,7 +36,7 @@ void vncPointerButtonAction(int buttonMask);
void vncPointerMove(int x, int y);
void vncGetPointerPos(int *x, int *y);
-void vncKeyboardEvent(KeySym keysym, int down);
+void vncKeyboardEvent(KeySym keysym, unsigned xtcode, int down);
/* Backend dependent functions below here */
diff --git a/unix/xserver/hw/vnc/Makefile.am b/unix/xserver/hw/vnc/Makefile.am
index 0d6a4ac4..24a40b3d 100644
--- a/unix/xserver/hw/vnc/Makefile.am
+++ b/unix/xserver/hw/vnc/Makefile.am
@@ -18,7 +18,7 @@ HDRS = vncExtInit.h vncHooks.h \
libvnccommon_la_SOURCES = $(HDRS) \
vncExt.c vncExtInit.cc vncHooks.c vncSelection.c \
vncBlockHandler.c XorgGlue.c RFBGlue.cc XserverDesktop.cc \
- Input.c InputXKB.c
+ Input.c InputXKB.c qnum_to_xorgevdev.c qnum_to_xorgkbd.c
libvnccommon_la_CPPFLAGS = -DVENDOR_RELEASE="$(VENDOR_RELEASE)" \
-DVENDOR_STRING="\"$(VENDOR_STRING)\"" -I$(TIGERVNC_SRCDIR)/common -UHAVE_CONFIG_H \
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
index 031fb535..2131db65 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -53,6 +53,11 @@ using namespace network;
static LogWriter vlog("XserverDesktop");
+BoolParameter rawKeyboard("RawKeyboard",
+ "Send keyboard events straight through and "
+ "avoid mapping them to the current keyboard "
+ "layout", false);
+
class FileHTTPServer : public rfb::HTTPServer {
public:
FileHTTPServer(XserverDesktop* d) : desktop(d) {}
@@ -773,5 +778,8 @@ void XserverDesktop::grabRegion(const rfb::Region& region)
void XserverDesktop::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
{
- vncKeyboardEvent(keysym, down);
+ if (!rawKeyboard)
+ keycode = 0;
+
+ vncKeyboardEvent(keysym, keycode, down);
}
diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man
index 04e8f94b..6d867ec7 100644
--- a/unix/xserver/hw/vnc/Xvnc.man
+++ b/unix/xserver/hw/vnc/Xvnc.man
@@ -305,6 +305,13 @@ extra fake Shift events but may result in a slightly different symbol
(e.g. a Return instead of a keypad Enter).
.
.TP
+.B \-RawKeyboard
+Send keyboard events straight through and avoid mapping them to the current
+keyboard layout. This effectively makes the keyboard behave according to the
+layout configured on the server instead of the layout configured on the
+client. Default is off.
+.
+.TP
.B \-AllowOverride
Comma separated list of parameters that can be modified using VNC extension.
Parameters can be modified for example using \fBvncconfig\fP(1) program from
diff --git a/unix/xserver/hw/vnc/qnum_to_xorgevdev.c b/unix/xserver/hw/vnc/qnum_to_xorgevdev.c
new file mode 100644
index 00000000..357c88d1
--- /dev/null
+++ b/unix/xserver/hw/vnc/qnum_to_xorgevdev.c
@@ -0,0 +1,245 @@
+/*
+ * This file is auto-generated from keymaps.csv on 2017-08-28 13:03
+ * Database checksum sha256(f8aeff0c3430077a350e3d7ba2b335b381bd929ac4b193413730a402ff3f0097)
+ * To re-generate, run:
+ * keymap-gen --lang=stdc code-map keymaps.csv qnum xorgevdev
+*/
+const unsigned short code_map_qnum_to_xorgevdev[254] = {
+ [0x1] = 0x9, /* qnum:1 -> linux:1 (KEY_ESC) -> xorgevdev:9 */
+ [0x2] = 0xa, /* qnum:2 -> linux:2 (KEY_1) -> xorgevdev:10 */
+ [0x3] = 0xb, /* qnum:3 -> linux:3 (KEY_2) -> xorgevdev:11 */
+ [0x4] = 0xc, /* qnum:4 -> linux:4 (KEY_3) -> xorgevdev:12 */
+ [0x5] = 0xd, /* qnum:5 -> linux:5 (KEY_4) -> xorgevdev:13 */
+ [0x6] = 0xe, /* qnum:6 -> linux:6 (KEY_5) -> xorgevdev:14 */
+ [0x7] = 0xf, /* qnum:7 -> linux:7 (KEY_6) -> xorgevdev:15 */
+ [0x8] = 0x10, /* qnum:8 -> linux:8 (KEY_7) -> xorgevdev:16 */
+ [0x9] = 0x11, /* qnum:9 -> linux:9 (KEY_8) -> xorgevdev:17 */
+ [0xa] = 0x12, /* qnum:10 -> linux:10 (KEY_9) -> xorgevdev:18 */
+ [0xb] = 0x13, /* qnum:11 -> linux:11 (KEY_0) -> xorgevdev:19 */
+ [0xc] = 0x14, /* qnum:12 -> linux:12 (KEY_MINUS) -> xorgevdev:20 */
+ [0xd] = 0x15, /* qnum:13 -> linux:13 (KEY_EQUAL) -> xorgevdev:21 */
+ [0xe] = 0x16, /* qnum:14 -> linux:14 (KEY_BACKSPACE) -> xorgevdev:22 */
+ [0xf] = 0x17, /* qnum:15 -> linux:15 (KEY_TAB) -> xorgevdev:23 */
+ [0x10] = 0x18, /* qnum:16 -> linux:16 (KEY_Q) -> xorgevdev:24 */
+ [0x11] = 0x19, /* qnum:17 -> linux:17 (KEY_W) -> xorgevdev:25 */
+ [0x12] = 0x1a, /* qnum:18 -> linux:18 (KEY_E) -> xorgevdev:26 */
+ [0x13] = 0x1b, /* qnum:19 -> linux:19 (KEY_R) -> xorgevdev:27 */
+ [0x14] = 0x1c, /* qnum:20 -> linux:20 (KEY_T) -> xorgevdev:28 */
+ [0x15] = 0x1d, /* qnum:21 -> linux:21 (KEY_Y) -> xorgevdev:29 */
+ [0x16] = 0x1e, /* qnum:22 -> linux:22 (KEY_U) -> xorgevdev:30 */
+ [0x17] = 0x1f, /* qnum:23 -> linux:23 (KEY_I) -> xorgevdev:31 */
+ [0x18] = 0x20, /* qnum:24 -> linux:24 (KEY_O) -> xorgevdev:32 */
+ [0x19] = 0x21, /* qnum:25 -> linux:25 (KEY_P) -> xorgevdev:33 */
+ [0x1a] = 0x22, /* qnum:26 -> linux:26 (KEY_LEFTBRACE) -> xorgevdev:34 */
+ [0x1b] = 0x23, /* qnum:27 -> linux:27 (KEY_RIGHTBRACE) -> xorgevdev:35 */
+ [0x1c] = 0x24, /* qnum:28 -> linux:28 (KEY_ENTER) -> xorgevdev:36 */
+ [0x1d] = 0x25, /* qnum:29 -> linux:29 (KEY_LEFTCTRL) -> xorgevdev:37 */
+ [0x1e] = 0x26, /* qnum:30 -> linux:30 (KEY_A) -> xorgevdev:38 */
+ [0x1f] = 0x27, /* qnum:31 -> linux:31 (KEY_S) -> xorgevdev:39 */
+ [0x20] = 0x28, /* qnum:32 -> linux:32 (KEY_D) -> xorgevdev:40 */
+ [0x21] = 0x29, /* qnum:33 -> linux:33 (KEY_F) -> xorgevdev:41 */
+ [0x22] = 0x2a, /* qnum:34 -> linux:34 (KEY_G) -> xorgevdev:42 */
+ [0x23] = 0x2b, /* qnum:35 -> linux:35 (KEY_H) -> xorgevdev:43 */
+ [0x24] = 0x2c, /* qnum:36 -> linux:36 (KEY_J) -> xorgevdev:44 */
+ [0x25] = 0x2d, /* qnum:37 -> linux:37 (KEY_K) -> xorgevdev:45 */
+ [0x26] = 0x2e, /* qnum:38 -> linux:38 (KEY_L) -> xorgevdev:46 */
+ [0x27] = 0x2f, /* qnum:39 -> linux:39 (KEY_SEMICOLON) -> xorgevdev:47 */
+ [0x28] = 0x30, /* qnum:40 -> linux:40 (KEY_APOSTROPHE) -> xorgevdev:48 */
+ [0x29] = 0x31, /* qnum:41 -> linux:41 (KEY_GRAVE) -> xorgevdev:49 */
+ [0x2a] = 0x32, /* qnum:42 -> linux:42 (KEY_LEFTSHIFT) -> xorgevdev:50 */
+ [0x2b] = 0x33, /* qnum:43 -> linux:43 (KEY_BACKSLASH) -> xorgevdev:51 */
+ [0x2c] = 0x34, /* qnum:44 -> linux:44 (KEY_Z) -> xorgevdev:52 */
+ [0x2d] = 0x35, /* qnum:45 -> linux:45 (KEY_X) -> xorgevdev:53 */
+ [0x2e] = 0x36, /* qnum:46 -> linux:46 (KEY_C) -> xorgevdev:54 */
+ [0x2f] = 0x37, /* qnum:47 -> linux:47 (KEY_V) -> xorgevdev:55 */
+ [0x30] = 0x38, /* qnum:48 -> linux:48 (KEY_B) -> xorgevdev:56 */
+ [0x31] = 0x39, /* qnum:49 -> linux:49 (KEY_N) -> xorgevdev:57 */
+ [0x32] = 0x3a, /* qnum:50 -> linux:50 (KEY_M) -> xorgevdev:58 */
+ [0x33] = 0x3b, /* qnum:51 -> linux:51 (KEY_COMMA) -> xorgevdev:59 */
+ [0x34] = 0x3c, /* qnum:52 -> linux:52 (KEY_DOT) -> xorgevdev:60 */
+ [0x35] = 0x3d, /* qnum:53 -> linux:53 (KEY_SLASH) -> xorgevdev:61 */
+ [0x36] = 0x3e, /* qnum:54 -> linux:54 (KEY_RIGHTSHIFT) -> xorgevdev:62 */
+ [0x37] = 0x3f, /* qnum:55 -> linux:55 (KEY_KPASTERISK) -> xorgevdev:63 */
+ [0x38] = 0x40, /* qnum:56 -> linux:56 (KEY_LEFTALT) -> xorgevdev:64 */
+ [0x39] = 0x41, /* qnum:57 -> linux:57 (KEY_SPACE) -> xorgevdev:65 */
+ [0x3a] = 0x42, /* qnum:58 -> linux:58 (KEY_CAPSLOCK) -> xorgevdev:66 */
+ [0x3b] = 0x43, /* qnum:59 -> linux:59 (KEY_F1) -> xorgevdev:67 */
+ [0x3c] = 0x44, /* qnum:60 -> linux:60 (KEY_F2) -> xorgevdev:68 */
+ [0x3d] = 0x45, /* qnum:61 -> linux:61 (KEY_F3) -> xorgevdev:69 */
+ [0x3e] = 0x46, /* qnum:62 -> linux:62 (KEY_F4) -> xorgevdev:70 */
+ [0x3f] = 0x47, /* qnum:63 -> linux:63 (KEY_F5) -> xorgevdev:71 */
+ [0x40] = 0x48, /* qnum:64 -> linux:64 (KEY_F6) -> xorgevdev:72 */
+ [0x41] = 0x49, /* qnum:65 -> linux:65 (KEY_F7) -> xorgevdev:73 */
+ [0x42] = 0x4a, /* qnum:66 -> linux:66 (KEY_F8) -> xorgevdev:74 */
+ [0x43] = 0x4b, /* qnum:67 -> linux:67 (KEY_F9) -> xorgevdev:75 */
+ [0x44] = 0x4c, /* qnum:68 -> linux:68 (KEY_F10) -> xorgevdev:76 */
+ [0x45] = 0x4d, /* qnum:69 -> linux:69 (KEY_NUMLOCK) -> xorgevdev:77 */
+ [0x46] = 0x4e, /* qnum:70 -> linux:70 (KEY_SCROLLLOCK) -> xorgevdev:78 */
+ [0x47] = 0x4f, /* qnum:71 -> linux:71 (KEY_KP7) -> xorgevdev:79 */
+ [0x48] = 0x50, /* qnum:72 -> linux:72 (KEY_KP8) -> xorgevdev:80 */
+ [0x49] = 0x51, /* qnum:73 -> linux:73 (KEY_KP9) -> xorgevdev:81 */
+ [0x4a] = 0x52, /* qnum:74 -> linux:74 (KEY_KPMINUS) -> xorgevdev:82 */
+ [0x4b] = 0x53, /* qnum:75 -> linux:75 (KEY_KP4) -> xorgevdev:83 */
+ [0x4c] = 0x54, /* qnum:76 -> linux:76 (KEY_KP5) -> xorgevdev:84 */
+ [0x4d] = 0x55, /* qnum:77 -> linux:77 (KEY_KP6) -> xorgevdev:85 */
+ [0x4e] = 0x56, /* qnum:78 -> linux:78 (KEY_KPPLUS) -> xorgevdev:86 */
+ [0x4f] = 0x57, /* qnum:79 -> linux:79 (KEY_KP1) -> xorgevdev:87 */
+ [0x50] = 0x58, /* qnum:80 -> linux:80 (KEY_KP2) -> xorgevdev:88 */
+ [0x51] = 0x59, /* qnum:81 -> linux:81 (KEY_KP3) -> xorgevdev:89 */
+ [0x52] = 0x5a, /* qnum:82 -> linux:82 (KEY_KP0) -> xorgevdev:90 */
+ [0x53] = 0x5b, /* qnum:83 -> linux:83 (KEY_KPDOT) -> xorgevdev:91 */
+ [0x54] = 0x6b, /* qnum:84 -> linux:99 (KEY_SYSRQ) -> xorgevdev:107 */
+ [0x55] = 0xc2, /* qnum:85 -> linux:186 (KEY_F16) -> xorgevdev:194 */
+ [0x56] = 0x5e, /* qnum:86 -> linux:86 (KEY_102ND) -> xorgevdev:94 */
+ [0x57] = 0x5f, /* qnum:87 -> linux:87 (KEY_F11) -> xorgevdev:95 */
+ [0x58] = 0x60, /* qnum:88 -> linux:88 (KEY_F12) -> xorgevdev:96 */
+ [0x59] = 0x7d, /* qnum:89 -> linux:117 (KEY_KPEQUAL) -> xorgevdev:125 */
+ [0x5a] = 0xc6, /* qnum:90 -> linux:190 (KEY_F20) -> xorgevdev:198 */
+ [0x5b] = 0x6d, /* qnum:91 -> linux:101 (KEY_LINEFEED) -> xorgevdev:109 */
+ [0x5c] = 0x67, /* qnum:92 -> linux:95 (KEY_KPJPCOMMA) -> xorgevdev:103 */
+ [0x5d] = 0xbf, /* qnum:93 -> linux:183 (KEY_F13) -> xorgevdev:191 */
+ [0x5e] = 0xc0, /* qnum:94 -> linux:184 (KEY_F14) -> xorgevdev:192 */
+ [0x5f] = 0xc1, /* qnum:95 -> linux:185 (KEY_F15) -> xorgevdev:193 */
+ [0x63] = 0xb1, /* qnum:99 -> linux:169 (KEY_PHONE) -> xorgevdev:177 */
+ [0x64] = 0x8e, /* qnum:100 -> linux:134 (KEY_OPEN) -> xorgevdev:142 */
+ [0x65] = 0x8f, /* qnum:101 -> linux:135 (KEY_PASTE) -> xorgevdev:143 */
+ [0x66] = 0x95, /* qnum:102 -> linux:141 (KEY_SETUP) -> xorgevdev:149 */
+ [0x67] = 0x98, /* qnum:103 -> linux:144 (KEY_FILE) -> xorgevdev:152 */
+ [0x68] = 0x99, /* qnum:104 -> linux:145 (KEY_SENDFILE) -> xorgevdev:153 */
+ [0x69] = 0x9a, /* qnum:105 -> linux:146 (KEY_DELETEFILE) -> xorgevdev:154 */
+ [0x6a] = 0x9f, /* qnum:106 -> linux:151 (KEY_MSDOS) -> xorgevdev:159 */
+ [0x6b] = 0xa1, /* qnum:107 -> linux:153 (KEY_DIRECTION) -> xorgevdev:161 */
+ [0x6c] = 0xa9, /* qnum:108 -> linux:161 (KEY_EJECTCD) -> xorgevdev:169 */
+ [0x6d] = 0xc9, /* qnum:109 -> linux:193 (KEY_F23) -> xorgevdev:201 */
+ [0x6f] = 0xca, /* qnum:111 -> linux:194 (KEY_F24) -> xorgevdev:202 */
+ [0x70] = 0xb2, /* qnum:112 -> linux:170 (KEY_ISO) -> xorgevdev:178 */
+ [0x71] = 0xb6, /* qnum:113 -> linux:174 (KEY_EXIT) -> xorgevdev:182 */
+ [0x72] = 0xb7, /* qnum:114 -> linux:175 (KEY_MOVE) -> xorgevdev:183 */
+ [0x73] = 0x61, /* qnum:115 -> linux:89 (KEY_RO) -> xorgevdev:97 */
+ [0x74] = 0xc7, /* qnum:116 -> linux:191 (KEY_F21) -> xorgevdev:199 */
+ [0x75] = 0xb9, /* qnum:117 -> linux:177 (KEY_SCROLLUP) -> xorgevdev:185 */
+ [0x76] = 0x5d, /* qnum:118 -> linux:85 (KEY_ZENKAKUHANKAKU) -> xorgevdev:93 */
+ [0x77] = 0x63, /* qnum:119 -> linux:91 (KEY_HIRAGANA) -> xorgevdev:99 */
+ [0x78] = 0x62, /* qnum:120 -> linux:90 (KEY_KATAKANA) -> xorgevdev:98 */
+ [0x79] = 0x64, /* qnum:121 -> linux:92 (KEY_HENKAN) -> xorgevdev:100 */
+ [0x7b] = 0x66, /* qnum:123 -> linux:94 (KEY_MUHENKAN) -> xorgevdev:102 */
+ [0x7d] = 0x84, /* qnum:125 -> linux:124 (KEY_YEN) -> xorgevdev:132 */
+ [0x7e] = 0x81, /* qnum:126 -> linux:121 (KEY_KPCOMMA) -> xorgevdev:129 */
+ [0x81] = 0xb3, /* qnum:129 -> linux:171 (KEY_CONFIG) -> xorgevdev:179 */
+ [0x82] = 0x9e, /* qnum:130 -> linux:150 (KEY_WWW) -> xorgevdev:158 */
+ [0x83] = 0xc3, /* qnum:131 -> linux:187 (KEY_F17) -> xorgevdev:195 */
+ [0x84] = 0xc5, /* qnum:132 -> linux:189 (KEY_F19) -> xorgevdev:197 */
+ [0x85] = 0x89, /* qnum:133 -> linux:129 (KEY_AGAIN) -> xorgevdev:137 */
+ [0x86] = 0x8a, /* qnum:134 -> linux:130 (KEY_PROPS) -> xorgevdev:138 */
+ [0x87] = 0x8b, /* qnum:135 -> linux:131 (KEY_UNDO) -> xorgevdev:139 */
+ [0x88] = 0xb8, /* qnum:136 -> linux:176 (KEY_EDIT) -> xorgevdev:184 */
+ [0x89] = 0xbd, /* qnum:137 -> linux:181 (KEY_NEW) -> xorgevdev:189 */
+ [0x8a] = 0xbe, /* qnum:138 -> linux:182 (KEY_REDO) -> xorgevdev:190 */
+ [0x8b] = 0x80, /* qnum:139 -> linux:120 (KEY_SCALE) -> xorgevdev:128 */
+ [0x8c] = 0x8c, /* qnum:140 -> linux:132 (KEY_FRONT) -> xorgevdev:140 */
+ [0x8d] = 0x83, /* qnum:141 -> linux:123 (KEY_HANJA) -> xorgevdev:131 */
+ [0x8e] = 0xf1, /* qnum:142 -> linux:233 (KEY_FORWARDMAIL) -> xorgevdev:241 */
+ [0x8f] = 0xba, /* qnum:143 -> linux:178 (KEY_SCROLLDOWN) -> xorgevdev:186 */
+ [0x90] = 0xad, /* qnum:144 -> linux:165 (KEY_PREVIOUSSONG) -> xorgevdev:173 */
+ [0x92] = 0xa0, /* qnum:146 -> linux:152 (KEY_SCREENLOCK) -> xorgevdev:160 */
+ [0x93] = 0x9b, /* qnum:147 -> linux:147 (KEY_XFER) -> xorgevdev:155 */
+ [0x94] = 0xe6, /* qnum:148 -> linux:222 (KEY_ALTERASE) -> xorgevdev:230 */
+ [0x95] = 0xcb, /* qnum:149 -> linux:195 (unnamed) -> xorgevdev:203 */
+ [0x96] = 0xcc, /* qnum:150 -> linux:196 (unnamed) -> xorgevdev:204 */
+ [0x97] = 0x9d, /* qnum:151 -> linux:149 (KEY_PROG2) -> xorgevdev:157 */
+ [0x98] = 0xb0, /* qnum:152 -> linux:168 (KEY_REWIND) -> xorgevdev:176 */
+ [0x99] = 0xab, /* qnum:153 -> linux:163 (KEY_NEXTSONG) -> xorgevdev:171 */
+ [0x9a] = 0xcd, /* qnum:154 -> linux:197 (unnamed) -> xorgevdev:205 */
+ [0x9b] = 0xce, /* qnum:155 -> linux:198 (unnamed) -> xorgevdev:206 */
+ [0x9c] = 0x68, /* qnum:156 -> linux:96 (KEY_KPENTER) -> xorgevdev:104 */
+ [0x9d] = 0x69, /* qnum:157 -> linux:97 (KEY_RIGHTCTRL) -> xorgevdev:105 */
+ [0x9e] = 0x93, /* qnum:158 -> linux:139 (KEY_MENU) -> xorgevdev:147 */
+ [0x9f] = 0x9c, /* qnum:159 -> linux:148 (KEY_PROG1) -> xorgevdev:156 */
+ [0xa0] = 0x79, /* qnum:160 -> linux:113 (KEY_MUTE) -> xorgevdev:121 */
+ [0xa1] = 0x94, /* qnum:161 -> linux:140 (KEY_CALC) -> xorgevdev:148 */
+ [0xa2] = 0xac, /* qnum:162 -> linux:164 (KEY_PLAYPAUSE) -> xorgevdev:172 */
+ [0xa3] = 0xa8, /* qnum:163 -> linux:160 (KEY_CLOSECD) -> xorgevdev:168 */
+ [0xa4] = 0xae, /* qnum:164 -> linux:166 (KEY_STOPCD) -> xorgevdev:174 */
+ [0xa5] = 0xd5, /* qnum:165 -> linux:205 (KEY_SUSPEND) -> xorgevdev:213 */
+ [0xa6] = 0xa2, /* qnum:166 -> linux:154 (KEY_CYCLEWINDOWS) -> xorgevdev:162 */
+ [0xa7] = 0xcf, /* qnum:167 -> linux:199 (unnamed) -> xorgevdev:207 */
+ [0xa8] = 0xd0, /* qnum:168 -> linux:200 (KEY_PLAYCD) -> xorgevdev:208 */
+ [0xa9] = 0xd1, /* qnum:169 -> linux:201 (KEY_PAUSECD) -> xorgevdev:209 */
+ [0xab] = 0xd2, /* qnum:171 -> linux:202 (KEY_PROG3) -> xorgevdev:210 */
+ [0xac] = 0xd3, /* qnum:172 -> linux:203 (KEY_PROG4) -> xorgevdev:211 */
+ [0xad] = 0xd4, /* qnum:173 -> linux:204 (KEY_DASHBOARD) -> xorgevdev:212 */
+ [0xae] = 0x7a, /* qnum:174 -> linux:114 (KEY_VOLUMEDOWN) -> xorgevdev:122 */
+ [0xaf] = 0xd6, /* qnum:175 -> linux:206 (KEY_CLOSE) -> xorgevdev:214 */
+ [0xb0] = 0x7b, /* qnum:176 -> linux:115 (KEY_VOLUMEUP) -> xorgevdev:123 */
+ [0xb1] = 0xaf, /* qnum:177 -> linux:167 (KEY_RECORD) -> xorgevdev:175 */
+ [0xb2] = 0xb4, /* qnum:178 -> linux:172 (KEY_HOMEPAGE) -> xorgevdev:180 */
+ [0xb3] = 0xd7, /* qnum:179 -> linux:207 (KEY_PLAY) -> xorgevdev:215 */
+ [0xb4] = 0xd8, /* qnum:180 -> linux:208 (KEY_FASTFORWARD) -> xorgevdev:216 */
+ [0xb5] = 0x6a, /* qnum:181 -> linux:98 (KEY_KPSLASH) -> xorgevdev:106 */
+ [0xb6] = 0xd9, /* qnum:182 -> linux:209 (KEY_BASSBOOST) -> xorgevdev:217 */
+ [0xb8] = 0x6c, /* qnum:184 -> linux:100 (KEY_RIGHTALT) -> xorgevdev:108 */
+ [0xb9] = 0xda, /* qnum:185 -> linux:210 (KEY_PRINT) -> xorgevdev:218 */
+ [0xba] = 0xdb, /* qnum:186 -> linux:211 (KEY_HP) -> xorgevdev:219 */
+ [0xbb] = 0xdc, /* qnum:187 -> linux:212 (KEY_CAMERA) -> xorgevdev:220 */
+ [0xbc] = 0x91, /* qnum:188 -> linux:137 (KEY_CUT) -> xorgevdev:145 */
+ [0xbd] = 0xdd, /* qnum:189 -> linux:213 (KEY_SOUND) -> xorgevdev:221 */
+ [0xbe] = 0xde, /* qnum:190 -> linux:214 (KEY_QUESTION) -> xorgevdev:222 */
+ [0xbf] = 0xdf, /* qnum:191 -> linux:215 (KEY_EMAIL) -> xorgevdev:223 */
+ [0xc0] = 0xe0, /* qnum:192 -> linux:216 (KEY_CHAT) -> xorgevdev:224 */
+ [0xc1] = 0x90, /* qnum:193 -> linux:136 (KEY_FIND) -> xorgevdev:144 */
+ [0xc2] = 0xe2, /* qnum:194 -> linux:218 (KEY_CONNECT) -> xorgevdev:226 */
+ [0xc3] = 0xe3, /* qnum:195 -> linux:219 (KEY_FINANCE) -> xorgevdev:227 */
+ [0xc4] = 0xe4, /* qnum:196 -> linux:220 (KEY_SPORT) -> xorgevdev:228 */
+ [0xc5] = 0xe5, /* qnum:197 -> linux:221 (KEY_SHOP) -> xorgevdev:229 */
+ [0xc6] = 0x7f, /* qnum:198 -> linux:119 (KEY_PAUSE) -> xorgevdev:127 */
+ [0xc7] = 0x6e, /* qnum:199 -> linux:102 (KEY_HOME) -> xorgevdev:110 */
+ [0xc8] = 0x6f, /* qnum:200 -> linux:103 (KEY_UP) -> xorgevdev:111 */
+ [0xc9] = 0x70, /* qnum:201 -> linux:104 (KEY_PAGEUP) -> xorgevdev:112 */
+ [0xca] = 0xe7, /* qnum:202 -> linux:223 (KEY_CANCEL) -> xorgevdev:231 */
+ [0xcb] = 0x71, /* qnum:203 -> linux:105 (KEY_LEFT) -> xorgevdev:113 */
+ [0xcc] = 0xe8, /* qnum:204 -> linux:224 (KEY_BRIGHTNESSDOWN) -> xorgevdev:232 */
+ [0xcd] = 0x72, /* qnum:205 -> linux:106 (KEY_RIGHT) -> xorgevdev:114 */
+ [0xce] = 0x7e, /* qnum:206 -> linux:118 (KEY_KPPLUSMINUS) -> xorgevdev:126 */
+ [0xcf] = 0x73, /* qnum:207 -> linux:107 (KEY_END) -> xorgevdev:115 */
+ [0xd0] = 0x74, /* qnum:208 -> linux:108 (KEY_DOWN) -> xorgevdev:116 */
+ [0xd1] = 0x75, /* qnum:209 -> linux:109 (KEY_PAGEDOWN) -> xorgevdev:117 */
+ [0xd2] = 0x76, /* qnum:210 -> linux:110 (KEY_INSERT) -> xorgevdev:118 */
+ [0xd3] = 0x77, /* qnum:211 -> linux:111 (KEY_DELETE) -> xorgevdev:119 */
+ [0xd4] = 0xe9, /* qnum:212 -> linux:225 (KEY_BRIGHTNESSUP) -> xorgevdev:233 */
+ [0xd5] = 0xf2, /* qnum:213 -> linux:234 (KEY_SAVE) -> xorgevdev:242 */
+ [0xd6] = 0xeb, /* qnum:214 -> linux:227 (KEY_SWITCHVIDEOMODE) -> xorgevdev:235 */
+ [0xd7] = 0xec, /* qnum:215 -> linux:228 (KEY_KBDILLUMTOGGLE) -> xorgevdev:236 */
+ [0xd8] = 0xed, /* qnum:216 -> linux:229 (KEY_KBDILLUMDOWN) -> xorgevdev:237 */
+ [0xd9] = 0xee, /* qnum:217 -> linux:230 (KEY_KBDILLUMUP) -> xorgevdev:238 */
+ [0xda] = 0xef, /* qnum:218 -> linux:231 (KEY_SEND) -> xorgevdev:239 */
+ [0xdb] = 0x85, /* qnum:219 -> linux:125 (KEY_LEFTMETA) -> xorgevdev:133 */
+ [0xdc] = 0x86, /* qnum:220 -> linux:126 (KEY_RIGHTMETA) -> xorgevdev:134 */
+ [0xdd] = 0x87, /* qnum:221 -> linux:127 (KEY_COMPOSE) -> xorgevdev:135 */
+ [0xde] = 0x7c, /* qnum:222 -> linux:116 (KEY_POWER) -> xorgevdev:124 */
+ [0xdf] = 0x96, /* qnum:223 -> linux:142 (KEY_SLEEP) -> xorgevdev:150 */
+ [0xe3] = 0x97, /* qnum:227 -> linux:143 (KEY_WAKEUP) -> xorgevdev:151 */
+ [0xe4] = 0xf0, /* qnum:228 -> linux:232 (KEY_REPLY) -> xorgevdev:240 */
+ [0xe5] = 0xe1, /* qnum:229 -> linux:217 (KEY_SEARCH) -> xorgevdev:225 */
+ [0xe6] = 0xa4, /* qnum:230 -> linux:156 (KEY_BOOKMARKS) -> xorgevdev:164 */
+ [0xe7] = 0xb5, /* qnum:231 -> linux:173 (KEY_REFRESH) -> xorgevdev:181 */
+ [0xe8] = 0x88, /* qnum:232 -> linux:128 (KEY_STOP) -> xorgevdev:136 */
+ [0xe9] = 0xa7, /* qnum:233 -> linux:159 (KEY_FORWARD) -> xorgevdev:167 */
+ [0xea] = 0xa6, /* qnum:234 -> linux:158 (KEY_BACK) -> xorgevdev:166 */
+ [0xeb] = 0xa5, /* qnum:235 -> linux:157 (KEY_COMPUTER) -> xorgevdev:165 */
+ [0xec] = 0xa3, /* qnum:236 -> linux:155 (KEY_MAIL) -> xorgevdev:163 */
+ [0xed] = 0xea, /* qnum:237 -> linux:226 (KEY_MEDIA) -> xorgevdev:234 */
+ [0xef] = 0x78, /* qnum:239 -> linux:112 (KEY_MACRO) -> xorgevdev:120 */
+ [0xf0] = 0xf3, /* qnum:240 -> linux:235 (KEY_DOCUMENTS) -> xorgevdev:243 */
+ [0xf1] = 0xf4, /* qnum:241 -> linux:236 (KEY_BATTERY) -> xorgevdev:244 */
+ [0xf2] = 0xf5, /* qnum:242 -> linux:237 (KEY_BLUETOOTH) -> xorgevdev:245 */
+ [0xf3] = 0xf6, /* qnum:243 -> linux:238 (KEY_WLAN) -> xorgevdev:246 */
+ [0xf4] = 0xf7, /* qnum:244 -> linux:239 (KEY_UWB) -> xorgevdev:247 */
+ [0xf5] = 0x92, /* qnum:245 -> linux:138 (KEY_HELP) -> xorgevdev:146 */
+ [0xf6] = 0xbb, /* qnum:246 -> linux:179 (KEY_KPLEFTPAREN) -> xorgevdev:187 */
+ [0xf7] = 0xc4, /* qnum:247 -> linux:188 (KEY_F18) -> xorgevdev:196 */
+ [0xf8] = 0x8d, /* qnum:248 -> linux:133 (KEY_COPY) -> xorgevdev:141 */
+ [0xf9] = 0xc8, /* qnum:249 -> linux:192 (KEY_F22) -> xorgevdev:200 */
+ [0xfb] = 0xbc, /* qnum:251 -> linux:180 (KEY_KPRIGHTPAREN) -> xorgevdev:188 */
+ [0xfd] = 0xaa, /* qnum:253 -> linux:162 (KEY_EJECTCLOSECD) -> xorgevdev:170 */
+};
+const unsigned int code_map_qnum_to_xorgevdev_len = sizeof(code_map_qnum_to_xorgevdev)/sizeof(code_map_qnum_to_xorgevdev[0]);
diff --git a/unix/xserver/hw/vnc/qnum_to_xorgkbd.c b/unix/xserver/hw/vnc/qnum_to_xorgkbd.c
new file mode 100644
index 00000000..57c2047a
--- /dev/null
+++ b/unix/xserver/hw/vnc/qnum_to_xorgkbd.c
@@ -0,0 +1,121 @@
+/*
+ * This file is auto-generated from keymaps.csv on 2017-08-28 13:04
+ * Database checksum sha256(f8aeff0c3430077a350e3d7ba2b335b381bd929ac4b193413730a402ff3f0097)
+ * To re-generate, run:
+ * keymap-gen --lang=stdc code-map keymaps.csv qnum xorgkbd
+*/
+const unsigned short code_map_qnum_to_xorgkbd[254] = {
+ [0x1] = 0x9, /* qnum:1 -> linux:1 (KEY_ESC) -> xorgkbd:9 */
+ [0x2] = 0xa, /* qnum:2 -> linux:2 (KEY_1) -> xorgkbd:10 */
+ [0x3] = 0xb, /* qnum:3 -> linux:3 (KEY_2) -> xorgkbd:11 */
+ [0x4] = 0xc, /* qnum:4 -> linux:4 (KEY_3) -> xorgkbd:12 */
+ [0x5] = 0xd, /* qnum:5 -> linux:5 (KEY_4) -> xorgkbd:13 */
+ [0x6] = 0xe, /* qnum:6 -> linux:6 (KEY_5) -> xorgkbd:14 */
+ [0x7] = 0xf, /* qnum:7 -> linux:7 (KEY_6) -> xorgkbd:15 */
+ [0x8] = 0x10, /* qnum:8 -> linux:8 (KEY_7) -> xorgkbd:16 */
+ [0x9] = 0x11, /* qnum:9 -> linux:9 (KEY_8) -> xorgkbd:17 */
+ [0xa] = 0x12, /* qnum:10 -> linux:10 (KEY_9) -> xorgkbd:18 */
+ [0xb] = 0x13, /* qnum:11 -> linux:11 (KEY_0) -> xorgkbd:19 */
+ [0xc] = 0x14, /* qnum:12 -> linux:12 (KEY_MINUS) -> xorgkbd:20 */
+ [0xd] = 0x15, /* qnum:13 -> linux:13 (KEY_EQUAL) -> xorgkbd:21 */
+ [0xe] = 0x16, /* qnum:14 -> linux:14 (KEY_BACKSPACE) -> xorgkbd:22 */
+ [0xf] = 0x17, /* qnum:15 -> linux:15 (KEY_TAB) -> xorgkbd:23 */
+ [0x10] = 0x18, /* qnum:16 -> linux:16 (KEY_Q) -> xorgkbd:24 */
+ [0x11] = 0x19, /* qnum:17 -> linux:17 (KEY_W) -> xorgkbd:25 */
+ [0x12] = 0x1a, /* qnum:18 -> linux:18 (KEY_E) -> xorgkbd:26 */
+ [0x13] = 0x1b, /* qnum:19 -> linux:19 (KEY_R) -> xorgkbd:27 */
+ [0x14] = 0x1c, /* qnum:20 -> linux:20 (KEY_T) -> xorgkbd:28 */
+ [0x15] = 0x1d, /* qnum:21 -> linux:21 (KEY_Y) -> xorgkbd:29 */
+ [0x16] = 0x1e, /* qnum:22 -> linux:22 (KEY_U) -> xorgkbd:30 */
+ [0x17] = 0x1f, /* qnum:23 -> linux:23 (KEY_I) -> xorgkbd:31 */
+ [0x18] = 0x20, /* qnum:24 -> linux:24 (KEY_O) -> xorgkbd:32 */
+ [0x19] = 0x21, /* qnum:25 -> linux:25 (KEY_P) -> xorgkbd:33 */
+ [0x1a] = 0x22, /* qnum:26 -> linux:26 (KEY_LEFTBRACE) -> xorgkbd:34 */
+ [0x1b] = 0x23, /* qnum:27 -> linux:27 (KEY_RIGHTBRACE) -> xorgkbd:35 */
+ [0x1c] = 0x24, /* qnum:28 -> linux:28 (KEY_ENTER) -> xorgkbd:36 */
+ [0x1d] = 0x25, /* qnum:29 -> linux:29 (KEY_LEFTCTRL) -> xorgkbd:37 */
+ [0x1e] = 0x26, /* qnum:30 -> linux:30 (KEY_A) -> xorgkbd:38 */
+ [0x1f] = 0x27, /* qnum:31 -> linux:31 (KEY_S) -> xorgkbd:39 */
+ [0x20] = 0x28, /* qnum:32 -> linux:32 (KEY_D) -> xorgkbd:40 */
+ [0x21] = 0x29, /* qnum:33 -> linux:33 (KEY_F) -> xorgkbd:41 */
+ [0x22] = 0x2a, /* qnum:34 -> linux:34 (KEY_G) -> xorgkbd:42 */
+ [0x23] = 0x2b, /* qnum:35 -> linux:35 (KEY_H) -> xorgkbd:43 */
+ [0x24] = 0x2c, /* qnum:36 -> linux:36 (KEY_J) -> xorgkbd:44 */
+ [0x25] = 0x2d, /* qnum:37 -> linux:37 (KEY_K) -> xorgkbd:45 */
+ [0x26] = 0x2e, /* qnum:38 -> linux:38 (KEY_L) -> xorgkbd:46 */
+ [0x27] = 0x2f, /* qnum:39 -> linux:39 (KEY_SEMICOLON) -> xorgkbd:47 */
+ [0x28] = 0x30, /* qnum:40 -> linux:40 (KEY_APOSTROPHE) -> xorgkbd:48 */
+ [0x29] = 0x31, /* qnum:41 -> linux:41 (KEY_GRAVE) -> xorgkbd:49 */
+ [0x2a] = 0x32, /* qnum:42 -> linux:42 (KEY_LEFTSHIFT) -> xorgkbd:50 */
+ [0x2b] = 0x33, /* qnum:43 -> linux:43 (KEY_BACKSLASH) -> xorgkbd:51 */
+ [0x2c] = 0x34, /* qnum:44 -> linux:44 (KEY_Z) -> xorgkbd:52 */
+ [0x2d] = 0x35, /* qnum:45 -> linux:45 (KEY_X) -> xorgkbd:53 */
+ [0x2e] = 0x36, /* qnum:46 -> linux:46 (KEY_C) -> xorgkbd:54 */
+ [0x2f] = 0x37, /* qnum:47 -> linux:47 (KEY_V) -> xorgkbd:55 */
+ [0x30] = 0x38, /* qnum:48 -> linux:48 (KEY_B) -> xorgkbd:56 */
+ [0x31] = 0x39, /* qnum:49 -> linux:49 (KEY_N) -> xorgkbd:57 */
+ [0x32] = 0x3a, /* qnum:50 -> linux:50 (KEY_M) -> xorgkbd:58 */
+ [0x33] = 0x3b, /* qnum:51 -> linux:51 (KEY_COMMA) -> xorgkbd:59 */
+ [0x34] = 0x3c, /* qnum:52 -> linux:52 (KEY_DOT) -> xorgkbd:60 */
+ [0x35] = 0x3d, /* qnum:53 -> linux:53 (KEY_SLASH) -> xorgkbd:61 */
+ [0x36] = 0x3e, /* qnum:54 -> linux:54 (KEY_RIGHTSHIFT) -> xorgkbd:62 */
+ [0x37] = 0x3f, /* qnum:55 -> linux:55 (KEY_KPASTERISK) -> xorgkbd:63 */
+ [0x38] = 0x40, /* qnum:56 -> linux:56 (KEY_LEFTALT) -> xorgkbd:64 */
+ [0x39] = 0x41, /* qnum:57 -> linux:57 (KEY_SPACE) -> xorgkbd:65 */
+ [0x3a] = 0x42, /* qnum:58 -> linux:58 (KEY_CAPSLOCK) -> xorgkbd:66 */
+ [0x3b] = 0x43, /* qnum:59 -> linux:59 (KEY_F1) -> xorgkbd:67 */
+ [0x3c] = 0x44, /* qnum:60 -> linux:60 (KEY_F2) -> xorgkbd:68 */
+ [0x3d] = 0x45, /* qnum:61 -> linux:61 (KEY_F3) -> xorgkbd:69 */
+ [0x3e] = 0x46, /* qnum:62 -> linux:62 (KEY_F4) -> xorgkbd:70 */
+ [0x3f] = 0x47, /* qnum:63 -> linux:63 (KEY_F5) -> xorgkbd:71 */
+ [0x40] = 0x48, /* qnum:64 -> linux:64 (KEY_F6) -> xorgkbd:72 */
+ [0x41] = 0x49, /* qnum:65 -> linux:65 (KEY_F7) -> xorgkbd:73 */
+ [0x42] = 0x4a, /* qnum:66 -> linux:66 (KEY_F8) -> xorgkbd:74 */
+ [0x43] = 0x4b, /* qnum:67 -> linux:67 (KEY_F9) -> xorgkbd:75 */
+ [0x44] = 0x4c, /* qnum:68 -> linux:68 (KEY_F10) -> xorgkbd:76 */
+ [0x45] = 0x4d, /* qnum:69 -> linux:69 (KEY_NUMLOCK) -> xorgkbd:77 */
+ [0x46] = 0x4e, /* qnum:70 -> linux:70 (KEY_SCROLLLOCK) -> xorgkbd:78 */
+ [0x47] = 0x4f, /* qnum:71 -> linux:71 (KEY_KP7) -> xorgkbd:79 */
+ [0x48] = 0x50, /* qnum:72 -> linux:72 (KEY_KP8) -> xorgkbd:80 */
+ [0x49] = 0x51, /* qnum:73 -> linux:73 (KEY_KP9) -> xorgkbd:81 */
+ [0x4a] = 0x52, /* qnum:74 -> linux:74 (KEY_KPMINUS) -> xorgkbd:82 */
+ [0x4b] = 0x53, /* qnum:75 -> linux:75 (KEY_KP4) -> xorgkbd:83 */
+ [0x4c] = 0x54, /* qnum:76 -> linux:76 (KEY_KP5) -> xorgkbd:84 */
+ [0x4d] = 0x55, /* qnum:77 -> linux:77 (KEY_KP6) -> xorgkbd:85 */
+ [0x4e] = 0x56, /* qnum:78 -> linux:78 (KEY_KPPLUS) -> xorgkbd:86 */
+ [0x4f] = 0x57, /* qnum:79 -> linux:79 (KEY_KP1) -> xorgkbd:87 */
+ [0x50] = 0x58, /* qnum:80 -> linux:80 (KEY_KP2) -> xorgkbd:88 */
+ [0x51] = 0x59, /* qnum:81 -> linux:81 (KEY_KP3) -> xorgkbd:89 */
+ [0x52] = 0x5a, /* qnum:82 -> linux:82 (KEY_KP0) -> xorgkbd:90 */
+ [0x53] = 0x5b, /* qnum:83 -> linux:83 (KEY_KPDOT) -> xorgkbd:91 */
+ [0x54] = 0x6f, /* qnum:84 -> linux:99 (KEY_SYSRQ) -> xorgkbd:111 */
+ [0x55] = 0x79, /* qnum:85 -> linux:186 (KEY_F16) -> xorgkbd:121 */
+ [0x56] = 0x5e, /* qnum:86 -> linux:86 (KEY_102ND) -> xorgkbd:94 */
+ [0x57] = 0x5f, /* qnum:87 -> linux:87 (KEY_F11) -> xorgkbd:95 */
+ [0x58] = 0x60, /* qnum:88 -> linux:88 (KEY_F12) -> xorgkbd:96 */
+ [0x59] = 0x7e, /* qnum:89 -> linux:117 (KEY_KPEQUAL) -> xorgkbd:126 */
+ [0x5d] = 0x76, /* qnum:93 -> linux:183 (KEY_F13) -> xorgkbd:118 */
+ [0x5e] = 0x77, /* qnum:94 -> linux:184 (KEY_F14) -> xorgkbd:119 */
+ [0x5f] = 0x78, /* qnum:95 -> linux:185 (KEY_F15) -> xorgkbd:120 */
+ [0x7d] = 0x85, /* qnum:125 -> linux:124 (KEY_YEN) -> xorgkbd:133 */
+ [0x83] = 0x7a, /* qnum:131 -> linux:187 (KEY_F17) -> xorgkbd:122 */
+ [0x9c] = 0x6c, /* qnum:156 -> linux:96 (KEY_KPENTER) -> xorgkbd:108 */
+ [0x9d] = 0x6d, /* qnum:157 -> linux:97 (KEY_RIGHTCTRL) -> xorgkbd:109 */
+ [0xb5] = 0x70, /* qnum:181 -> linux:98 (KEY_KPSLASH) -> xorgkbd:112 */
+ [0xb8] = 0x71, /* qnum:184 -> linux:100 (KEY_RIGHTALT) -> xorgkbd:113 */
+ [0xc6] = 0x6e, /* qnum:198 -> linux:119 (KEY_PAUSE) -> xorgkbd:110 */
+ [0xc7] = 0x61, /* qnum:199 -> linux:102 (KEY_HOME) -> xorgkbd:97 */
+ [0xc8] = 0x62, /* qnum:200 -> linux:103 (KEY_UP) -> xorgkbd:98 */
+ [0xc9] = 0x63, /* qnum:201 -> linux:104 (KEY_PAGEUP) -> xorgkbd:99 */
+ [0xcb] = 0x64, /* qnum:203 -> linux:105 (KEY_LEFT) -> xorgkbd:100 */
+ [0xcd] = 0x66, /* qnum:205 -> linux:106 (KEY_RIGHT) -> xorgkbd:102 */
+ [0xcf] = 0x67, /* qnum:207 -> linux:107 (KEY_END) -> xorgkbd:103 */
+ [0xd0] = 0x68, /* qnum:208 -> linux:108 (KEY_DOWN) -> xorgkbd:104 */
+ [0xd1] = 0x69, /* qnum:209 -> linux:109 (KEY_PAGEDOWN) -> xorgkbd:105 */
+ [0xd2] = 0x6a, /* qnum:210 -> linux:110 (KEY_INSERT) -> xorgkbd:106 */
+ [0xd3] = 0x6b, /* qnum:211 -> linux:111 (KEY_DELETE) -> xorgkbd:107 */
+ [0xdb] = 0x73, /* qnum:219 -> linux:125 (KEY_LEFTMETA) -> xorgkbd:115 */
+ [0xdc] = 0x74, /* qnum:220 -> linux:126 (KEY_RIGHTMETA) -> xorgkbd:116 */
+ [0xdd] = 0x75, /* qnum:221 -> linux:127 (KEY_COMPOSE) -> xorgkbd:117 */
+};
+const unsigned int code_map_qnum_to_xorgkbd_len = sizeof(code_map_qnum_to_xorgkbd)/sizeof(code_map_qnum_to_xorgkbd[0]);