From 347519a4d8f3befb719f11eeb0121c736ce64dee Mon Sep 17 00:00:00 2001
From: David Skywalker <dantoine@gmail.com>
Date: Thu, 31 Jan 2019 12:50:58 +0100
Subject: [PATCH] now X11 driver using keycodes instead keysyms, fixes
 international layouts problems.

---
 gfx/common/x11_common.c          |  20 ++-
 input/drivers/x11_input.c        |  11 +-
 input/include/xfree86_keycodes.h | 176 ++++++++++++++++++++
 input/input_keymaps.c            | 269 ++++++++++++++-----------------
 4 files changed, 311 insertions(+), 165 deletions(-)
 create mode 100644 input/include/xfree86_keycodes.h

diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c
index 96693dd1ee..1916bc71e2 100644
--- a/gfx/common/x11_common.c
+++ b/gfx/common/x11_common.c
@@ -405,7 +405,7 @@ bool x11_get_metrics(void *data,
    return true;
 }
 
-static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
+static void x11_handle_key_event(unsigned keycode, XEvent *event, XIC ic, bool filter)
 {
    int i;
    Status status;
@@ -419,6 +419,7 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
 
    chars[0]       = '\0';
 
+   /* this code generates the localized chars using keysyms */
    if (!filter)
    {
       if (down)
@@ -454,8 +455,10 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
     * to feed it keysyms anyway, so here is a little hack... */
    if (keysym >= XK_A && keysym <= XK_Z)
        keysym += XK_z - XK_Z;
-
-   key   = input_keymaps_translate_keysym_to_rk(keysym);
+       
+   /* Get the real keycode,
+      that correctly ignores international layouts as windows code does. */
+   key     = input_keymaps_translate_keysym_to_rk(keycode);
 
    if (state & ShiftMask)
       mod |= RETROKMOD_SHIFT;
@@ -465,10 +468,10 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
       mod |= RETROKMOD_CTRL;
    if (state & Mod1Mask)
       mod |= RETROKMOD_ALT;
+   if (state & Mod2Mask)
+      mod |= RETROKMOD_NUMLOCK;
    if (state & Mod4Mask)
       mod |= RETROKMOD_META;
-   if (IsKeypadKey(keysym))
-      mod |= RETROKMOD_NUMLOCK;
 
    input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD);
 
@@ -483,9 +486,14 @@ bool x11_alive(void *data)
    {
       XEvent event;
       bool filter = false;
+      unsigned keycode = 0;
 
       /* Can get events from older windows. Check this. */
       XNextEvent(g_x11_dpy, &event);
+      
+      /* IMPORTANT - Get keycode before XFilterEvent
+         because the event is localizated after the call */
+      keycode = event.xkey.keycode;
       filter = XFilterEvent(&event, g_x11_win);
 
       switch (event.type)
@@ -548,7 +556,7 @@ bool x11_alive(void *data)
          case KeyPress:
          case KeyRelease:
             if (event.xkey.window == g_x11_win)
-               x11_handle_key_event(&event, g_x11_xic, filter);
+               x11_handle_key_event(keycode, &event, g_x11_xic, filter);
             break;
       }
    }
diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c
index 77cd53438d..4672333e6f 100644
--- a/input/drivers/x11_input.c
+++ b/input/drivers/x11_input.c
@@ -75,7 +75,7 @@ static void *x_input_init(const char *joypad_driver)
 
 static bool x_keyboard_pressed(x11_input_t *x11, unsigned key)
 {
-   int keycode = XKeysymToKeycode(x11->display, rarch_keysym_lut[(enum retro_key)key]);
+   int keycode = rarch_keysym_lut[(enum retro_key)key];
    return x11->state[keycode >> 3] & (1 << (keycode & 7));
 }
 
@@ -155,23 +155,20 @@ static int16_t x_pressed_analog(x11_input_t *x11,
    unsigned id_plus      = 0;
    int id_minus_key      = 0;
    int id_plus_key       = 0;
-   unsigned sym          = 0;
-   int keycode           = 0;
+   unsigned keycode      = 0;
 
    input_conv_analog_id_to_bind_id(idx, id, &id_minus, &id_plus);
 
    id_minus_key          = binds[id_minus].key;
    id_plus_key           = binds[id_plus].key;
 
-   sym                   = rarch_keysym_lut[(enum retro_key)id_minus_key];
-   keycode               = XKeysymToKeycode(x11->display, sym);
+   keycode               = rarch_keysym_lut[(enum retro_key)id_minus_key];
    if (      binds[id_minus].valid
          && (id_minus_key < RETROK_LAST)
          && (x11->state[keycode >> 3] & (1 << (keycode & 7))))
       pressed_minus = -0x7fff;
 
-   sym                   = rarch_keysym_lut[(enum retro_key)id_plus_key];
-   keycode               = XKeysymToKeycode(x11->display, sym);
+   keycode               = rarch_keysym_lut[(enum retro_key)id_plus_key];
    if (      binds[id_plus].valid
          && (id_plus_key < RETROK_LAST)
          && (x11->state[keycode >> 3] & (1 << (keycode & 7))))
diff --git a/input/include/xfree86_keycodes.h b/input/include/xfree86_keycodes.h
new file mode 100644
index 0000000000..827088f2ae
--- /dev/null
+++ b/input/include/xfree86_keycodes.h
@@ -0,0 +1,176 @@
+/*  RetroArch - A frontend for libretro.
+ *  Copyright (C) 2010-2014 - Hans-Kristian Arntzen
+ *  Copyright (C) 2011-2017 - Daniel De Matteis
+ *
+ *  RetroArch is free software: you can redistribute it and/or modify it under the terms
+ *  of the GNU General Public License as published by the Free Software Found-
+ *  ation, either version 3 of the License, or (at your option) any later version.
+ *
+ *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ *  PURPOSE.  See the GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with RetroArch.
+ *  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* generated from /usr/share/X11/xkb/keycodes/evdev */
+
+#ifndef __XFREE86_KEYCODES__H
+#define __XFREE86_KEYCODES__H
+
+enum xfvk_key
+{
+   XFVK_UNKNOWN        = 0,
+   XFVK_FIRST          = 0,
+   
+   XFVK_ESC            = 9,
+   XFVK_FK01           = 67,
+   XFVK_FK02           = 68,
+   XFVK_FK03           = 69,
+   XFVK_FK04           = 70,
+   XFVK_FK05           = 71,
+   XFVK_FK06           = 72,
+   XFVK_FK07           = 73,
+   XFVK_FK08           = 74,
+   XFVK_FK09           = 75,
+   XFVK_FK10           = 76,
+   XFVK_FK11           = 95,
+   XFVK_FK12           = 96,
+
+   // Added for pc105 compatibility
+   XFVK_LSGT           = 94,
+   XFVK_TLDE           = 49,
+   XFVK_AE01           = 10,
+   XFVK_AE02           = 11,
+   XFVK_AE03           = 12,
+   XFVK_AE04           = 13,
+   XFVK_AE05           = 14,
+   XFVK_AE06           = 15,
+   XFVK_AE07           = 16,
+   XFVK_AE08           = 17,
+   XFVK_AE09           = 18,
+   XFVK_AE10           = 19,
+   XFVK_AE11           = 20,
+   XFVK_AE12           = 21,
+   XFVK_BKSP           = 22,
+
+   XFVK_TAB            = 23,
+   XFVK_AD01           = 24,
+   XFVK_AD02           = 25,
+   XFVK_AD03           = 26,
+   XFVK_AD04           = 27,
+   XFVK_AD05           = 28,
+   XFVK_AD06           = 29,
+   XFVK_AD07           = 30,
+   XFVK_AD08           = 31,
+   XFVK_AD09           = 32,
+   XFVK_AD10           = 33,
+   XFVK_AD11           = 34,
+   XFVK_AD12           = 35,
+   XFVK_BKSL           = 51,
+   XFVK_AC12           = XFVK_BKSL,
+   XFVK_RTRN           = 36,
+
+   XFVK_CAPS           = 66,
+   XFVK_AC01           = 38,
+   XFVK_AC02           = 39,
+   XFVK_AC03           = 40,
+   XFVK_AC04           = 41,
+   XFVK_AC05           = 42,
+   XFVK_AC06           = 43,
+   XFVK_AC07           = 44,
+   XFVK_AC08           = 45,
+   XFVK_AC09           = 46,
+   XFVK_AC10           = 47,
+   XFVK_AC11           = 48,
+
+   XFVK_LFSH           = 50,
+   XFVK_AB01           = 52,
+   XFVK_AB02           = 53,
+   XFVK_AB03           = 54,
+   XFVK_AB04           = 55,
+   XFVK_AB05           = 56,
+   XFVK_AB06           = 57,
+   XFVK_AB07           = 58,
+   XFVK_AB08           = 59,
+   XFVK_AB09           = 60,
+   XFVK_AB10           = 61,
+   XFVK_RTSH           = 62,
+
+   XFVK_LALT           = 64,
+   XFVK_LCTL           = 37,
+   XFVK_SPCE           = 65,
+   XFVK_RCTL           = 105,
+   XFVK_RALT           = 108,
+	
+   XFVK_PRSC           = 107,
+	// SYRQ            = 107,
+   XFVK_SCLK           = 78,
+   XFVK_PAUS           = 127,
+	// BRK             = 419,
+
+   XFVK_INS            = 118,
+   XFVK_HOME           = 110,
+   XFVK_PGUP           = 112,
+   XFVK_DELE           = 119,
+   XFVK_END            = 115,
+   XFVK_PGDN           = 117,
+
+   XFVK_UP             = 111,
+   XFVK_LEFT           = 113,
+   XFVK_DOWN           = 116,
+   XFVK_RGHT           = 114,
+
+   XFVK_NMLK           = 77,
+   XFVK_KPDV           = 106,
+   XFVK_KPMU           = 63,
+   XFVK_KPSU           = 82,
+
+   XFVK_KP7            = 79,
+   XFVK_KP8            = 80,
+   XFVK_KP9            = 81,
+   XFVK_KPAD           = 86,
+
+   XFVK_KP4            = 83,
+   XFVK_KP5            = 84,
+   XFVK_KP6            = 85,
+
+   XFVK_KP1            = 87,
+   XFVK_KP2            = 88,
+   XFVK_KP3            = 89,
+   XFVK_KPEN           = 104,
+
+   XFVK_KP0            = 90,
+   XFVK_KPDL           = 91,
+   XFVK_KPEQ           = 125,
+
+
+   // Microsoft keyboard extra keys
+   XFVK_LWIN           = 133,
+   XFVK_RWIN           = 134,
+   XFVK_COMP           = 135,
+   XFVK_MENU           = XFVK_COMP,
+
+   // Extended keys
+   XFVK_CALC           = 148,
+
+   XFVK_FK13           = 191,
+   XFVK_FK14           = 192,
+   XFVK_FK15           = 193,
+   XFVK_FK16           = 194,
+   XFVK_FK17           = 195,
+   XFVK_FK18           = 196,
+   XFVK_FK19           = 197,
+   XFVK_FK20           = 198,
+   XFVK_FK21           = 199,
+   XFVK_FK22           = 200,
+   XFVK_FK23           = 201,
+   XFVK_FK24           = 202,
+
+   XFVK_LAST,
+   XFVK_DUMMY          = 255
+};
+	
+#endif /* __XFREE86_KEYCODES__H */
+
diff --git a/input/input_keymaps.c b/input/input_keymaps.c
index 522f77ae32..48d9855320 100644
--- a/input/input_keymaps.c
+++ b/input/input_keymaps.c
@@ -50,9 +50,7 @@
 #endif
 
 #ifdef HAVE_X11
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/keysym.h>
+#include "input/include/xfree86_keycodes.h"
 #endif
 
 #ifdef HAVE_DINPUT
@@ -693,156 +691,123 @@ const struct rarch_key_map rarch_key_map_wiiu[] = {
 
 #ifdef HAVE_X11
 
-#ifndef XF68XK_Calculator
-#define XF86XK_Calculator          0x1008FF1D
-#endif
-
 const struct rarch_key_map rarch_key_map_x11[] = {
-   { XK_BackSpace, RETROK_BACKSPACE },
-   { XK_Tab, RETROK_TAB },
-   { XK_Clear, RETROK_CLEAR },
-   { XK_Return, RETROK_RETURN },
-   { XK_Pause, RETROK_PAUSE },
-   { XK_Escape, RETROK_ESCAPE },
-   { XK_space, RETROK_SPACE },
-   { XK_exclam, RETROK_EXCLAIM },
-   { XK_quotedbl, RETROK_QUOTEDBL },
-   { XK_numbersign, RETROK_HASH },
-   { XK_dollar, RETROK_DOLLAR },
-   { XK_ampersand, RETROK_AMPERSAND },
-   { XK_apostrophe, RETROK_QUOTE },
-   { XK_parenleft, RETROK_LEFTPAREN },
-   { XK_parenright, RETROK_RIGHTPAREN },
-   { XK_asterisk, RETROK_ASTERISK },
-   { XK_plus, RETROK_PLUS },
-   { XK_comma, RETROK_COMMA },
-   { XK_minus, RETROK_MINUS },
-   { XK_period, RETROK_PERIOD },
-   { XK_slash, RETROK_SLASH },
-   { XK_0, RETROK_0 },
-   { XK_1, RETROK_1 },
-   { XK_2, RETROK_2 },
-   { XK_3, RETROK_3 },
-   { XK_4, RETROK_4 },
-   { XK_5, RETROK_5 },
-   { XK_6, RETROK_6 },
-   { XK_7, RETROK_7 },
-   { XK_8, RETROK_8 },
-   { XK_9, RETROK_9 },
-   { XK_colon, RETROK_COLON },
-   { XK_semicolon, RETROK_SEMICOLON },
-   { XK_less, RETROK_LESS },
-   { XK_equal, RETROK_EQUALS },
-   { XK_greater, RETROK_GREATER },
-   { XK_question, RETROK_QUESTION },
-   { XK_at, RETROK_AT },
-   { XK_bracketleft, RETROK_LEFTBRACKET },
-   { XK_backslash, RETROK_BACKSLASH },
-   { XK_bracketright, RETROK_RIGHTBRACKET },
-   { XK_dead_circumflex, RETROK_CARET },
-   { XK_underscore, RETROK_UNDERSCORE },
-   { XK_grave, RETROK_BACKQUOTE },
-   { XK_a, RETROK_a },
-   { XK_b, RETROK_b },
-   { XK_c, RETROK_c },
-   { XK_d, RETROK_d },
-   { XK_e, RETROK_e },
-   { XK_f, RETROK_f },
-   { XK_g, RETROK_g },
-   { XK_h, RETROK_h },
-   { XK_i, RETROK_i },
-   { XK_j, RETROK_j },
-   { XK_k, RETROK_k },
-   { XK_l, RETROK_l },
-   { XK_m, RETROK_m },
-   { XK_n, RETROK_n },
-   { XK_o, RETROK_o },
-   { XK_p, RETROK_p },
-   { XK_q, RETROK_q },
-   { XK_r, RETROK_r },
-   { XK_s, RETROK_s },
-   { XK_t, RETROK_t },
-   { XK_u, RETROK_u },
-   { XK_v, RETROK_v },
-   { XK_w, RETROK_w },
-   { XK_x, RETROK_x },
-   { XK_y, RETROK_y },
-   { XK_z, RETROK_z },
-   { XK_Delete, RETROK_DELETE },
-   { XK_KP_0, RETROK_KP0 },
-   { XK_KP_1, RETROK_KP1 },
-   { XK_KP_2, RETROK_KP2 },
-   { XK_KP_3, RETROK_KP3 },
-   { XK_KP_4, RETROK_KP4 },
-   { XK_KP_5, RETROK_KP5 },
-   { XK_KP_6, RETROK_KP6 },
-   { XK_KP_7, RETROK_KP7 },
-   { XK_KP_8, RETROK_KP8 },
-   { XK_KP_9, RETROK_KP9 },
-   { XK_KP_Decimal, RETROK_KP_PERIOD },
-   { XK_KP_Divide, RETROK_KP_DIVIDE },
-   { XK_KP_Multiply, RETROK_KP_MULTIPLY },
-   { XK_KP_Subtract, RETROK_KP_MINUS },
-   { XK_KP_Add, RETROK_KP_PLUS },
-   { XK_KP_Enter, RETROK_KP_ENTER },
-   { XK_KP_Equal, RETROK_KP_EQUALS },
-   { XK_Up, RETROK_UP },
-   { XK_Down, RETROK_DOWN },
-   { XK_Right, RETROK_RIGHT },
-   { XK_Left, RETROK_LEFT },
-   { XK_Insert, RETROK_INSERT },
-   { XK_Home, RETROK_HOME },
-   { XK_End, RETROK_END },
-   { XK_Page_Up, RETROK_PAGEUP },
-   { XK_Page_Down, RETROK_PAGEDOWN },
-   { XK_F1, RETROK_F1 },
-   { XK_F2, RETROK_F2 },
-   { XK_F3, RETROK_F3 },
-   { XK_F4, RETROK_F4 },
-   { XK_F5, RETROK_F5 },
-   { XK_F6, RETROK_F6 },
-   { XK_F7, RETROK_F7 },
-   { XK_F8, RETROK_F8 },
-   { XK_F9, RETROK_F9 },
-   { XK_F10, RETROK_F10 },
-   { XK_F11, RETROK_F11 },
-   { XK_F12, RETROK_F12 },
-   { XK_F13, RETROK_F13 },
-   { XK_F14, RETROK_F14 },
-   { XK_F15, RETROK_F15 },
-   { XK_Num_Lock, RETROK_NUMLOCK },
-   { XK_Caps_Lock, RETROK_CAPSLOCK },
-   { XK_Scroll_Lock, RETROK_SCROLLOCK },
-   { XK_Shift_R, RETROK_RSHIFT },
-   { XK_Shift_L, RETROK_LSHIFT },
-   { XK_Control_R, RETROK_RCTRL },
-   { XK_Control_L, RETROK_LCTRL },
-   { XK_Alt_R, RETROK_RALT },
-   { XK_Alt_L, RETROK_LALT },
-   { XK_Meta_R, RETROK_RMETA },
-   { XK_Meta_L, RETROK_LMETA },
-   { XK_Super_L, RETROK_LSUPER },
-   { XK_Super_R, RETROK_RSUPER },
-   { XK_Mode_switch, RETROK_MODE },
-   { XK_Multi_key, RETROK_COMPOSE },
-   { XK_Help, RETROK_HELP },
-   { XK_Print, RETROK_PRINT },
-   { XK_Sys_Req, RETROK_SYSREQ },
-   { XK_Break, RETROK_BREAK },
-   { XK_Menu, RETROK_MENU },
-   /*{ ?, RETROK_POWER },*/
-   { XK_EuroSign, RETROK_EURO },
-   { XK_Undo, RETROK_UNDO },
-   /*{ ?, RETROK_OEM_102 },*/
-   /* FIXME(shizeeg): RetroArch can't handle these buttons atm.
-    * Do we really need RETROK_KP_INSERT, RETROK_KP_END,
-    * RETROK_KP_DOWN, RETROK_KP_PAGEDOWN ???
-    *
-   { XK_KP_Insert,  RETROK_KP0 },
-   { XK_KP_End,  RETROK_KP1 },
-   { XK_KP_Down,  RETROK_KP2 },
-   { XK_KP_Page_Down,  RETROK_KP3 },*/
-   { XF86XK_Calculator, RETROK_HELP },
+
+   { XFVK_ESC, RETROK_ESCAPE },
+   { XFVK_FK01, RETROK_F1 },
+   { XFVK_FK02, RETROK_F2 },
+   { XFVK_FK03, RETROK_F3 },
+   { XFVK_FK04, RETROK_F4 },
+   { XFVK_FK05, RETROK_F5 },
+   { XFVK_FK06, RETROK_F6 },
+   { XFVK_FK07, RETROK_F7 },
+   { XFVK_FK08, RETROK_F8 },
+   { XFVK_FK09, RETROK_F9 },
+   { XFVK_FK10, RETROK_F10 },
+   { XFVK_FK11, RETROK_F11 },
+   { XFVK_FK12, RETROK_F12 },
+
+   { XFVK_TLDE, RETROK_BACKQUOTE },
+   { XFVK_AE01, RETROK_1 },
+   { XFVK_AE02, RETROK_2 },
+   { XFVK_AE03, RETROK_3 },
+   { XFVK_AE04, RETROK_4 },
+   { XFVK_AE05, RETROK_5 },
+   { XFVK_AE06, RETROK_6 },
+   { XFVK_AE07, RETROK_7 },
+   { XFVK_AE08, RETROK_8 },
+   { XFVK_AE09, RETROK_9 },
+   { XFVK_AE10, RETROK_0 },
+   { XFVK_AE11, RETROK_MINUS },
+   { XFVK_AE12, RETROK_EQUALS },
+   { XFVK_BKSP, RETROK_BACKSPACE },
+
+   { XFVK_TAB, RETROK_TAB },
+   { XFVK_AD01, RETROK_q },
+   { XFVK_AD02, RETROK_w },
+   { XFVK_AD03, RETROK_e },
+   { XFVK_AD04, RETROK_r },
+   { XFVK_AD05, RETROK_t },
+   { XFVK_AD06, RETROK_y },
+   { XFVK_AD07, RETROK_u },
+   { XFVK_AD08, RETROK_i },
+   { XFVK_AD09, RETROK_o },
+   { XFVK_AD10, RETROK_p },
+   { XFVK_AD11, RETROK_LEFTBRACKET },
+   { XFVK_AD12, RETROK_RIGHTBRACKET },
+   { XFVK_RTRN, RETROK_RETURN },
+
+   { XFVK_CAPS, RETROK_CAPSLOCK },
+   { XFVK_AC01, RETROK_a },
+   { XFVK_AC02, RETROK_s },
+   { XFVK_AC03, RETROK_d },
+   { XFVK_AC04, RETROK_f },
+   { XFVK_AC05, RETROK_g },
+   { XFVK_AC06, RETROK_h },
+   { XFVK_AC07, RETROK_j },
+   { XFVK_AC08, RETROK_k },
+   { XFVK_AC09, RETROK_l },
+   { XFVK_AC10, RETROK_SEMICOLON },
+   { XFVK_AC11, RETROK_QUOTE },
+   { XFVK_AC12, RETROK_BACKSLASH },
+
+   { XFVK_LFSH, RETROK_LSHIFT },
+   { XFVK_AB01, RETROK_z },
+   { XFVK_AB02, RETROK_x },
+   { XFVK_AB03, RETROK_c },
+   { XFVK_AB04, RETROK_v },
+   { XFVK_AB05, RETROK_b },
+   { XFVK_AB06, RETROK_n },
+   { XFVK_AB07, RETROK_m },
+   { XFVK_AB08, RETROK_COMMA },
+   { XFVK_AB09, RETROK_PERIOD },
+   { XFVK_AB10, RETROK_SLASH },
+   { XFVK_RTSH, RETROK_RSHIFT },
+
+   { XFVK_LALT, RETROK_LALT },
+   { XFVK_LCTL, RETROK_LCTRL },
+   { XFVK_SPCE, RETROK_SPACE },
+   { XFVK_RCTL, RETROK_RCTRL },
+   { XFVK_RALT, RETROK_RALT },
+
+   { XFVK_LSGT, RETROK_OEM_102 },
+   { XFVK_MENU, RETROK_MENU },
+   { XFVK_LWIN, RETROK_LSUPER },
+   { XFVK_RWIN, RETROK_RSUPER },
+   { XFVK_CALC, RETROK_HELP },
+
+   { XFVK_PRSC, RETROK_PRINT },
+   { XFVK_SCLK, RETROK_SCROLLOCK },
+   { XFVK_PAUS, RETROK_PAUSE },
+   { XFVK_INS, RETROK_INSERT },
+   { XFVK_HOME, RETROK_HOME },
+   { XFVK_PGUP, RETROK_PAGEUP },
+   { XFVK_DELE, RETROK_DELETE },
+   { XFVK_END, RETROK_END },
+   { XFVK_PGDN, RETROK_PAGEDOWN },
+   { XFVK_UP, RETROK_UP },
+   { XFVK_LEFT, RETROK_LEFT },
+   { XFVK_DOWN, RETROK_DOWN },
+   { XFVK_RGHT, RETROK_RIGHT },
+
+   { XFVK_NMLK, RETROK_NUMLOCK },
+   { XFVK_KPDV, RETROK_KP_DIVIDE },
+   { XFVK_KPMU, RETROK_KP_MULTIPLY },
+   { XFVK_KPSU, RETROK_KP_MINUS },
+   { XFVK_KP7, RETROK_KP7 },
+   { XFVK_KP8, RETROK_KP8 },
+   { XFVK_KP9, RETROK_KP9 },
+   { XFVK_KPAD, RETROK_KP_PLUS },
+   { XFVK_KP4, RETROK_KP4 },
+   { XFVK_KP5, RETROK_KP5 },
+   { XFVK_KP6, RETROK_KP6 },
+   { XFVK_KP1, RETROK_KP1 },
+   { XFVK_KP2, RETROK_KP2 },
+   { XFVK_KP3, RETROK_KP3 },
+   { XFVK_KPEN, RETROK_KP_ENTER },
+   { XFVK_KP0, RETROK_KP0 },
+   { XFVK_KPDL, RETROK_KP_PERIOD },
+   { XFVK_KPEQ, RETROK_KP_EQUALS },
 
    { 0, RETROK_UNKNOWN },
 };