First pass of new SDL scancode concept for X11.
authorSam Lantinga <slouken@libsdl.org>
Thu, 07 Feb 2008 15:31:09 +0000
changeset 2305 fbe8ff44c519
parent 2304 50f58ce12497
child 2306 1a8bab15a45d
First pass of new SDL scancode concept for X11.
include/SDL_keysym.h
include/SDL_scancode.h
src/events/SDL_keyboard.c
src/events/scancodes_darwin.h
src/events/scancodes_linux.h
src/events/scancodes_xfree86.h
src/video/cocoa/SDL_cocoakeyboard.m
src/video/cocoa/SDL_cocoakeys.h
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11keyboard.c
src/video/x11/SDL_x11keyboard.h
src/video/x11/SDL_x11sym.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
test/checkkeys.c
--- a/include/SDL_keysym.h	Tue Feb 05 07:30:50 2008 +0000
+++ b/include/SDL_keysym.h	Thu Feb 07 15:31:09 2008 +0000
@@ -221,6 +221,7 @@
     SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY),
     SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE),
     SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT),
+    SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW),
     SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL),
     SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR),
     SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER),
--- a/include/SDL_scancode.h	Tue Feb 05 07:30:50 2008 +0000
+++ b/include/SDL_scancode.h	Thu Feb 07 15:31:09 2008 +0000
@@ -91,7 +91,7 @@
     SDL_SCANCODE_TAB = 43,
     SDL_SCANCODE_SPACE = 44,
 
-    SDL_SCANCODE_HYPHENMINUS = 45,
+    SDL_SCANCODE_MINUS = 45,
     SDL_SCANCODE_EQUALS = 46,
     SDL_SCANCODE_LEFTBRACKET = 47,
     SDL_SCANCODE_RIGHTBRACKET = 48,
@@ -286,27 +286,28 @@
     SDL_SCANCODE_AUDIOPLAY = 261,
     SDL_SCANCODE_AUDIOMUTE = 262,
     SDL_SCANCODE_MEDIASELECT = 263,
-    SDL_SCANCODE_MAIL = 264,
-    SDL_SCANCODE_CALCULATOR = 265,
-    SDL_SCANCODE_COMPUTER = 266,
-    SDL_SCANCODE_AC_SEARCH = 267,
-    SDL_SCANCODE_AC_HOME = 268,
-    SDL_SCANCODE_AC_BACK = 269,
-    SDL_SCANCODE_AC_FORWARD = 270,
-    SDL_SCANCODE_AC_STOP = 271,
-    SDL_SCANCODE_AC_REFRESH = 272,
-    SDL_SCANCODE_AC_BOOKMARKS = 273,
+    SDL_SCANCODE_WWW = 264,
+    SDL_SCANCODE_MAIL = 265,
+    SDL_SCANCODE_CALCULATOR = 266,
+    SDL_SCANCODE_COMPUTER = 267,
+    SDL_SCANCODE_AC_SEARCH = 268,
+    SDL_SCANCODE_AC_HOME = 269,
+    SDL_SCANCODE_AC_BACK = 270,
+    SDL_SCANCODE_AC_FORWARD = 271,
+    SDL_SCANCODE_AC_STOP = 272,
+    SDL_SCANCODE_AC_REFRESH = 273,
+    SDL_SCANCODE_AC_BOOKMARKS = 274,
 
     /* These are values that Christian Walther added (for mac keyboard?) */
 
-    SDL_SCANCODE_BRIGHTNESSDOWN = 274,
-    SDL_SCANCODE_BRIGHTNESSUP = 275,
-    SDL_SCANCODE_DISPLAYSWITCH = 276, /**< display mirroring/dual display switch, video mode switch */
-    SDL_SCANCODE_KBDILLUMTOGGLE = 277,
-    SDL_SCANCODE_KBDILLUMDOWN = 278,
-    SDL_SCANCODE_KBDILLUMUP = 279,
-    SDL_SCANCODE_EJECT = 280,
-    SDL_SCANCODE_SLEEP = 281,
+    SDL_SCANCODE_BRIGHTNESSDOWN = 275,
+    SDL_SCANCODE_BRIGHTNESSUP = 276,
+    SDL_SCANCODE_DISPLAYSWITCH = 277, /**< display mirroring/dual display switch, video mode switch */
+    SDL_SCANCODE_KBDILLUMTOGGLE = 278,
+    SDL_SCANCODE_KBDILLUMDOWN = 279,
+    SDL_SCANCODE_KBDILLUMUP = 280,
+    SDL_SCANCODE_EJECT = 281,
+    SDL_SCANCODE_SLEEP = 282,
 
     /* Add any other keys here */
 
--- a/src/events/SDL_keyboard.c	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/events/SDL_keyboard.c	Thu Feb 07 15:31:09 2008 +0000
@@ -242,6 +242,7 @@
     SDLK_AUDIOPLAY,
     SDLK_AUDIOMUTE,
     SDLK_MEDIASELECT,
+    SDLK_WWW,
     SDLK_MAIL,
     SDLK_CALCULATOR,
     SDLK_COMPUTER,
@@ -473,6 +474,7 @@
     "AudioPlay",
     "AudioMute",
     "MediaSelect",
+    "WWW",
     "Mail",
     "Calculator",
     "Computer",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/scancodes_darwin.h	Thu Feb 07 15:31:09 2008 +0000
@@ -0,0 +1,160 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/* Mac virtual key code to SDLKey mapping table
+   Sources:
+   - Inside Macintosh: Text <http://developer.apple.com/documentation/mac/Text/Text-571.html>
+   - Apple USB keyboard driver source <http://darwinsource.opendarwin.org/10.4.6.ppc/IOHIDFamily-172.8/IOHIDFamily/Cosmo_USB2ADB.c>
+   - experimentation on various ADB and USB ISO keyboards and one ADB ANSI keyboard
+*/
+/* *INDENT-OFF* */
+static SDL_scancode darwin_scancode_table[] = {
+    /*   0 */   SDL_SCANCODE_A,
+    /*   1 */   SDL_SCANCODE_S,
+    /*   2 */   SDL_SCANCODE_D,
+    /*   3 */   SDL_SCANCODE_F,
+    /*   4 */   SDL_SCANCODE_H,
+    /*   5 */   SDL_SCANCODE_G,
+    /*   6 */   SDL_SCANCODE_Z,
+    /*   7 */   SDL_SCANCODE_X,
+    /*   8 */   SDL_SCANCODE_C,
+    /*   9 */   SDL_SCANCODE_V,
+    /*  10 */   SDL_SCANCODE_NONUSBACKSLASH, /* SDL_SCANCODE_NONUSBACKSLASH on ANSI and JIS keyboards (if this key would exist there), SDL_SCANCODE_GRAVE on ISO. (The USB keyboard driver actually translates these usage codes to different virtual key codes depending on whether the keyboard is ISO/ANSI/JIS. That's why you have to help it identify the keyboard type when you plug in a PC USB keyboard. It's a historical thing - ADB keyboards are wired this way.) */
+    /*  11 */   SDL_SCANCODE_B,
+    /*  12 */   SDL_SCANCODE_Q,
+    /*  13 */   SDL_SCANCODE_W,
+    /*  14 */   SDL_SCANCODE_E,
+    /*  15 */   SDL_SCANCODE_R,
+    /*  16 */   SDL_SCANCODE_Y,
+    /*  17 */   SDL_SCANCODE_T,
+    /*  18 */   SDL_SCANCODE_1,
+    /*  19 */   SDL_SCANCODE_2,
+    /*  20 */   SDL_SCANCODE_3,
+    /*  21 */   SDL_SCANCODE_4,
+    /*  22 */   SDL_SCANCODE_6,
+    /*  23 */   SDL_SCANCODE_5,
+    /*  24 */   SDL_SCANCODE_EQUALS,
+    /*  25 */   SDL_SCANCODE_9,
+    /*  26 */   SDL_SCANCODE_7,
+    /*  27 */   SDL_SCANCODE_MINUS,
+    /*  28 */   SDL_SCANCODE_8,
+    /*  29 */   SDL_SCANCODE_0,
+    /*  30 */   SDL_SCANCODE_RIGHTBRACKET,
+    /*  31 */   SDL_SCANCODE_O,
+    /*  32 */   SDL_SCANCODE_U,
+    /*  33 */   SDL_SCANCODE_LEFTBRACKET,
+    /*  34 */   SDL_SCANCODE_I,
+    /*  35 */   SDL_SCANCODE_P,
+    /*  36 */   SDL_SCANCODE_RETURN,
+    /*  37 */   SDL_SCANCODE_L,
+    /*  38 */   SDL_SCANCODE_J,
+    /*  39 */   SDL_SCANCODE_APOSTROPHE,
+    /*  40 */   SDL_SCANCODE_K,
+    /*  41 */   SDL_SCANCODE_SEMICOLON,
+    /*  42 */   SDL_SCANCODE_BACKSLASH,
+    /*  43 */   SDL_SCANCODE_COMMA,
+    /*  44 */   SDL_SCANCODE_SLASH,
+    /*  45 */   SDL_SCANCODE_N,
+    /*  46 */   SDL_SCANCODE_M,
+    /*  47 */   SDL_SCANCODE_PERIOD,
+    /*  48 */   SDL_SCANCODE_TAB,
+    /*  49 */   SDL_SCANCODE_SPACE,
+    /*  50 */   SDL_SCANCODE_GRAVE, /* SDL_SCANCODE_GRAVE on ANSI and JIS keyboards, SDL_SCANCODE_NONUSBACKSLASH on ISO (see comment about virtual key code 10 above) */
+    /*  51 */   SDL_SCANCODE_BACKSPACE,
+    /*  52 */   SDL_SCANCODE_KP_ENTER, /* keyboard enter on portables */
+    /*  53 */   SDL_SCANCODE_ESCAPE,
+    /*  54 */   SDL_SCANCODE_RGUI,
+    /*  55 */   SDL_SCANCODE_LGUI,
+    /*  56 */   SDL_SCANCODE_LSHIFT,
+    /*  57 */   SDL_SCANCODE_CAPSLOCK,
+    /*  58 */   SDL_SCANCODE_LALT,
+    /*  59 */   SDL_SCANCODE_LCTRL,
+    /*  60 */   SDL_SCANCODE_RSHIFT,
+    /*  61 */   SDL_SCANCODE_RALT,
+    /*  62 */   SDL_SCANCODE_RCTRL,
+    /*  63 */   SDL_SCANCODE_RGUI, /* fn on portables, acts as a hardware-level modifier already, so we don't generate events for it, also XK_Meta_R */
+    /*  64 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  65 */   SDL_SCANCODE_KP_PERIOD,
+    /*  66 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  67 */   SDL_SCANCODE_KP_MULTIPLY,
+    /*  68 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  69 */   SDL_SCANCODE_KP_PLUS,
+    /*  70 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  71 */   SDL_SCANCODE_NUMLOCKCLEAR,
+    /*  72 */   SDL_SCANCODE_VOLUMEUP,
+    /*  73 */   SDL_SCANCODE_VOLUMEDOWN,
+    /*  74 */   SDL_SCANCODE_MUTE,
+    /*  75 */   SDL_SCANCODE_KP_DIVIDE,
+    /*  76 */   SDL_SCANCODE_KP_ENTER, /* keypad enter on external keyboards, fn-return on portables */
+    /*  77 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  78 */   SDL_SCANCODE_KP_MINUS,
+    /*  79 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  80 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  81 */   SDL_SCANCODE_KP_EQUALS,
+    /*  82 */   SDL_SCANCODE_KP_0,
+    /*  83 */   SDL_SCANCODE_KP_1,
+    /*  84 */   SDL_SCANCODE_KP_2,
+    /*  85 */   SDL_SCANCODE_KP_3,
+    /*  86 */   SDL_SCANCODE_KP_4,
+    /*  87 */   SDL_SCANCODE_KP_5,
+    /*  88 */   SDL_SCANCODE_KP_6,
+    /*  89 */   SDL_SCANCODE_KP_7,
+    /*  90 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /*  91 */   SDL_SCANCODE_KP_8,
+    /*  92 */   SDL_SCANCODE_KP_9,
+    /*  93 */   SDL_SCANCODE_INTERNATIONAL3, /* Cosmo_USB2ADB.c says "Yen (JIS)" */
+    /*  94 */   SDL_SCANCODE_INTERNATIONAL1, /* Cosmo_USB2ADB.c says "Ro (JIS)" */
+    /*  95 */   SDL_SCANCODE_KP_COMMA, /* Cosmo_USB2ADB.c says ", JIS only" */
+    /*  96 */   SDL_SCANCODE_F5,
+    /*  97 */   SDL_SCANCODE_F6,
+    /*  98 */   SDL_SCANCODE_F7,
+    /*  99 */   SDL_SCANCODE_F3,
+    /* 100 */   SDL_SCANCODE_F8,
+    /* 101 */   SDL_SCANCODE_F9,
+    /* 102 */   SDL_SCANCODE_LANG2, /* Cosmo_USB2ADB.c says "Eisu" */
+    /* 103 */   SDL_SCANCODE_F11,
+    /* 104 */   SDL_SCANCODE_LANG1, /* Cosmo_USB2ADB.c says "Kana" */
+    /* 105 */   SDL_SCANCODE_PRINTSCREEN, /* On ADB keyboards, this key is labeled "F13/print screen". Problem: USB has different usage codes for these two functions. On Apple USB keyboards, the key is labeled "F13" and sends the F13 usage code (SDL_SCANCODE_F13). I decided to use SDL_SCANCODE_PRINTSCREEN here nevertheless since SDL applications are more likely to assume the presence of a print screen key than an F13 key. */
+    /* 106 */   SDL_SCANCODE_F16,
+    /* 107 */   SDL_SCANCODE_SCROLLLOCK, /* F14/scroll lock, see comment about F13/print screen above */
+    /* 108 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /* 109 */   SDL_SCANCODE_F10,
+    /* 110 */   SDL_SCANCODE_APPLICATION, /* windows contextual menu key, fn-enter on portables */
+    /* 111 */   SDL_SCANCODE_F12,
+    /* 112 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
+    /* 113 */   SDL_SCANCODE_PAUSE, /* F15/pause, see comment about F13/print screen above */
+    /* 114 */   SDL_SCANCODE_INSERT, /* the key is actually labeled "help" on Apple keyboards, and works as such in Mac OS, but it sends the "insert" usage code even on Apple USB keyboards */
+    /* 115 */   SDL_SCANCODE_HOME,
+    /* 116 */   SDL_SCANCODE_PAGEUP,
+    /* 117 */   SDL_SCANCODE_DELETE,
+    /* 118 */   SDL_SCANCODE_F4,
+    /* 119 */   SDL_SCANCODE_END,
+    /* 120 */   SDL_SCANCODE_F2,
+    /* 121 */   SDL_SCANCODE_PAGEDOWN,
+    /* 122 */   SDL_SCANCODE_F1,
+    /* 123 */   SDL_SCANCODE_LEFT,
+    /* 124 */   SDL_SCANCODE_RIGHT,
+    /* 125 */   SDL_SCANCODE_DOWN,
+    /* 126 */   SDL_SCANCODE_UP,
+    /* 127 */   SDL_SCANCODE_POWER
+};
+/* *INDENT-ON* */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/scancodes_linux.h	Thu Feb 07 15:31:09 2008 +0000
@@ -0,0 +1,264 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "../../include/SDL_scancode.h"
+
+/* Linux virtual key code to SDLKey mapping table
+   Sources:
+   - Linux kernel source input.h
+*/
+/* *INDENT-OFF* */
+static SDL_scancode linux_scancode_table[] = {
+    /*  0 */    SDL_SCANCODE_UNKNOWN,
+    /*  1 */    SDL_SCANCODE_ESCAPE,
+    /*  2 */    SDL_SCANCODE_1,
+    /*  3 */    SDL_SCANCODE_2,
+    /*  4 */    SDL_SCANCODE_3,
+    /*  5 */    SDL_SCANCODE_4,
+    /*  6 */    SDL_SCANCODE_5,
+    /*  7 */    SDL_SCANCODE_6,
+    /*  8 */    SDL_SCANCODE_7,
+    /*  9 */    SDL_SCANCODE_8,
+    /*  10 */    SDL_SCANCODE_9,
+    /*  11 */    SDL_SCANCODE_0,
+    /*  12 */    SDL_SCANCODE_MINUS,
+    /*  13 */    SDL_SCANCODE_EQUALS,
+    /*  14 */    SDL_SCANCODE_BACKSPACE,
+    /*  15 */    SDL_SCANCODE_TAB,
+    /*  16 */    SDL_SCANCODE_Q,
+    /*  17 */    SDL_SCANCODE_W,
+    /*  18 */    SDL_SCANCODE_E,
+    /*  19 */    SDL_SCANCODE_R,
+    /*  20 */    SDL_SCANCODE_T,
+    /*  21 */    SDL_SCANCODE_Y,
+    /*  22 */    SDL_SCANCODE_U,
+    /*  23 */    SDL_SCANCODE_I,
+    /*  24 */    SDL_SCANCODE_O,
+    /*  25 */    SDL_SCANCODE_P,
+    /*  26 */    SDL_SCANCODE_LEFTBRACKET,
+    /*  27 */    SDL_SCANCODE_RIGHTBRACKET,
+    /*  28 */    SDL_SCANCODE_RETURN,
+    /*  29 */    SDL_SCANCODE_LCTRL,
+    /*  30 */    SDL_SCANCODE_A,
+    /*  31 */    SDL_SCANCODE_S,
+    /*  32 */    SDL_SCANCODE_D,
+    /*  33 */    SDL_SCANCODE_F,
+    /*  34 */    SDL_SCANCODE_G,
+    /*  35 */    SDL_SCANCODE_H,
+    /*  36 */    SDL_SCANCODE_J,
+    /*  37 */    SDL_SCANCODE_K,
+    /*  38 */    SDL_SCANCODE_L,
+    /*  39 */    SDL_SCANCODE_SEMICOLON,
+    /*  40 */    SDL_SCANCODE_APOSTROPHE,
+    /*  41 */    SDL_SCANCODE_GRAVE,
+    /*  42 */    SDL_SCANCODE_LSHIFT,
+    /*  43 */    SDL_SCANCODE_BACKSLASH,
+    /*  44 */    SDL_SCANCODE_Z,
+    /*  45 */    SDL_SCANCODE_X,
+    /*  46 */    SDL_SCANCODE_C,
+    /*  47 */    SDL_SCANCODE_V,
+    /*  48 */    SDL_SCANCODE_B,
+    /*  49 */    SDL_SCANCODE_N,
+    /*  50 */    SDL_SCANCODE_M,
+    /*  51 */    SDL_SCANCODE_COMMA,
+    /*  52 */    SDL_SCANCODE_PERIOD,
+    /*  53 */    SDL_SCANCODE_SLASH,
+    /*  54 */    SDL_SCANCODE_RSHIFT,
+    /*  55 */    SDL_SCANCODE_KP_MULTIPLY,
+    /*  56 */    SDL_SCANCODE_LALT,
+    /*  57 */    SDL_SCANCODE_SPACE,
+    /*  58 */    SDL_SCANCODE_CAPSLOCK,
+    /*  59 */    SDL_SCANCODE_F1,
+    /*  60 */    SDL_SCANCODE_F2,
+    /*  61 */    SDL_SCANCODE_F3,
+    /*  62 */    SDL_SCANCODE_F4,
+    /*  63 */    SDL_SCANCODE_F5,
+    /*  64 */    SDL_SCANCODE_F6,
+    /*  65 */    SDL_SCANCODE_F7,
+    /*  66 */    SDL_SCANCODE_F8,
+    /*  67 */    SDL_SCANCODE_F9,
+    /*  68 */    SDL_SCANCODE_F10,
+    /*  69 */    SDL_SCANCODE_NUMLOCKCLEAR,
+    /*  70 */    SDL_SCANCODE_SCROLLLOCK,
+    /*  71 */    SDL_SCANCODE_KP_7,
+    /*  72 */    SDL_SCANCODE_KP_8,
+    /*  73 */    SDL_SCANCODE_KP_9,
+    /*  74 */    SDL_SCANCODE_KP_MINUS,
+    /*  75 */    SDL_SCANCODE_KP_4,
+    /*  76 */    SDL_SCANCODE_KP_5,
+    /*  77 */    SDL_SCANCODE_KP_6,
+    /*  78 */    SDL_SCANCODE_KP_PLUS,
+    /*  79 */    SDL_SCANCODE_KP_1,
+    /*  80 */    SDL_SCANCODE_KP_2,
+    /*  81 */    SDL_SCANCODE_KP_3,
+    /*  82 */    SDL_SCANCODE_KP_0,
+    /*  83 */    SDL_SCANCODE_KP_PERIOD,
+    0,
+    /*  85 */    SDL_SCANCODE_UNKNOWN, /* KEY_ZENKAKUHANKAKU */
+    /*  86 */    SDL_SCANCODE_NONUSBACKSLASH, /* KEY_102ND */
+    /*  87 */    SDL_SCANCODE_F11,
+    /*  88 */    SDL_SCANCODE_F12,
+    /*  89 */    SDL_SCANCODE_INTERNATIONAL1, /* KEY_RO */
+    /*  90 */    SDL_SCANCODE_LANG3, /* KEY_KATAKANA */
+    /*  91 */    SDL_SCANCODE_LANG4, /* KEY_HIRAGANA */
+    /*  92 */    SDL_SCANCODE_INTERNATIONAL4, /* KEY_HENKAN */
+    /*  93 */    SDL_SCANCODE_INTERNATIONAL2, /* KEY_KATAKANAHIRAGANA */
+    /*  94 */    SDL_SCANCODE_INTERNATIONAL5, /* KEY_MUHENKAN */
+    /*  95 */    SDL_SCANCODE_INTERNATIONAL5, /* KEY_KPJPCOMMA */
+    /*  96 */    SDL_SCANCODE_KP_ENTER,
+    /*  97 */    SDL_SCANCODE_RCTRL,
+    /*  98 */    SDL_SCANCODE_KP_DIVIDE,
+    /*  99 */    SDL_SCANCODE_SYSREQ,
+    /*  100 */    SDL_SCANCODE_RALT,
+    /*  101 */    SDL_SCANCODE_UNKNOWN, /* KEY_LINEFEED */
+    /*  102 */    SDL_SCANCODE_HOME,
+    /*  103 */    SDL_SCANCODE_UP,
+    /*  104 */    SDL_SCANCODE_PAGEUP,
+    /*  105 */    SDL_SCANCODE_LEFT,
+    /*  106 */    SDL_SCANCODE_RIGHT,
+    /*  107 */    SDL_SCANCODE_END,
+    /*  108 */    SDL_SCANCODE_DOWN,
+    /*  109 */    SDL_SCANCODE_PAGEDOWN,
+    /*  110 */    SDL_SCANCODE_INSERT,
+    /*  111 */    SDL_SCANCODE_DELETE,
+    /*  112 */    SDL_SCANCODE_UNKNOWN, /* KEY_MACRO */
+    /*  113 */    SDL_SCANCODE_MUTE,
+    /*  114 */    SDL_SCANCODE_VOLUMEDOWN,
+    /*  115 */    SDL_SCANCODE_VOLUMEUP,
+    /*  116 */    SDL_SCANCODE_POWER,
+    /*  117 */    SDL_SCANCODE_KP_EQUALS,
+    /*  118 */    SDL_SCANCODE_KP_PLUSMINUS,
+    /*  119 */    SDL_SCANCODE_PAUSE,
+    0,
+    /*  121 */    SDL_SCANCODE_KP_COMMA,
+    /*  122 */    SDL_SCANCODE_LANG1, /* KEY_HANGUEL */
+    /*  123 */    SDL_SCANCODE_LANG2, /* KEY_HANJA */
+    /*  124 */    SDL_SCANCODE_INTERNATIONAL3, /* KEY_YEN */
+    /*  125 */    SDL_SCANCODE_LGUI,
+    /*  126 */    SDL_SCANCODE_RGUI,
+    /*  127 */    SDL_SCANCODE_UNKNOWN, /* KEY_COMPOSE */
+    /*  128 */    SDL_SCANCODE_STOP,
+    /*  129 */    SDL_SCANCODE_AGAIN,
+    /*  130 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROPS */
+    /*  131 */    SDL_SCANCODE_UNDO,
+    /*  132 */    SDL_SCANCODE_UNKNOWN, /* KEY_FRONT */
+    /*  133 */    SDL_SCANCODE_COPY,
+    /*  134 */    SDL_SCANCODE_UNKNOWN, /* KEY_OPEN */
+    /*  135 */    SDL_SCANCODE_PASTE,
+    /*  136 */    SDL_SCANCODE_FIND,
+    /*  137 */    SDL_SCANCODE_CUT,
+    /*  138 */    SDL_SCANCODE_HELP,
+    /*  139 */    SDL_SCANCODE_MENU,
+    /*  140 */    SDL_SCANCODE_CALCULATOR,
+    /*  141 */    SDL_SCANCODE_UNKNOWN, /* KEY_SETUP */
+    /*  142 */    SDL_SCANCODE_SLEEP,
+    /*  143 */    SDL_SCANCODE_UNKNOWN, /* KEY_WAKEUP */
+    /*  144 */    SDL_SCANCODE_UNKNOWN, /* KEY_FILE */
+    /*  145 */    SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE */
+    /*  146 */    SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE */
+    /*  147 */    SDL_SCANCODE_UNKNOWN, /* KEY_XFER */
+    /*  148 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROG1 */
+    /*  149 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROG2 */
+    /*  150 */    SDL_SCANCODE_UNKNOWN, /* KEY_WWW */
+    /*  151 */    SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS */
+    /*  152 */    SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE */
+    /*  153 */    SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION */
+    /*  154 */    SDL_SCANCODE_UNKNOWN, /* KEY_CYCLEWINDOWS */
+    /*  155 */    SDL_SCANCODE_MAIL,
+    /*  156 */    SDL_SCANCODE_AC_BOOKMARKS,
+    /*  157 */    SDL_SCANCODE_COMPUTER,
+    /*  158 */    SDL_SCANCODE_AC_BACK,
+    /*  159 */    SDL_SCANCODE_AC_FORWARD,
+    /*  160 */    SDL_SCANCODE_UNKNOWN, /* KEY_CLOSECD */
+    /*  161 */    SDL_SCANCODE_EJECT, /* KEY_EJECTCD */
+    /*  162 */    SDL_SCANCODE_UNKNOWN, /* KEY_EJECTCLOSECD */
+    /*  163 */    SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG */
+    /*  164 */    SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE */
+    /*  165 */    SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG */
+    /*  166 */    SDL_SCANCODE_UNKNOWN, /* KEY_STOPCD */
+    /*  167 */    SDL_SCANCODE_UNKNOWN, /* KEY_RECORD */
+    /*  168 */    SDL_SCANCODE_UNKNOWN, /* KEY_REWIND */
+    /*  169 */    SDL_SCANCODE_UNKNOWN, /* KEY_PHONE */
+    /*  170 */    SDL_SCANCODE_UNKNOWN, /* KEY_ISO */
+    /*  171 */    SDL_SCANCODE_UNKNOWN, /* KEY_CONFIG */
+    /*  172 */    SDL_SCANCODE_AC_HOME,
+    /*  173 */    SDL_SCANCODE_AC_REFRESH,
+    /*  174 */    SDL_SCANCODE_UNKNOWN, /* KEY_EXIT */
+    /*  175 */    SDL_SCANCODE_UNKNOWN, /* KEY_MOVE */
+    /*  176 */    SDL_SCANCODE_UNKNOWN, /* KEY_EDIT */
+    /*  177 */    SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLUP */
+    /*  178 */    SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLDOWN */
+    /*  179 */    SDL_SCANCODE_KP_LEFTPAREN,
+    /*  180 */    SDL_SCANCODE_KP_RIGHTPAREN,
+    /*  181 */    SDL_SCANCODE_UNKNOWN, /* KEY_NEW */
+    /*  182 */    SDL_SCANCODE_UNKNOWN, /* KEY_REDO */
+    /*  183 */    SDL_SCANCODE_F13,
+    /*  184 */    SDL_SCANCODE_F14,
+    /*  185 */    SDL_SCANCODE_F15,
+    /*  186 */    SDL_SCANCODE_F16,
+    /*  187 */    SDL_SCANCODE_F17,
+    /*  188 */    SDL_SCANCODE_F18,
+    /*  189 */    SDL_SCANCODE_F19,
+    /*  190 */    SDL_SCANCODE_F20,
+    /*  191 */    SDL_SCANCODE_F21,
+    /*  192 */    SDL_SCANCODE_F22,
+    /*  193 */    SDL_SCANCODE_F23,
+    /*  194 */    SDL_SCANCODE_F24,
+    0, 0, 0, 0,
+    /*  200 */    SDL_SCANCODE_UNKNOWN, /* KEY_PLAYCD */
+    /*  201 */    SDL_SCANCODE_UNKNOWN, /* KEY_PAUSECD */
+    /*  202 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROG3 */
+    /*  203 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROG4 */
+    0,
+    /*  205 */    SDL_SCANCODE_UNKNOWN, /* KEY_SUSPEND */
+    /*  206 */    SDL_SCANCODE_UNKNOWN, /* KEY_CLOSE */
+    /*  207 */    SDL_SCANCODE_UNKNOWN, /* KEY_PLAY */
+    /*  208 */    SDL_SCANCODE_UNKNOWN, /* KEY_FASTFORWARD */
+    /*  209 */    SDL_SCANCODE_UNKNOWN, /* KEY_BASSBOOST */
+    /*  210 */    SDL_SCANCODE_UNKNOWN, /* KEY_PRINT */
+    /*  211 */    SDL_SCANCODE_UNKNOWN, /* KEY_HP */
+    /*  212 */    SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA */
+    /*  213 */    SDL_SCANCODE_UNKNOWN, /* KEY_SOUND */
+    /*  214 */    SDL_SCANCODE_UNKNOWN, /* KEY_QUESTION */
+    /*  215 */    SDL_SCANCODE_UNKNOWN, /* KEY_EMAIL */
+    /*  216 */    SDL_SCANCODE_UNKNOWN, /* KEY_CHAT */
+    /*  217 */    SDL_SCANCODE_AC_SEARCH,
+    /*  218 */    SDL_SCANCODE_UNKNOWN, /* KEY_CONNECT */
+    /*  219 */    SDL_SCANCODE_UNKNOWN, /* KEY_FINANCE */
+    /*  220 */    SDL_SCANCODE_UNKNOWN, /* KEY_SPORT */
+    /*  221 */    SDL_SCANCODE_UNKNOWN, /* KEY_SHOP */
+    /*  222 */    SDL_SCANCODE_ALTERASE,
+    /*  223 */    SDL_SCANCODE_CANCEL,
+    /*  224 */    SDL_SCANCODE_BRIGHTNESSDOWN,
+    /*  225 */    SDL_SCANCODE_BRIGHTNESSUP,
+    /*  226 */    SDL_SCANCODE_UNKNOWN, /* KEY_MEDIA */
+    /*  227 */    SDL_SCANCODE_DISPLAYSWITCH, /* KEY_SWITCHVIDEOMODE */
+    /*  228 */    SDL_SCANCODE_KBDILLUMTOGGLE,
+    /*  229 */    SDL_SCANCODE_KBDILLUMDOWN,
+    /*  230 */    SDL_SCANCODE_KBDILLUMUP,
+    /*  231 */    SDL_SCANCODE_UNKNOWN, /* KEY_SEND */
+    /*  232 */    SDL_SCANCODE_UNKNOWN, /* KEY_REPLY */
+    /*  233 */    SDL_SCANCODE_UNKNOWN, /* KEY_FORWARDMAIL */
+    /*  234 */    SDL_SCANCODE_UNKNOWN, /* KEY_SAVE */
+    /*  235 */    SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS */
+    /*  236 */    SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY */
+};
+/* *INDENT-ON* */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/events/scancodes_xfree86.h	Thu Feb 07 15:31:09 2008 +0000
@@ -0,0 +1,178 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "../../include/SDL_scancode.h"
+
+/* XFree86 key code to SDL scancode mapping table
+   Sources:
+   - atKeyNames.h from XFree86 source code
+*/
+/* *INDENT-OFF* */
+static SDL_scancode xfree86_scancode_table[] = {
+    /*  0 */    SDL_SCANCODE_UNKNOWN,
+    /*  1 */    SDL_SCANCODE_ESCAPE,
+    /*  2 */    SDL_SCANCODE_1,
+    /*  3 */    SDL_SCANCODE_2,
+    /*  4 */    SDL_SCANCODE_3,
+    /*  5 */    SDL_SCANCODE_4,
+    /*  6 */    SDL_SCANCODE_5,
+    /*  7 */    SDL_SCANCODE_6,
+    /*  8 */    SDL_SCANCODE_7,
+    /*  9 */    SDL_SCANCODE_8,
+    /*  10 */   SDL_SCANCODE_9,
+    /*  11 */   SDL_SCANCODE_0,
+    /*  12 */   SDL_SCANCODE_MINUS,
+    /*  13 */   SDL_SCANCODE_EQUALS,
+    /*  14 */   SDL_SCANCODE_BACKSPACE,
+    /*  15 */   SDL_SCANCODE_TAB,
+    /*  16 */   SDL_SCANCODE_Q,
+    /*  17 */   SDL_SCANCODE_W,
+    /*  18 */   SDL_SCANCODE_E,
+    /*  19 */   SDL_SCANCODE_R,
+    /*  20 */   SDL_SCANCODE_T,
+    /*  21 */   SDL_SCANCODE_Y,
+    /*  22 */   SDL_SCANCODE_U,
+    /*  23 */   SDL_SCANCODE_I,
+    /*  24 */   SDL_SCANCODE_O,
+    /*  25 */   SDL_SCANCODE_P,
+    /*  26 */   SDL_SCANCODE_LEFTBRACKET,
+    /*  27 */   SDL_SCANCODE_RIGHTBRACKET,
+    /*  28 */   SDL_SCANCODE_RETURN,
+    /*  29 */   SDL_SCANCODE_LCTRL,
+    /*  30 */   SDL_SCANCODE_A,
+    /*  31 */   SDL_SCANCODE_S,
+    /*  32 */   SDL_SCANCODE_D,
+    /*  33 */   SDL_SCANCODE_F,
+    /*  34 */   SDL_SCANCODE_G,
+    /*  35 */   SDL_SCANCODE_H,
+    /*  36 */   SDL_SCANCODE_J,
+    /*  37 */   SDL_SCANCODE_K,
+    /*  38 */   SDL_SCANCODE_L,
+    /*  39 */   SDL_SCANCODE_SEMICOLON,
+    /*  40 */   SDL_SCANCODE_APOSTROPHE,
+    /*  41 */   SDL_SCANCODE_GRAVE,
+    /*  42 */   SDL_SCANCODE_LSHIFT,
+    /*  43 */   SDL_SCANCODE_BACKSLASH,
+    /*  44 */   SDL_SCANCODE_Z,
+    /*  45 */   SDL_SCANCODE_X,
+    /*  46 */   SDL_SCANCODE_C,
+    /*  47 */   SDL_SCANCODE_V,
+    /*  48 */   SDL_SCANCODE_B,
+    /*  49 */   SDL_SCANCODE_N,
+    /*  50 */   SDL_SCANCODE_M,
+    /*  51 */   SDL_SCANCODE_COMMA,
+    /*  52 */   SDL_SCANCODE_PERIOD,
+    /*  53 */   SDL_SCANCODE_SLASH,
+    /*  54 */   SDL_SCANCODE_RSHIFT,
+    /*  55 */   SDL_SCANCODE_KP_MULTIPLY,
+    /*  56 */   SDL_SCANCODE_LALT,
+    /*  57 */   SDL_SCANCODE_SPACE,
+    /*  58 */   SDL_SCANCODE_CAPSLOCK,
+    /*  59 */   SDL_SCANCODE_F1,
+    /*  60 */   SDL_SCANCODE_F2,
+    /*  61 */   SDL_SCANCODE_F3,
+    /*  62 */   SDL_SCANCODE_F4,
+    /*  63 */   SDL_SCANCODE_F5,
+    /*  64 */   SDL_SCANCODE_F6,
+    /*  65 */   SDL_SCANCODE_F7,
+    /*  66 */   SDL_SCANCODE_F8,
+    /*  67 */   SDL_SCANCODE_F9,
+    /*  68 */   SDL_SCANCODE_F10,
+    /*  69 */   SDL_SCANCODE_NUMLOCKCLEAR,
+    /*  70 */   SDL_SCANCODE_SCROLLLOCK,
+    /*  71 */   SDL_SCANCODE_KP_7,
+    /*  72 */   SDL_SCANCODE_KP_8,
+    /*  73 */   SDL_SCANCODE_KP_9,
+    /*  74 */   SDL_SCANCODE_KP_MINUS,
+    /*  75 */   SDL_SCANCODE_KP_4,
+    /*  76 */   SDL_SCANCODE_KP_5,
+    /*  77 */   SDL_SCANCODE_KP_6,
+    /*  78 */   SDL_SCANCODE_KP_PLUS,
+    /*  79 */   SDL_SCANCODE_KP_1,
+    /*  80 */   SDL_SCANCODE_KP_2,
+    /*  81 */   SDL_SCANCODE_KP_3,
+    /*  82 */   SDL_SCANCODE_KP_0,
+    /*  83 */   SDL_SCANCODE_KP_PERIOD,
+    /*  84 */   SDL_SCANCODE_SYSREQ,
+    /*  85 */   SDL_SCANCODE_MODE,
+    /*  86 */   SDL_SCANCODE_NONUSBACKSLASH,
+    /*  87 */   SDL_SCANCODE_F11,
+    /*  88 */   SDL_SCANCODE_F12,
+    /*  89 */   SDL_SCANCODE_HOME,
+    /*  90 */   SDL_SCANCODE_UP,
+    /*  91 */   SDL_SCANCODE_PAGEUP,
+    /*  92 */   SDL_SCANCODE_LEFT,
+    /*  93 */   SDL_SCANCODE_BRIGHTNESSDOWN, /* on PowerBook G4 / KEY_Begin */
+    /*  94 */   SDL_SCANCODE_RIGHT,
+    /*  95 */   SDL_SCANCODE_END,
+    /*  96 */   SDL_SCANCODE_DOWN,
+    /*  97 */   SDL_SCANCODE_PAGEDOWN,
+    /*  98 */   SDL_SCANCODE_INSERT,
+    /*  99 */   SDL_SCANCODE_DELETE,
+    /*  100 */  SDL_SCANCODE_KP_ENTER,
+    /*  101 */  SDL_SCANCODE_RCTRL,
+    /*  102 */  SDL_SCANCODE_PAUSE,
+    /*  103 */  SDL_SCANCODE_PRINTSCREEN,
+    /*  104 */  SDL_SCANCODE_KP_DIVIDE,
+    /*  105 */  SDL_SCANCODE_RALT,
+    /*  106 */  SDL_SCANCODE_UNKNOWN, /* BREAK */
+    /*  107 */  SDL_SCANCODE_LGUI,
+    /*  108 */  SDL_SCANCODE_RGUI,
+    /*  109 */  SDL_SCANCODE_APPLICATION,
+    /*  110 */  SDL_SCANCODE_F13,
+    /*  111 */  SDL_SCANCODE_F14,
+    /*  112 */  SDL_SCANCODE_F15,
+    /*  113 */  SDL_SCANCODE_F16,
+    /*  114 */  SDL_SCANCODE_F17,
+    /*  115 */	SDL_SCANCODE_UNKNOWN,
+    /*	116 */  SDL_SCANCODE_UNKNOWN, /* is translated to XK_ISO_Level3_Shift by my X server, but I have no keyboard that generates this code, so I don't know what the correct SDL_SCANCODE_* for it is */
+    /*  117 */  SDL_SCANCODE_UNKNOWN,
+    /*  118 */  SDL_SCANCODE_KP_EQUALS,
+    /*  119 */  SDL_SCANCODE_UNKNOWN,
+    /*  120 */  SDL_SCANCODE_UNKNOWN,
+    /*  121 */  SDL_SCANCODE_UNKNOWN,
+    /*  122 */  SDL_SCANCODE_UNKNOWN,
+    /*  123 */  SDL_SCANCODE_UNKNOWN,
+    /*  124 */  SDL_SCANCODE_UNKNOWN,
+    /*  125 */  SDL_SCANCODE_INTERNATIONAL3, /* Yen */
+    /*  126 */  SDL_SCANCODE_UNKNOWN,
+    /*  127 */  SDL_SCANCODE_UNKNOWN,
+    /*  128 */  SDL_SCANCODE_UNKNOWN,
+    /*  129 */  SDL_SCANCODE_UNKNOWN,
+    /*  130 */  SDL_SCANCODE_UNKNOWN,
+    /*  131 */  SDL_SCANCODE_UNKNOWN,
+    /*  132 */  SDL_SCANCODE_POWER,
+    /*  133 */  SDL_SCANCODE_MUTE,
+    /*  134 */  SDL_SCANCODE_VOLUMEDOWN,
+    /*  135 */  SDL_SCANCODE_VOLUMEUP,
+    /*  136 */  SDL_SCANCODE_HELP,
+    /*  137 */  SDL_SCANCODE_STOP,
+    /*  138 */  SDL_SCANCODE_AGAIN,
+    /*  139 */  SDL_SCANCODE_UNKNOWN, /* PROPS */
+    /*  140 */  SDL_SCANCODE_UNDO,
+    /*  141 */  SDL_SCANCODE_UNKNOWN, /* FRONT */
+    /*  142 */  SDL_SCANCODE_COPY,
+    /*  143 */  SDL_SCANCODE_UNKNOWN, /* OPEN */
+    /*  144 */  SDL_SCANCODE_PASTE,
+    /*  145 */  SDL_SCANCODE_FIND,
+    /*  146 */  SDL_SCANCODE_CUT,
+};
+/* *INDENT-ON* */
--- a/src/video/cocoa/SDL_cocoakeyboard.m	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/video/cocoa/SDL_cocoakeyboard.m	Thu Feb 07 15:31:09 2008 +0000
@@ -22,9 +22,9 @@
 #include "SDL_config.h"
 
 #include "SDL_cocoavideo.h"
-#include "SDL_cocoakeys.h"
 
 #include "../../events/SDL_keyboard_c.h"
+#include "../../events/scancodes_darwin.h"
 
 #include <Carbon/Carbon.h>
 
@@ -372,13 +372,13 @@
         UInt32 keyboard_type = LMGetKbdType();
         OSStatus err;
 
-        for (i = 0; i < SDL_arraysize(scancode_table); i++) {
+        for (i = 0; i < SDL_arraysize(darwin_scancode_table); i++) {
             UniChar s[8];
             UniCharCount len;
             UInt32 dead_key_state;
 
             /* Make sure this scancode is a valid character scancode */
-            scancode = scancode_table[i];
+            scancode = darwin_scancode_table[i];
             if (scancode == SDL_SCANCODE_UNKNOWN ||
                 (keymap[scancode] & SDLK_SCANCODE_MASK)) {
                 continue;
@@ -407,7 +407,7 @@
             UInt32 c, state = 0;
 
             /* Make sure this scancode is a valid character scancode */
-            scancode = scancode_table[i];
+            scancode = darwin_scancode_table[i];
             if (scancode == SDL_SCANCODE_UNKNOWN ||
                 (keymap[scancode] & SDLK_SCANCODE_MASK)) {
                 continue;
@@ -487,8 +487,8 @@
         /* see comments in SDL_cocoakeys.h */
         scancode = 60 - scancode;
     }
-    if (scancode < SDL_arraysize(scancode_table)) {
-        code = scancode_table[scancode];
+    if (scancode < SDL_arraysize(darwin_scancode_table)) {
+        code = darwin_scancode_table[scancode];
     }
     else {
         /* Hmm, does this ever happen?  If so, need to extend the keymap... */
--- a/src/video/cocoa/SDL_cocoakeys.h	Tue Feb 05 07:30:50 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2006 Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library 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
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Sam Lantinga
-    slouken@libsdl.org
-*/
-
-/* Mac virtual key code to SDLKey mapping table
-   Sources:
-   - Inside Macintosh: Text <http://developer.apple.com/documentation/mac/Text/Text-571.html>
-   - Apple USB keyboard driver source <http://darwinsource.opendarwin.org/10.4.6.ppc/IOHIDFamily-172.8/IOHIDFamily/Cosmo_USB2ADB.c>
-   - experimentation on various ADB and USB ISO keyboards and one ADB ANSI keyboard
-*/
-/* *INDENT-OFF* */
-static SDL_scancode scancode_table[128] = {
-    /*   0 */   SDL_SCANCODE_A,
-    /*   1 */   SDL_SCANCODE_S,
-    /*   2 */   SDL_SCANCODE_D,
-    /*   3 */   SDL_SCANCODE_F,
-    /*   4 */   SDL_SCANCODE_H,
-    /*   5 */   SDL_SCANCODE_G,
-    /*   6 */   SDL_SCANCODE_Z,
-    /*   7 */   SDL_SCANCODE_X,
-    /*   8 */   SDL_SCANCODE_C,
-    /*   9 */   SDL_SCANCODE_V,
-    /*  10 */   SDL_SCANCODE_NONUSBACKSLASH, /* SDL_SCANCODE_NONUSBACKSLASH on ANSI and JIS keyboards (if this key would exist there), SDL_SCANCODE_GRAVE on ISO. (The USB keyboard driver actually translates these usage codes to different virtual key codes depending on whether the keyboard is ISO/ANSI/JIS. That's why you have to help it identify the keyboard type when you plug in a PC USB keyboard. It's a historical thing - ADB keyboards are wired this way.) */
-    /*  11 */   SDL_SCANCODE_B,
-    /*  12 */   SDL_SCANCODE_Q,
-    /*  13 */   SDL_SCANCODE_W,
-    /*  14 */   SDL_SCANCODE_E,
-    /*  15 */   SDL_SCANCODE_R,
-    /*  16 */   SDL_SCANCODE_Y,
-    /*  17 */   SDL_SCANCODE_T,
-    /*  18 */   SDL_SCANCODE_1,
-    /*  19 */   SDL_SCANCODE_2,
-    /*  20 */   SDL_SCANCODE_3,
-    /*  21 */   SDL_SCANCODE_4,
-    /*  22 */   SDL_SCANCODE_6,
-    /*  23 */   SDL_SCANCODE_5,
-    /*  24 */   SDL_SCANCODE_EQUALS,
-    /*  25 */   SDL_SCANCODE_9,
-    /*  26 */   SDL_SCANCODE_7,
-    /*  27 */   SDL_SCANCODE_HYPHENMINUS,
-    /*  28 */   SDL_SCANCODE_8,
-    /*  29 */   SDL_SCANCODE_0,
-    /*  30 */   SDL_SCANCODE_RIGHTBRACKET,
-    /*  31 */   SDL_SCANCODE_O,
-    /*  32 */   SDL_SCANCODE_U,
-    /*  33 */   SDL_SCANCODE_LEFTBRACKET,
-    /*  34 */   SDL_SCANCODE_I,
-    /*  35 */   SDL_SCANCODE_P,
-    /*  36 */   SDL_SCANCODE_RETURN,
-    /*  37 */   SDL_SCANCODE_L,
-    /*  38 */   SDL_SCANCODE_J,
-    /*  39 */   SDL_SCANCODE_APOSTROPHE,
-    /*  40 */   SDL_SCANCODE_K,
-    /*  41 */   SDL_SCANCODE_SEMICOLON,
-    /*  42 */   SDL_SCANCODE_BACKSLASH,
-    /*  43 */   SDL_SCANCODE_COMMA,
-    /*  44 */   SDL_SCANCODE_SLASH,
-    /*  45 */   SDL_SCANCODE_N,
-    /*  46 */   SDL_SCANCODE_M,
-    /*  47 */   SDL_SCANCODE_PERIOD,
-    /*  48 */   SDL_SCANCODE_TAB,
-    /*  49 */   SDL_SCANCODE_SPACE,
-    /*  50 */   SDL_SCANCODE_GRAVE, /* SDL_SCANCODE_GRAVE on ANSI and JIS keyboards, SDL_SCANCODE_NONUSBACKSLASH on ISO (see comment about virtual key code 10 above) */
-    /*  51 */   SDL_SCANCODE_BACKSPACE,
-    /*  52 */   SDL_SCANCODE_KP_ENTER, /* keyboard enter on portables */
-    /*  53 */   SDL_SCANCODE_ESCAPE,
-    /*  54 */   SDL_SCANCODE_RGUI,
-    /*  55 */   SDL_SCANCODE_LGUI,
-    /*  56 */   SDL_SCANCODE_LSHIFT,
-    /*  57 */   SDL_SCANCODE_CAPSLOCK,
-    /*  58 */   SDL_SCANCODE_LALT,
-    /*  59 */   SDL_SCANCODE_LCTRL,
-    /*  60 */   SDL_SCANCODE_RSHIFT,
-    /*  61 */   SDL_SCANCODE_RALT,
-    /*  62 */   SDL_SCANCODE_RCTRL,
-    /*  63 */   SDL_SCANCODE_UNKNOWN, /* fn on portables, acts as a hardware-level modifier already, so we don't generate events for it */
-    /*  64 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  65 */   SDL_SCANCODE_KP_PERIOD,
-    /*  66 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  67 */   SDL_SCANCODE_KP_MULTIPLY,
-    /*  68 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  69 */   SDL_SCANCODE_KP_PLUS,
-    /*  70 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  71 */   SDL_SCANCODE_NUMLOCKCLEAR,
-    /*  72 */   SDL_SCANCODE_VOLUMEUP,
-    /*  73 */   SDL_SCANCODE_VOLUMEDOWN,
-    /*  74 */   SDL_SCANCODE_MUTE,
-    /*  75 */   SDL_SCANCODE_KP_DIVIDE,
-    /*  76 */   SDL_SCANCODE_KP_ENTER, /* keypad enter on external keyboards, fn-return on portables */
-    /*  77 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  78 */   SDL_SCANCODE_KP_MINUS,
-    /*  79 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  80 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  81 */   SDL_SCANCODE_KP_EQUALS,
-    /*  82 */   SDL_SCANCODE_KP_0,
-    /*  83 */   SDL_SCANCODE_KP_1,
-    /*  84 */   SDL_SCANCODE_KP_2,
-    /*  85 */   SDL_SCANCODE_KP_3,
-    /*  86 */   SDL_SCANCODE_KP_4,
-    /*  87 */   SDL_SCANCODE_KP_5,
-    /*  88 */   SDL_SCANCODE_KP_6,
-    /*  89 */   SDL_SCANCODE_KP_7,
-    /*  90 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /*  91 */   SDL_SCANCODE_KP_8,
-    /*  92 */   SDL_SCANCODE_KP_9,
-    /*  93 */   SDL_SCANCODE_INTERNATIONAL3, /* Cosmo_USB2ADB.c says "Yen (JIS)" */
-    /*  94 */   SDL_SCANCODE_INTERNATIONAL1, /* Cosmo_USB2ADB.c says "Ro (JIS)" */
-    /*  95 */   SDL_SCANCODE_KP_COMMA, /* Cosmo_USB2ADB.c says ", JIS only" */
-    /*  96 */   SDL_SCANCODE_F5,
-    /*  97 */   SDL_SCANCODE_F6,
-    /*  98 */   SDL_SCANCODE_F7,
-    /*  99 */   SDL_SCANCODE_F3,
-    /* 100 */   SDL_SCANCODE_F8,
-    /* 101 */   SDL_SCANCODE_F9,
-    /* 102 */   SDL_SCANCODE_LANG2, /* Cosmo_USB2ADB.c says "Eisu" */
-    /* 103 */   SDL_SCANCODE_F11,
-    /* 104 */   SDL_SCANCODE_LANG1, /* Cosmo_USB2ADB.c says "Kana" */
-    /* 105 */   SDL_SCANCODE_PRINTSCREEN, /* On ADB keyboards, this key is labeled "F13/print screen". Problem: USB has different usage codes for these two functions. On Apple USB keyboards, the key is labeled "F13" and sends the F13 usage code (SDL_SCANCODE_F13). I decided to use SDL_SCANCODE_PRINTSCREEN here nevertheless since SDL applications are more likely to assume the presence of a print screen key than an F13 key. */
-    /* 106 */   SDL_SCANCODE_F16,
-    /* 107 */   SDL_SCANCODE_SCROLLLOCK, /* F14/scroll lock, see comment about F13/print screen above */
-    /* 108 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /* 109 */   SDL_SCANCODE_F10,
-    /* 110 */   SDL_SCANCODE_APPLICATION, /* windows contextual menu key, fn-enter on portables */
-    /* 111 */   SDL_SCANCODE_F12,
-    /* 112 */   SDL_SCANCODE_UNKNOWN, /* unknown (unused?) */
-    /* 113 */   SDL_SCANCODE_PAUSE, /* F15/pause, see comment about F13/print screen above */
-    /* 114 */   SDL_SCANCODE_INSERT, /* the key is actually labeled "help" on Apple keyboards, and works as such in Mac OS, but it sends the "insert" usage code even on Apple USB keyboards */
-    /* 115 */   SDL_SCANCODE_HOME,
-    /* 116 */   SDL_SCANCODE_PAGEUP,
-    /* 117 */   SDL_SCANCODE_DELETE,
-    /* 118 */   SDL_SCANCODE_F4,
-    /* 119 */   SDL_SCANCODE_END,
-    /* 120 */   SDL_SCANCODE_F2,
-    /* 121 */   SDL_SCANCODE_PAGEDOWN,
-    /* 122 */   SDL_SCANCODE_F1,
-    /* 123 */   SDL_SCANCODE_LEFT,
-    /* 124 */   SDL_SCANCODE_RIGHT,
-    /* 125 */   SDL_SCANCODE_DOWN,
-    /* 126 */   SDL_SCANCODE_UP,
-    /* 127 */   SDL_SCANCODE_POWER
-};
-/* *INDENT-ON* */
--- a/src/video/x11/SDL_x11events.c	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/video/x11/SDL_x11events.c	Thu Feb 07 15:31:09 2008 +0000
@@ -140,6 +140,15 @@
         }
         break;
 
+        /* Has the keyboard layout changed? */
+    case MappingNotify:{
+#ifdef DEBUG_XEVENTS
+            printf("MappingNotify!\n");
+#endif
+            X11_UpdateKeymap(this);
+        }
+        break;
+
         /* Mouse motion? */
     case MotionNotify:{
 #ifdef DEBUG_MOTION
@@ -174,23 +183,25 @@
 #ifdef DEBUG_XEVENTS
             printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
 #endif
-            SDLKey physicalKey = videodata->keyCodeToSDLKTable[keycode];
             SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED,
-                                (Uint8) keycode, physicalKey);
+                                videodata->key_layout[keycode]);
 #if 1
-            if (physicalKey == SDLK_UNKNOWN) {
+            if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
+                int min_keycode, max_keycode;
+                XDisplayKeycodes(videodata->display, &min_keycode,
+                                 &max_keycode);
+                keysym = XKeycodeToKeysym(videodata->display, keycode, 0);
                 fprintf(stderr,
-                        "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>. X11 KeyCode is %d, X11 KeySym 0x%X.\n",
-                        (int) keycode,
-                        (unsigned int) XKeycodeToKeysym(videodata->display,
-                                                        keycode, 0));
+                        "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> X11 KeyCode %d (%d), X11 KeySym 0x%X (%s).\n",
+                        keycode, keycode - min_keycode, keysym,
+                        XKeysymToString(keysym));
             }
 #endif
-            /* works for Latin-1 */
-            SDL_memset(&text[0], 0, SDL_TEXTINPUTEVENT_TEXT_SIZE);
-            /* Xutf8LookupString() */
+            /* Xutf8LookupString(), works for Latin-1 */
+            SDL_zero(text);
             XLookupString(&xevent, text, sizeof(text), &keysym, NULL);
-            if (0 != SDL_strlen(text)) {
+            if (*text) {
+                printf("Sending text event %s\n", text);
                 SDL_SendKeyboardText(videodata->keyboard, text);
             }
         }
@@ -204,8 +215,7 @@
             printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
 #endif
             SDL_SendKeyboardKey(videodata->keyboard, SDL_RELEASED,
-                                (Uint8) keycode,
-                                videodata->keyCodeToSDLKTable[keycode]);
+                                videodata->key_layout[keycode]);
         }
         break;
 
--- a/src/video/x11/SDL_x11keyboard.c	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/video/x11/SDL_x11keyboard.c	Thu Feb 07 15:31:09 2008 +0000
@@ -24,1007 +24,376 @@
 #include "SDL_x11video.h"
 
 #include "../../events/SDL_keyboard_c.h"
+#include "../../events/scancodes_darwin.h"
+#include "../../events/scancodes_xfree86.h"
 
 #include <X11/keysym.h>
 
 #include "imKStoUCS.h"
 
-/* 
-   KeyCode-to-SDLKey translation tables for various X servers. Which
-   one to use is decided in X11_InitKeyboard().
-*/
-
-static SDLKey macKeyCodeToSDLK[];
-static SDLKey xorgLinuxKeyCodeToSDLK[];
-
-static SDLKey *keyCodeToSDLKeyTables[] = {
-    xorgLinuxKeyCodeToSDLK,
-    macKeyCodeToSDLK,
-    NULL
-};
-
-/* *INDENT-OFF* */
-
-/* These are just Mac virtual key codes + 8 (see SDL/src/video/cocoa/
-   SDL_cocoakeys.h for more info). Observed to work with Apple X11 on
-   Mac OS X 10.4. May also work on older Linux distributions on Mac
-   hardware.
-*/
-
-#define KeyCodeTableSize (256)
-static SDLKey macKeyCodeToSDLK[KeyCodeTableSize] = 
-{
-    /*   0 */   SDLK_UNKNOWN,
-    /*   1 */   SDLK_UNKNOWN,
-    /*   2 */   SDLK_UNKNOWN,
-    /*   3 */   SDLK_UNKNOWN,
-    /*   4 */   SDLK_UNKNOWN,
-    /*   5 */   SDLK_UNKNOWN,
-    /*   6 */   SDLK_UNKNOWN,
-    /*   7 */   SDLK_UNKNOWN,
-    /*   8 */   SDLK_A,
-    /*   9 */   SDLK_S,
-    /*  10 */   SDLK_D,
-    /*  11 */   SDLK_F,
-    /*  12 */   SDLK_H,
-    /*  13 */   SDLK_G,
-    /*  14 */   SDLK_Z,
-    /*  15 */   SDLK_X,
-    /*  16 */   SDLK_C,
-    /*  17 */   SDLK_V,
-    /*  18 */   SDLK_GRAVE,
-    /*  19 */   SDLK_B,
-    /*  20 */   SDLK_Q,
-    /*  21 */   SDLK_W,
-    /*  22 */   SDLK_E,
-    /*  23 */   SDLK_R,
-    /*  24 */   SDLK_Y,
-    /*  25 */   SDLK_T,
-    /*  26 */   SDLK_1,
-    /*  27 */   SDLK_2,
-    /*  28 */   SDLK_3,
-    /*  29 */   SDLK_4,
-    /*  30 */   SDLK_6,
-    /*  31 */   SDLK_5,
-    /*  32 */   SDLK_EQUALS,
-    /*  33 */   SDLK_9,
-    /*  34 */   SDLK_7,
-    /*  35 */   SDLK_HYPHENMINUS,
-    /*  36 */   SDLK_8,
-    /*  37 */   SDLK_0,
-    /*  38 */   SDLK_RIGHTBRACKET,
-    /*  39 */   SDLK_O,
-    /*  40 */   SDLK_U,
-    /*  41 */   SDLK_LEFTBRACKET,
-    /*  42 */   SDLK_I,
-    /*  43 */   SDLK_P,
-    /*  44 */   SDLK_RETURN,
-    /*  45 */   SDLK_L,
-    /*  46 */   SDLK_J,
-    /*  47 */   SDLK_APOSTROPHE,
-    /*  48 */   SDLK_K,
-    /*  49 */   SDLK_SEMICOLON,
-    /*  50 */   SDLK_BACKSLASH,
-    /*  51 */   SDLK_COMMA,
-    /*  52 */   SDLK_SLASH,
-    /*  53 */   SDLK_N,
-    /*  54 */   SDLK_M,
-    /*  55 */   SDLK_PERIOD,
-    /*  56 */   SDLK_TAB,
-    /*  57 */   SDLK_SPACE,
-    /*  58 */   SDLK_NONUSBACKSLASH,
-    /*  59 */   SDLK_BACKSPACE,
-    /*  60 */   SDLK_KP_ENTER,
-    /*  61 */   SDLK_ESCAPE,
-    /*  62 */   SDLK_RMETA,
-    /*  63 */   SDLK_LMETA,
-    /*  64 */   SDLK_LSHIFT,
-    /*  65 */   SDLK_CAPSLOCK,
-    /*  66 */   SDLK_LALT,
-    /*  67 */   SDLK_LCTRL,
-    /*  68 */   SDLK_RSHIFT,
-    /*  69 */   SDLK_RALT,
-    /*  70 */   SDLK_RCTRL,
-    /*  71 */   SDLK_NONE,
-    /*  72 */   SDLK_UNKNOWN,
-    /*  73 */   SDLK_KP_PERIOD,
-    /*  74 */   SDLK_UNKNOWN,
-    /*  75 */   SDLK_KP_MULTIPLY,
-    /*  76 */   SDLK_UNKNOWN,
-    /*  77 */   SDLK_KP_PLUS,
-    /*  78 */   SDLK_UNKNOWN,
-    /*  79 */   SDLK_KP_NUMLOCKCLEAR,
-    /*  80 */   SDLK_VOLUMEUP,
-    /*  81 */   SDLK_VOLUMEDOWN,
-    /*  82 */   SDLK_MUTE,
-    /*  83 */   SDLK_KP_DIVIDE,
-    /*  84 */   SDLK_KP_ENTER,
-    /*  85 */   SDLK_UNKNOWN,
-    /*  86 */   SDLK_KP_MINUS,
-    /*  87 */   SDLK_UNKNOWN,
-    /*  88 */   SDLK_UNKNOWN,
-    /*  89 */   SDLK_KP_EQUALS,
-    /*  90 */   SDLK_KP_0,
-    /*  91 */   SDLK_KP_1,
-    /*  92 */   SDLK_KP_2,
-    /*  93 */   SDLK_KP_3,
-    /*  94 */   SDLK_KP_4,
-    /*  95 */   SDLK_KP_5,
-    /*  96 */   SDLK_KP_6,
-    /*  97 */   SDLK_KP_7,
-    /*  98 */   SDLK_UNKNOWN,
-    /*  99 */   SDLK_KP_8,
-    /* 100 */   SDLK_KP_9,
-    /* 101 */   SDLK_INTERNATIONAL3,
-    /* 102 */   SDLK_INTERNATIONAL1,
-    /* 103 */   SDLK_KP_COMMA,
-    /* 104 */   SDLK_F5,
-    /* 105 */   SDLK_F6,
-    /* 106 */   SDLK_F7,
-    /* 107 */   SDLK_F3,
-    /* 108 */   SDLK_F8,
-    /* 109 */   SDLK_F9,
-    /* 110 */   SDLK_LANG2,
-    /* 111 */   SDLK_F11,
-    /* 112 */   SDLK_LANG1,
-    /* 113 */   SDLK_PRINTSCREEN,
-    /* 114 */   SDLK_F16,
-    /* 115 */   SDLK_SCROLLLOCK,
-    /* 116 */   SDLK_UNKNOWN,
-    /* 117 */   SDLK_F10,
-    /* 118 */   SDLK_APPLICATION,
-    /* 119 */   SDLK_F12,
-    /* 120 */   SDLK_UNKNOWN,
-    /* 121 */   SDLK_PAUSE,
-    /* 122 */   SDLK_INSERT,
-    /* 123 */   SDLK_HOME,
-    /* 124 */   SDLK_PAGEUP,
-    /* 125 */   SDLK_DELETE,
-    /* 126 */   SDLK_F4,
-    /* 127 */   SDLK_END,
-    /* 128 */   SDLK_F2,
-    /* 129 */   SDLK_PAGEDOWN,
-    /* 130 */   SDLK_F1,
-    /* 131 */   SDLK_LEFT,
-    /* 132 */   SDLK_RIGHT,
-    /* 133 */   SDLK_DOWN,
-    /* 134 */   SDLK_UP,
-    /* 135 */   SDLK_POWER,
-    /* 136 */   SDLK_UNKNOWN, /* codes higher than 135 shouldn't occur as Mac virtual keycodes only go to 127 */
-    /* 137 */   SDLK_UNKNOWN,
-    /* 138 */   SDLK_UNKNOWN,
-    /* 139 */   SDLK_UNKNOWN,
-    /* 140 */   SDLK_UNKNOWN,
-    /* 141 */   SDLK_UNKNOWN,
-    /* 142 */   SDLK_UNKNOWN,
-    /* 143 */   SDLK_UNKNOWN,
-    /* 144 */   SDLK_UNKNOWN,
-    /* 145 */   SDLK_UNKNOWN,
-    /* 146 */   SDLK_UNKNOWN,
-    /* 147 */   SDLK_UNKNOWN,
-    /* 148 */   SDLK_UNKNOWN,
-    /* 149 */   SDLK_UNKNOWN,
-    /* 150 */   SDLK_UNKNOWN,
-    /* 151 */   SDLK_UNKNOWN,
-    /* 152 */   SDLK_UNKNOWN,
-    /* 153 */   SDLK_UNKNOWN,
-    /* 154 */   SDLK_UNKNOWN,
-    /* 155 */   SDLK_UNKNOWN,
-    /* 156 */   SDLK_UNKNOWN,
-    /* 157 */   SDLK_UNKNOWN,
-    /* 158 */   SDLK_UNKNOWN,
-    /* 159 */   SDLK_UNKNOWN,
-    /* 160 */   SDLK_UNKNOWN,
-    /* 161 */   SDLK_UNKNOWN,
-    /* 162 */   SDLK_UNKNOWN,
-    /* 163 */   SDLK_UNKNOWN,
-    /* 164 */   SDLK_UNKNOWN,
-    /* 165 */   SDLK_UNKNOWN,
-    /* 166 */   SDLK_UNKNOWN,
-    /* 167 */   SDLK_UNKNOWN,
-    /* 168 */   SDLK_UNKNOWN,
-    /* 169 */   SDLK_UNKNOWN,
-    /* 170 */   SDLK_UNKNOWN,
-    /* 171 */   SDLK_UNKNOWN,
-    /* 172 */   SDLK_UNKNOWN,
-    /* 173 */   SDLK_UNKNOWN,
-    /* 174 */   SDLK_UNKNOWN,
-    /* 175 */   SDLK_UNKNOWN,
-    /* 176 */   SDLK_UNKNOWN,
-    /* 177 */   SDLK_UNKNOWN,
-    /* 178 */   SDLK_UNKNOWN,
-    /* 179 */   SDLK_UNKNOWN,
-    /* 180 */   SDLK_UNKNOWN,
-    /* 181 */   SDLK_UNKNOWN,
-    /* 182 */   SDLK_UNKNOWN,
-    /* 183 */   SDLK_UNKNOWN,
-    /* 184 */   SDLK_UNKNOWN,
-    /* 185 */   SDLK_UNKNOWN,
-    /* 186 */   SDLK_UNKNOWN,
-    /* 187 */   SDLK_UNKNOWN,
-    /* 188 */   SDLK_UNKNOWN,
-    /* 189 */   SDLK_UNKNOWN,
-    /* 190 */   SDLK_UNKNOWN,
-    /* 191 */   SDLK_UNKNOWN,
-    /* 192 */   SDLK_UNKNOWN,
-    /* 193 */   SDLK_UNKNOWN,
-    /* 194 */   SDLK_UNKNOWN,
-    /* 195 */   SDLK_UNKNOWN,
-    /* 196 */   SDLK_UNKNOWN,
-    /* 197 */   SDLK_UNKNOWN,
-    /* 198 */   SDLK_UNKNOWN,
-    /* 199 */   SDLK_UNKNOWN,
-    /* 200 */   SDLK_UNKNOWN,
-    /* 201 */   SDLK_UNKNOWN,
-    /* 202 */   SDLK_UNKNOWN,
-    /* 203 */   SDLK_UNKNOWN,
-    /* 204 */   SDLK_UNKNOWN,
-    /* 205 */   SDLK_UNKNOWN,
-    /* 206 */   SDLK_UNKNOWN,
-    /* 207 */   SDLK_UNKNOWN,
-    /* 208 */   SDLK_UNKNOWN,
-    /* 209 */   SDLK_UNKNOWN,
-    /* 210 */   SDLK_UNKNOWN,
-    /* 211 */   SDLK_UNKNOWN,
-    /* 212 */   SDLK_UNKNOWN,
-    /* 213 */   SDLK_UNKNOWN,
-    /* 214 */   SDLK_UNKNOWN,
-    /* 215 */   SDLK_UNKNOWN,
-    /* 216 */   SDLK_UNKNOWN,
-    /* 217 */   SDLK_UNKNOWN,
-    /* 218 */   SDLK_UNKNOWN,
-    /* 219 */   SDLK_UNKNOWN,
-    /* 220 */   SDLK_UNKNOWN,
-    /* 221 */   SDLK_UNKNOWN,
-    /* 222 */   SDLK_UNKNOWN,
-    /* 223 */   SDLK_UNKNOWN,
-    /* 224 */   SDLK_UNKNOWN,
-    /* 225 */   SDLK_UNKNOWN,
-    /* 226 */   SDLK_UNKNOWN,
-    /* 227 */   SDLK_UNKNOWN,
-    /* 228 */   SDLK_UNKNOWN,
-    /* 229 */   SDLK_UNKNOWN,
-    /* 230 */   SDLK_UNKNOWN,
-    /* 231 */   SDLK_UNKNOWN,
-    /* 232 */   SDLK_UNKNOWN,
-    /* 233 */   SDLK_UNKNOWN,
-    /* 234 */   SDLK_UNKNOWN,
-    /* 235 */   SDLK_UNKNOWN,
-    /* 236 */   SDLK_UNKNOWN,
-    /* 237 */   SDLK_UNKNOWN,
-    /* 238 */   SDLK_UNKNOWN,
-    /* 239 */   SDLK_UNKNOWN,
-    /* 240 */   SDLK_UNKNOWN,
-    /* 241 */   SDLK_UNKNOWN,
-    /* 242 */   SDLK_UNKNOWN,
-    /* 243 */   SDLK_UNKNOWN,
-    /* 244 */   SDLK_UNKNOWN,
-    /* 245 */   SDLK_UNKNOWN,
-    /* 246 */   SDLK_UNKNOWN,
-    /* 247 */   SDLK_UNKNOWN,
-    /* 248 */   SDLK_UNKNOWN,
-    /* 249 */   SDLK_UNKNOWN,
-    /* 250 */   SDLK_UNKNOWN,
-    /* 251 */   SDLK_UNKNOWN,
-    /* 252 */   SDLK_UNKNOWN,
-    /* 253 */   SDLK_UNKNOWN,
-    /* 254 */   SDLK_UNKNOWN,
-    /* 255 */   SDLK_UNKNOWN
+static KeySym XKeySymTable[SDL_NUM_SCANCODES] = {
+    0, 0, 0, 0,
+    XK_a,
+    XK_b,
+    XK_c,
+    XK_d,
+    XK_e,
+    XK_f,
+    XK_g,
+    XK_h,
+    XK_i,
+    XK_j,
+    XK_k,
+    XK_l,
+    XK_m,
+    XK_n,
+    XK_o,
+    XK_p,
+    XK_q,
+    XK_r,
+    XK_s,
+    XK_t,
+    XK_u,
+    XK_v,
+    XK_w,
+    XK_x,
+    XK_y,
+    XK_z,
+    XK_1,
+    XK_2,
+    XK_3,
+    XK_4,
+    XK_5,
+    XK_6,
+    XK_7,
+    XK_8,
+    XK_9,
+    XK_0,
+    XK_Return,
+    XK_Escape,
+    XK_BackSpace,
+    XK_Tab,
+    XK_space,
+    XK_minus,
+    XK_equal,
+    XK_bracketleft,
+    XK_bracketright,
+    XK_backslash,
+    0,                          /* SDL_SCANCODE_NONUSHASH ? */
+    XK_semicolon,
+    XK_apostrophe,
+    XK_grave,
+    XK_comma,
+    XK_period,
+    XK_slash,
+    XK_Caps_Lock,
+    XK_F1,
+    XK_F2,
+    XK_F3,
+    XK_F4,
+    XK_F5,
+    XK_F6,
+    XK_F7,
+    XK_F8,
+    XK_F9,
+    XK_F10,
+    XK_F11,
+    XK_F12,
+    XK_Print,
+    XK_Scroll_Lock,
+    XK_Pause,
+    XK_Insert,
+    XK_Home,
+    XK_Prior,
+    XK_Delete,
+    XK_End,
+    XK_Next,
+    XK_Right,
+    XK_Left,
+    XK_Down,
+    XK_Up,
+    XK_Num_Lock,
+    XK_KP_Divide,
+    XK_KP_Multiply,
+    XK_KP_Subtract,
+    XK_KP_Add,
+    XK_KP_Enter,
+    XK_KP_1,
+    XK_KP_2,
+    XK_KP_3,
+    XK_KP_4,
+    XK_KP_5,
+    XK_KP_6,
+    XK_KP_7,
+    XK_KP_8,
+    XK_KP_9,
+    XK_KP_0,
+    XK_KP_Decimal,
+    0,                          /* SDL_SCANCODE_NONUSBACKSLASH ? */
+    XK_Hyper_R,
+    0,                          /* SDL_SCANCODE_POWER ? */
+    XK_KP_Equal,
+    XK_F13,
+    XK_F14,
+    XK_F15,
+    XK_F16,
+    XK_F17,
+    XK_F18,
+    XK_F19,
+    XK_F20,
+    XK_F21,
+    XK_F22,
+    XK_F23,
+    XK_F24,
+    XK_Execute,
+    XK_Help,
+    XK_Menu,
+    XK_Select,
+    XK_Cancel,
+    XK_Redo,
+    XK_Undo,
+    0,                          /* SDL_SCANCODE_CUT ? */
+    0,                          /* SDL_SCANCODE_COPY ? */
+    0,                          /* SDL_SCANCODE_PASTE ? */
+    XK_Find,
+    0,                          /* SDL_SCANCODE_MUTE ? */
+    0,                          /* SDL_SCANCODE_VOLUMEUP ? */
+    0,                          /* SDL_SCANCODE_VOLUMEDOWN ? */
+    0, 0, 0,
+    XK_KP_Separator,
+    0,                          /* SDL_SCANCODE_KP_EQUALSAS400 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL1 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL2 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL3 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL4 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL5 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL6 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL7 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL8 ? */
+    0,                          /* SDL_SCANCODE_INTERNATIONAL9 ? */
+    0,                          /* SDL_SCANCODE_LANG1 ? */
+    0,                          /* SDL_SCANCODE_LANG2 ? */
+    0,                          /* SDL_SCANCODE_LANG3 ? */
+    0,                          /* SDL_SCANCODE_LANG4 ? */
+    0,                          /* SDL_SCANCODE_LANG5 ? */
+    0,                          /* SDL_SCANCODE_LANG6 ? */
+    0,                          /* SDL_SCANCODE_LANG7 ? */
+    0,                          /* SDL_SCANCODE_LANG8 ? */
+    0,                          /* SDL_SCANCODE_LANG9 ? */
+    0,                          /* SDL_SCANCODE_ALTERASE ? */
+    XK_Sys_Req,
+    0,                          /* SDL_SCANCODE_CANCEL ? - XK_Cancel was used above... */
+    0,                          /* SDL_SCANCODE_CLEAR ? */
+    0,                          /* SDL_SCANCODE_PRIOR ? - XK_Prior was used above... */
+    0,                          /* SDL_SCANCODE_RETURN2 ? */
+    0,                          /* SDL_SCANCODE_SEPARATOR ? */
+    0,                          /* SDL_SCANCODE_OUT ? */
+    0,                          /* SDL_SCANCODE_OPER ? */
+    0,                          /* SDL_SCANCODE_CLEARAGAIN ? */
+    0,                          /* SDL_SCANCODE_CRSEL ? */
+    0,                          /* SDL_SCANCODE_EXSEL ? */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0,                          /* SDL_SCANCODE_KP_00 ? */
+    0,                          /* SDL_SCANCODE_KP_000 ? */
+    0,                          /* SDL_SCANCODE_THOUSANDSSEPARATOR ? */
+    0,                          /* SDL_SCANCODE_DECIMALSEPARATOR ? */
+    0,                          /* SDL_SCANCODE_CURRENCYUNIT ? */
+    0,                          /* SDL_SCANCODE_CURRENCYSUBUNIT ? */
+    0,                          /* SDL_SCANCODE_KP_LEFTPAREN ? */
+    0,                          /* SDL_SCANCODE_KP_RIGHTPAREN ? */
+    0,                          /* SDL_SCANCODE_KP_LEFTBRACE ? */
+    0,                          /* SDL_SCANCODE_KP_RIGHTBRACE ? */
+    0,                          /* SDL_SCANCODE_KP_TAB ? */
+    0,                          /* SDL_SCANCODE_KP_BACKSPACE ? */
+    0,                          /* SDL_SCANCODE_KP_A ? */
+    0,                          /* SDL_SCANCODE_KP_B ? */
+    0,                          /* SDL_SCANCODE_KP_C ? */
+    0,                          /* SDL_SCANCODE_KP_D ? */
+    0,                          /* SDL_SCANCODE_KP_E ? */
+    0,                          /* SDL_SCANCODE_KP_F ? */
+    0,                          /* SDL_SCANCODE_KP_XOR ? */
+    0,                          /* SDL_SCANCODE_KP_POWER ? */
+    0,                          /* SDL_SCANCODE_KP_PERCENT ? */
+    0,                          /* SDL_SCANCODE_KP_LESS ? */
+    0,                          /* SDL_SCANCODE_KP_GREATER ? */
+    0,                          /* SDL_SCANCODE_KP_AMPERSAND ? */
+    0,                          /* SDL_SCANCODE_KP_DBLAMPERSAND ? */
+    0,                          /* SDL_SCANCODE_KP_VERTICALBAR ? */
+    0,                          /* SDL_SCANCODE_KP_DBLVERTICALBAR ? */
+    0,                          /* SDL_SCANCODE_KP_COLON ? */
+    0,                          /* SDL_SCANCODE_KP_HASH ? */
+    0,                          /* SDL_SCANCODE_KP_SPACE ? */
+    0,                          /* SDL_SCANCODE_KP_AT ? */
+    0,                          /* SDL_SCANCODE_KP_EXCLAM ? */
+    0,                          /* SDL_SCANCODE_KP_MEMSTORE ? */
+    0,                          /* SDL_SCANCODE_KP_MEMRECALL ? */
+    0,                          /* SDL_SCANCODE_KP_MEMCLEAR ? */
+    0,                          /* SDL_SCANCODE_KP_MEMADD ? */
+    0,                          /* SDL_SCANCODE_KP_MEMSUBTRACT ? */
+    0,                          /* SDL_SCANCODE_KP_MEMMULTIPLY ? */
+    0,                          /* SDL_SCANCODE_KP_MEMDIVIDE ? */
+    0,                          /* SDL_SCANCODE_KP_PLUSMINUS ? */
+    0,                          /* SDL_SCANCODE_KP_CLEAR ? */
+    0,                          /* SDL_SCANCODE_KP_CLEARENTRY ? */
+    0,                          /* SDL_SCANCODE_KP_BINARY ? */
+    0,                          /* SDL_SCANCODE_KP_OCTAL ? */
+    0,                          /* SDL_SCANCODE_KP_DECIMAL ? */
+    0,                          /* SDL_SCANCODE_KP_HEXADECIMAL ? */
+    0, 0,
+    XK_Control_L,
+    XK_Shift_L,
+    XK_Alt_L,
+    XK_Meta_L,
+    XK_Control_R,
+    XK_Shift_R,
+    XK_Alt_R,
+    XK_Meta_R,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    XK_Mode_switch /*XK_ISO_Level3_Shift */ ,
+    0,                          /* SDL_SCANCODE_AUDIONEXT ? */
+    0,                          /* SDL_SCANCODE_AUDIOPREV ? */
+    0,                          /* SDL_SCANCODE_AUDIOSTOP ? */
+    0,                          /* SDL_SCANCODE_AUDIOPLAY ? */
+    0,                          /* SDL_SCANCODE_AUDIOMUTE ? */
+    0,                          /* SDL_SCANCODE_MEDIASELECT ? */
+    0,                          /* SDL_SCANCODE_WWW ? */
+    0,                          /* SDL_SCANCODE_MAIL ? */
+    0,                          /* SDL_SCANCODE_CALCULATOR ? */
+    0,                          /* SDL_SCANCODE_COMPUTER ? */
+    0,                          /* SDL_SCANCODE_AC_SEARCH ? */
+    0,                          /* SDL_SCANCODE_AC_HOME ? */
+    0,                          /* SDL_SCANCODE_AC_BACK ? */
+    0,                          /* SDL_SCANCODE_AC_FORWARD ? */
+    0,                          /* SDL_SCANCODE_AC_STOP ? */
+    0,                          /* SDL_SCANCODE_AC_REFRESH ? */
+    0,                          /* SDL_SCANCODE_AC_BOOKMARKS ? */
+    0,                          /* SDL_SCANCODE_BRIGHTNESSDOWN ? */
+    0,                          /* SDL_SCANCODE_BRIGHTNESSUP ? */
+    0,                          /* SDL_SCANCODE_DISPLAYSWITCH ? */
+    0,                          /* SDL_SCANCODE_KBDILLUMTOGGLE ? */
+    0,                          /* SDL_SCANCODE_KBDILLUMDOWN ? */
+    0,                          /* SDL_SCANCODE_KBDILLUMUP ? */
+    0,                          /* SDL_SCANCODE_EJECT ? */
+    0,                          /* SDL_SCANCODE_SLEEP ? */
 };
 
-/* Found mostly by experimentation with X.org on Linux (Fedora Core 4 and
-   Ubuntu Dapper) on PC and PPC Mac hardware, some parts (especially about
-   the "multimedia"/"internet" keys) from various sources on the web.
-*/
-static SDLKey xorgLinuxKeyCodeToSDLK[KeyCodeTableSize] = 
-{
-    /*   0 */   SDLK_UNKNOWN,
-    /*   1 */   SDLK_UNKNOWN,
-    /*   2 */   SDLK_UNKNOWN,
-    /*   3 */   SDLK_UNKNOWN,
-    /*   4 */   SDLK_UNKNOWN,
-    /*   5 */   SDLK_UNKNOWN,
-    /*   6 */   SDLK_UNKNOWN,
-    /*   7 */   SDLK_UNKNOWN,
-    /*   8 */   SDLK_UNKNOWN,
-    /*   9 */   SDLK_ESCAPE,
-    /*  10 */   SDLK_1,
-    /*  11 */   SDLK_2,
-    /*  12 */   SDLK_3,
-    /*  13 */   SDLK_4,
-    /*  14 */   SDLK_5,
-    /*  15 */   SDLK_6,
-    /*  16 */   SDLK_7,
-    /*  17 */   SDLK_8,
-    /*  18 */   SDLK_9,
-    /*  19 */   SDLK_0,
-    /*  20 */   SDLK_HYPHENMINUS,
-    /*  21 */   SDLK_EQUALS,
-    /*  22 */   SDLK_BACKSPACE,
-    /*  23 */   SDLK_TAB,
-    /*  24 */   SDLK_Q,
-    /*  25 */   SDLK_W,
-    /*  26 */   SDLK_E,
-    /*  27 */   SDLK_R,
-    /*  28 */   SDLK_T,
-    /*  29 */   SDLK_Y,
-    /*  30 */   SDLK_U,
-    /*  31 */   SDLK_I,
-    /*  32 */   SDLK_O,
-    /*  33 */   SDLK_P,
-    /*  34 */   SDLK_LEFTBRACKET,
-    /*  35 */   SDLK_RIGHTBRACKET,
-    /*  36 */   SDLK_RETURN,
-    /*  37 */   SDLK_LCTRL,
-    /*  38 */   SDLK_A,
-    /*  39 */   SDLK_S,
-    /*  40 */   SDLK_D,
-    /*  41 */   SDLK_F,
-    /*  42 */   SDLK_G,
-    /*  43 */   SDLK_H,
-    /*  44 */   SDLK_J,
-    /*  45 */   SDLK_K,
-    /*  46 */   SDLK_L,
-    /*  47 */   SDLK_SEMICOLON,
-    /*  48 */   SDLK_APOSTROPHE,
-    /*  49 */   SDLK_GRAVE,
-    /*  50 */   SDLK_LSHIFT,
-    /*  51 */   SDLK_BACKSLASH,
-    /*  52 */   SDLK_Z,
-    /*  53 */   SDLK_X,
-    /*  54 */   SDLK_C,
-    /*  55 */   SDLK_V,
-    /*  56 */   SDLK_B,
-    /*  57 */   SDLK_N,
-    /*  58 */   SDLK_M,
-    /*  59 */   SDLK_COMMA,
-    /*  60 */   SDLK_PERIOD,
-    /*  61 */   SDLK_SLASH,
-    /*  62 */   SDLK_RSHIFT,
-    /*  63 */   SDLK_KP_MULTIPLY,
-    /*  64 */   SDLK_LALT,
-    /*  65 */   SDLK_SPACE,
-    /*  66 */   SDLK_CAPSLOCK,
-    /*  67 */   SDLK_F1,
-    /*  68 */   SDLK_F2,
-    /*  69 */   SDLK_F3,
-    /*  70 */   SDLK_F4,
-    /*  71 */   SDLK_F5,
-    /*  72 */   SDLK_F6,
-    /*  73 */   SDLK_F7,
-    /*  74 */   SDLK_F8,
-    /*  75 */   SDLK_F9,
-    /*  76 */   SDLK_F10,
-    /*  77 */   SDLK_KP_NUMLOCKCLEAR,
-    /*  78 */   SDLK_SCROLLLOCK,
-    /*  79 */   SDLK_KP_7,
-    /*  80 */   SDLK_KP_8,
-    /*  81 */   SDLK_KP_9,
-    /*  82 */   SDLK_KP_MINUS,
-    /*  83 */   SDLK_KP_4,
-    /*  84 */   SDLK_KP_5,
-    /*  85 */   SDLK_KP_6,
-    /*  86 */   SDLK_KP_PLUS,
-    /*  87 */   SDLK_KP_1,
-    /*  88 */   SDLK_KP_2,
-    /*  89 */   SDLK_KP_3,
-    /*  90 */   SDLK_KP_0,
-    /*  91 */   SDLK_KP_PERIOD,
-    /*  92 */   SDLK_SYSREQ,
-    /*  93 */   SDLK_MODE, /* is translated to XK_Mode_switch by my X server, but I have no keyboard that generates this code, so I'm not sure if this is correct */
-    /*  94 */   SDLK_NONUSBACKSLASH,
-    /*  95 */   SDLK_F11,
-    /*  96 */   SDLK_F12,
-    /*  97 */   SDLK_HOME,
-    /*  98 */   SDLK_UP,
-    /*  99 */   SDLK_PAGEUP,
-    /* 100 */   SDLK_LEFT,
-    /* 101 */   SDLK_BRIGHTNESSDOWN, /* on PowerBook G4 */
-    /* 102 */   SDLK_RIGHT,
-    /* 103 */   SDLK_END,
-    /* 104 */   SDLK_DOWN,
-    /* 105 */   SDLK_PAGEDOWN,
-    /* 106 */   SDLK_INSERT,
-    /* 107 */   SDLK_DELETE,
-    /* 108 */   SDLK_KP_ENTER,
-    /* 109 */   SDLK_RCTRL,
-    /* 110 */   SDLK_PAUSE,
-    /* 111 */   SDLK_PRINTSCREEN,
-    /* 112 */   SDLK_KP_DIVIDE,
-    /* 113 */   SDLK_RALT,
-    /* 114 */   SDLK_UNKNOWN,
-    /* 115 */   SDLK_LMETA,
-    /* 116 */   SDLK_RMETA,
-    /* 117 */   SDLK_APPLICATION,
-    /* 118 */   SDLK_F13,
-    /* 119 */   SDLK_F14,
-    /* 120 */   SDLK_F15,
-    /* 121 */   SDLK_F16,
-    /* 122 */   SDLK_F17,
-    /* 123 */   SDLK_UNKNOWN,
-    /* 124 */   SDLK_UNKNOWN, /* is translated to XK_ISO_Level3_Shift by my X server, but I have no keyboard that generates this code, so I don't know what the correct SDLK_* for it is */
-    /* 125 */   SDLK_UNKNOWN,
-    /* 126 */   SDLK_KP_EQUALS,
-    /* 127 */   SDLK_UNKNOWN,
-    /* 128 */   SDLK_UNKNOWN,
-    /* 129 */   SDLK_UNKNOWN,
-    /* 130 */   SDLK_UNKNOWN,
-    /* 131 */   SDLK_UNKNOWN,
-    /* 132 */   SDLK_UNKNOWN,
-    /* 133 */   SDLK_INTERNATIONAL3, /* Yen */
-    /* 134 */   SDLK_UNKNOWN,
-    /* 135 */   SDLK_AGAIN,
-    /* 136 */   SDLK_UNDO,
-    /* 137 */   SDLK_UNKNOWN,
-    /* 138 */   SDLK_UNKNOWN,
-    /* 139 */   SDLK_UNKNOWN,
-    /* 140 */   SDLK_UNKNOWN,
-    /* 141 */   SDLK_UNKNOWN,
-    /* 142 */   SDLK_UNKNOWN,
-    /* 143 */   SDLK_UNKNOWN,
-    /* 144 */   SDLK_AUDIOPREV,
-    /* 145 */   SDLK_UNKNOWN,
-    /* 146 */   SDLK_UNKNOWN,
-    /* 147 */   SDLK_UNKNOWN,
-    /* 148 */   SDLK_UNKNOWN,
-    /* 149 */   SDLK_UNKNOWN,
-    /* 150 */   SDLK_UNKNOWN,
-    /* 151 */   SDLK_UNKNOWN,
-    /* 152 */   SDLK_UNKNOWN,
-    /* 153 */   SDLK_AUDIONEXT,
-    /* 154 */   SDLK_UNKNOWN,
-    /* 155 */   SDLK_UNKNOWN,
-    /* 156 */   SDLK_UNKNOWN,
-    /* 157 */   SDLK_KP_EQUALS, /* on PowerBook G4 */
-    /* 158 */   SDLK_UNKNOWN,
-    /* 159 */   SDLK_UNKNOWN,
-    /* 160 */   SDLK_MUTE,
-    /* 161 */   SDLK_CALC,
-    /* 162 */   SDLK_AUDIOPLAY,
-    /* 163 */   SDLK_UNKNOWN,
-    /* 164 */   SDLK_AUDIOSTOP,
-    /* 165 */   SDLK_UNKNOWN,
-    /* 166 */   SDLK_UNKNOWN,
-    /* 167 */   SDLK_UNKNOWN,
-    /* 168 */   SDLK_UNKNOWN,
-    /* 169 */   SDLK_UNKNOWN,
-    /* 170 */   SDLK_UNKNOWN,
-    /* 171 */   SDLK_UNKNOWN,
-    /* 172 */   SDLK_UNKNOWN,
-    /* 173 */   SDLK_UNKNOWN,
-    /* 174 */   SDLK_VOLUMEDOWN,
-    /* 175 */   SDLK_UNKNOWN,
-    /* 176 */   SDLK_VOLUMEUP,
-    /* 177 */   SDLK_UNKNOWN,
-    /* 178 */   SDLK_WWW,
-    /* 179 */   SDLK_UNKNOWN,
-    /* 180 */   SDLK_UNKNOWN,
-    /* 181 */   SDLK_UNKNOWN,
-    /* 182 */   SDLK_UNKNOWN,
-    /* 183 */   SDLK_UNKNOWN,
-    /* 184 */   SDLK_UNKNOWN,
-    /* 185 */   SDLK_UNKNOWN,
-    /* 186 */   SDLK_UNKNOWN,
-    /* 187 */   SDLK_HELP,
-    /* 188 */   SDLK_UNKNOWN,
-    /* 189 */   SDLK_UNKNOWN,
-    /* 190 */   SDLK_UNKNOWN,
-    /* 191 */   SDLK_UNKNOWN,
-    /* 192 */   SDLK_UNKNOWN,
-    /* 193 */   SDLK_UNKNOWN,
-    /* 194 */   SDLK_UNKNOWN,
-    /* 195 */   SDLK_UNKNOWN,
-    /* 196 */   SDLK_UNKNOWN,
-    /* 197 */   SDLK_UNKNOWN,
-    /* 198 */   SDLK_UNKNOWN,
-    /* 199 */   SDLK_UNKNOWN,
-    /* 200 */   SDLK_UNKNOWN,
-    /* 201 */   SDLK_UNKNOWN,
-    /* 202 */   SDLK_UNKNOWN,
-    /* 203 */   SDLK_UNKNOWN,
-    /* 204 */   SDLK_EJECT, /* on PowerBook G4 */
-    /* 205 */   SDLK_UNKNOWN,
-    /* 206 */   SDLK_UNKNOWN,
-    /* 207 */   SDLK_UNKNOWN,
-    /* 208 */   SDLK_UNKNOWN,
-    /* 209 */   SDLK_UNKNOWN,
-    /* 210 */   SDLK_UNKNOWN,
-    /* 211 */   SDLK_UNKNOWN,
-    /* 212 */   SDLK_BRIGHTNESSUP, /* on PowerBook G4 */
-    /* 213 */   SDLK_UNKNOWN,
-    /* 214 */   SDLK_DISPLAYSWITCH, /* on PowerBook G4 */
-    /* 215 */   SDLK_KBDILLUMTOGGLE,
-    /* 216 */   SDLK_KBDILLUMDOWN,
-    /* 217 */   SDLK_KBDILLUMUP,
-    /* 218 */   SDLK_UNKNOWN,
-    /* 219 */   SDLK_UNKNOWN,
-    /* 220 */   SDLK_UNKNOWN,
-    /* 221 */   SDLK_UNKNOWN,
-    /* 222 */   SDLK_POWER,
-    /* 223 */   SDLK_SLEEP,
-    /* 224 */   SDLK_UNKNOWN,
-    /* 225 */   SDLK_UNKNOWN,
-    /* 226 */   SDLK_UNKNOWN,
-    /* 227 */   SDLK_UNKNOWN,
-    /* 228 */   SDLK_UNKNOWN,
-    /* 229 */   SDLK_SEARCH,
-    /* 230 */   SDLK_BOOKMARKS,
-    /* 231 */   SDLK_BROWSERRELOAD,
-    /* 232 */   SDLK_BROWSERSTOP,
-    /* 233 */   SDLK_BROWSERFORWARD,
-    /* 234 */   SDLK_BROWSERBACK,
-    /* 235 */   SDLK_COMPUTER,
-    /* 236 */   SDLK_EMAIL,
-    /* 237 */   SDLK_MEDIA,
-    /* 238 */   SDLK_UNKNOWN,
-    /* 239 */   SDLK_UNKNOWN,
-    /* 240 */   SDLK_UNKNOWN,
-    /* 241 */   SDLK_UNKNOWN,
-    /* 242 */   SDLK_UNKNOWN,
-    /* 243 */   SDLK_UNKNOWN,
-    /* 244 */   SDLK_UNKNOWN,
-    /* 245 */   SDLK_UNKNOWN,
-    /* 246 */   SDLK_UNKNOWN,
-    /* 247 */   SDLK_UNKNOWN,
-    /* 248 */   SDLK_UNKNOWN,
-    /* 249 */   SDLK_UNKNOWN,
-    /* 250 */   SDLK_UNKNOWN,
-    /* 251 */   SDLK_UNKNOWN,
-    /* 252 */   SDLK_UNKNOWN,
-    /* 253 */   SDLK_UNKNOWN,
-    /* 254 */   SDLK_UNKNOWN,
-    /* 255 */   SDLK_UNKNOWN
-};
-
-/*---------------------------------------------------------------------------*/
-
-/* Used by X11_KeySymToSDLKey(). This is a hybrid of a KeySym-to-layout-key
-    mapping (needed in X11_GetLayoutKey()) and a fallback KeySym-to-physical-key
-    mapping under the assumption of a US keyboard layout (needed in
-    X11_InitKeyboard()). If for a given KeySym...
-    - the layout and physical codes are the same (must be an SDLK_ constant):
-      there is one entry,
-    - the layout and physical codes differ: there are two entries, with the
-      layout one first,
-    - there is only a physical code in the table (must be an SDLK_ constant):
-      it's marked by X11_KEY_PHYSICAL_ONLY_BIT (this is the case when the layout
-      key code is handled by KeySymToUcs4()),
-    - there is only a layout code in the table (can't be an SDLK_ constant):
-      recognizable by the absence of SDL_KEY_CAN_BE_PHYSICAL_BIT.
-    This list is sorted by KeySym to allow a binary search.
-*/
-#define X11_KEY_PHYSICAL_ONLY_BIT SDL_KEY_LAYOUT_SPECIAL_BIT
-/* SDL_KEY_LAYOUT_SPECIAL_BIT cannot possibly occur in an SDLK_ constant, so we may repurpose that bit for our own use. */
 static struct
 {
-    KeySym sym;
-    SDLKey key;
-} keySymToSDLKey[KeyCodeTableSize] = 
-{
-    /* 0x00xx */
-    {XK_space, SDLK_SPACE},
-    {XK_apostrophe, SDLK_APOSTROPHE | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_comma, SDLK_COMMA | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_minus, SDLK_HYPHENMINUS | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_period, SDLK_PERIOD | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_slash, SDLK_SLASH | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_0, SDLK_0 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_1, SDLK_1 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_2, SDLK_2 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_3, SDLK_3 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_4, SDLK_4 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_5, SDLK_5 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_6, SDLK_6 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_7, SDLK_7 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_8, SDLK_8 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_9, SDLK_9 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_semicolon, SDLK_SEMICOLON | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_less, SDLK_NONUSBACKSLASH | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_equal, SDLK_EQUALS | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_bracketleft, SDLK_LEFTBRACKET | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_backslash, SDLK_BACKSLASH | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_bracketright, SDLK_RIGHTBRACKET | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_grave, SDLK_GRAVE | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_a, SDLK_A | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_b, SDLK_B | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_c, SDLK_C | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_d, SDLK_D | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_e, SDLK_E | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_f, SDLK_F | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_g, SDLK_G | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_h, SDLK_H | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_i, SDLK_I | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_j, SDLK_J | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_k, SDLK_K | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_l, SDLK_L | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_m, SDLK_M | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_n, SDLK_N | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_o, SDLK_O | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_p, SDLK_P | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_q, SDLK_Q | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_r, SDLK_R | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_s, SDLK_S | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_t, SDLK_T | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_u, SDLK_U | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_v, SDLK_V | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_w, SDLK_W | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_x, SDLK_X | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_y, SDLK_Y | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_z, SDLK_Z | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_section, SDLK_NONUSBACKSLASH | X11_KEY_PHYSICAL_ONLY_BIT},
-        /* 0xFExx */
-    {XK_ISO_Level3_Shift, SDLK_RALT},
-    {XK_dead_grave, '`'},
-    {XK_dead_acute, 0xB4},
-    {XK_dead_circumflex, '^'},
-    {XK_dead_tilde, '~'},
-    {XK_dead_macron, 0xAF},
-    {XK_dead_breve, 0x2D8},
-    {XK_dead_abovedot, 0x2D9},
-    {XK_dead_diaeresis, 0xA8},
-    {XK_dead_abovering, 0x2DA},
-    {XK_dead_doubleacute, 0x2DD},
-    {XK_dead_caron, 0x2C7},
-    {XK_dead_cedilla, 0xB8},
-    {XK_dead_ogonek, 0x2DB},
-    {XK_dead_iota, 0x3B9},
-    {XK_dead_voiced_sound, 0x309B},
-    {XK_dead_semivoiced_sound, 0x309C},
-    {XK_dead_belowdot, 0xB7},        /* that's actually MIDDLE DOT,
-                                        but I haven't found a
-                                        non-combining DOT BELOW
-                                        XK_dead_hook, XK_dead_horn: I
-                                        haven't found non-combining
-                                        HOOK and HORN characters */
-    /* 0xFFxx */
-    {XK_BackSpace, SDLK_BACKSPACE},
-    {XK_Tab, SDLK_TAB},
-    {XK_Return, SDLK_RETURN},
-    {XK_Pause, SDLK_PAUSE},
-    {XK_Scroll_Lock, SDLK_SCROLLLOCK},
-    {XK_Escape, SDLK_ESCAPE},
-    {XK_Home, SDLK_HOME},
-    {XK_Left, SDLK_LEFT},
-    {XK_Up, SDLK_UP},
-    {XK_Right, SDLK_RIGHT},
-    {XK_Down, SDLK_DOWN},
-    {XK_Page_Up, SDLK_PAGEUP},
-    {XK_Page_Down, SDLK_PAGEDOWN},
-    {XK_End, SDLK_END},
-    {XK_Print, SDLK_PRINTSCREEN},
-    {XK_Insert, SDLK_INSERT},
-    {XK_Menu, SDLK_APPLICATION},
-    {XK_Break, SDLK_PAUSE},
-    {XK_Mode_switch, SDLK_MODE},
-    {XK_Num_Lock, SDLK_KP_NUMLOCKCLEAR},
-    {XK_KP_Enter, SDLK_KP_ENTER},
-    {XK_KP_Home, SDLK_KP_7 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Left, SDLK_KP_4 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Up, SDLK_KP_8 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Right, SDLK_KP_6 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Down, SDLK_KP_2 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Page_Up, SDLK_KP_9 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Page_Down, SDLK_KP_3 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_End, SDLK_KP_1 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Begin, SDLK_KP_5 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Insert, SDLK_KP_0 | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Delete, SDLK_KP_PERIOD | X11_KEY_PHYSICAL_ONLY_BIT},
-    {XK_KP_Multiply, '*'},
-    {XK_KP_Multiply, SDLK_KP_MULTIPLY},
-    {XK_KP_Add, '+'},
-    {XK_KP_Add, SDLK_KP_PLUS},
-    {XK_KP_Separator, '.'},
-    {XK_KP_Separator, SDLK_KP_PERIOD},
-    {XK_KP_Subtract, '-'},
-    {XK_KP_Subtract, SDLK_KP_MINUS},
-    {XK_KP_Decimal, '.'},
-    {XK_KP_Decimal, SDLK_KP_PERIOD},
-    {XK_KP_Divide, '/'},
-    {XK_KP_Divide, SDLK_KP_DIVIDE},
-    {XK_KP_0, '0'},
-    {XK_KP_0, SDLK_KP_0},
-    {XK_KP_1, '1'},
-    {XK_KP_1, SDLK_KP_1},
-    {XK_KP_2, '2'},
-    {XK_KP_2, SDLK_KP_2},
-    {XK_KP_3, '3'},
-    {XK_KP_3, SDLK_KP_3},
-    {XK_KP_4, '4'},
-    {XK_KP_4, SDLK_KP_4},
-    {XK_KP_5, '5'},
-    {XK_KP_5, SDLK_KP_5},
-    {XK_KP_6, '6'},
-    {XK_KP_6, SDLK_KP_6},
-    {XK_KP_7, '7'},
-    {XK_KP_7, SDLK_KP_7},
-    {XK_KP_8, '8'},
-    {XK_KP_8, SDLK_KP_8},
-    {XK_KP_9, '9'},
-    {XK_KP_9, SDLK_KP_9},
-    {XK_KP_Equal, '='},
-    {XK_KP_Equal, SDLK_KP_EQUALS},
-    {XK_F1, SDLK_F1},
-    {XK_F2, SDLK_F2},
-    {XK_F3, SDLK_F3},
-    {XK_F4, SDLK_F4},
-    {XK_F5, SDLK_F5},
-    {XK_F6, SDLK_F6},
-    {XK_F7, SDLK_F7},
-    {XK_F8, SDLK_F8},
-    {XK_F9, SDLK_F9},
-    {XK_F10, SDLK_F10},
-    {XK_F11, SDLK_F11},
-    {XK_F12, SDLK_F12},
-    {XK_F13, SDLK_F13},
-    {XK_F14, SDLK_F14},
-    {XK_F15, SDLK_F15},
-    {XK_F16, SDLK_F16},
-    {XK_F17, SDLK_F17},
-    {XK_F18, SDLK_F18},
-    {XK_F19, SDLK_F19},
-    {XK_F20, SDLK_F20},
-    {XK_F21, SDLK_F21},
-    {XK_F22, SDLK_F22},
-    {XK_F23, SDLK_F23},
-    {XK_F24, SDLK_F24},
-    {XK_Shift_L, SDLK_LSHIFT},
-    {XK_Shift_R, SDLK_RSHIFT},
-    {XK_Control_L, SDLK_LCTRL},
-    {XK_Control_R, SDLK_RCTRL},
-    {XK_Caps_Lock, SDLK_CAPSLOCK},
-    {XK_Shift_Lock, SDLK_CAPSLOCK},
-    {XK_Meta_L, SDLK_LMETA},
-    {XK_Meta_R, SDLK_RMETA},
-    {XK_Alt_L, SDLK_LALT},
-    {XK_Alt_R, SDLK_RALT},
-    {XK_Super_L, SDLK_LMETA},
-    {XK_Super_R, SDLK_RMETA},
-    {XK_Hyper_L, SDLK_LMETA},
-    {XK_Hyper_R, SDLK_RMETA},
-    {XK_Delete, SDLK_DELETE},
-    {0x1000003, SDLK_KP_ENTER}   /* keyboard enter on Mac OS X */
-};
-
-/* *INDENT-ON* */
-
-/* 
-   Used for two purposes: - by X11_GetLayoutKey(), with physical =
-   false, to convert a KeySym to the corresponding layout key code
-   (SDLK_ ones and some character ones - most character KeySyms are
-   handled by X11_KeySymToUcs4() after this function returns
-   SDLK_UNKNOWN for them).  - by X11_InitKeyboard(), with physical =
-   true, to build a makeshift translation table based on the KeySyms
-   when none of the predefined KeyCode- to-SDLKey tables fits. This
-   is *not* correct anywhere but on a US layout, since the
-   translation table deals with physical key codes, while the X11
-   KeySym corresponds to our concept of a layout key code, but it's
-   better than nothing.
-*/
-
-static SDLKey
-X11_KeySymToSDLKey(KeySym sym, SDL_bool physical)
-{
-    /* Do a binary search for sym in the keySymToSDLKey table */
-    SDLKey key = SDLK_UNKNOWN;
-    int start = -1;
-    int end = SDL_arraysize(keySymToSDLKey);
-    int i;
-    /* Invariant: keySymToSDLKey[start].sym < sym <
-       keySymToSDLKey[end].sym (imagine ...[-1] = -inf and
-       ...[arraysize] = inf, these entries needn't be there in reality
-       because they're never accessed) */
-    while (end > start + 1) {
-        i = (start + end) / 2;
-        if (keySymToSDLKey[i].sym == sym) {
-            /* found an entry, if it's the second of two back up to the first */
-            if (keySymToSDLKey[i - 1].sym == sym)
-                i--;
-            /* if there are two, the physical one is the second */
-            if (physical && keySymToSDLKey[i + 1].sym == sym)
-                i++;
-            key = keySymToSDLKey[i].key;
-            break;
-        } else if (keySymToSDLKey[i].sym < sym)
-            start = i;
-        else
-            end = i;
-    }
-
-    /* if we're being asked for a layout key code, but the table only
-       has a physical one, or vice versa, return SDLK_UNKNOWN) */
-
-    if (!physical && ((key & X11_KEY_PHYSICAL_ONLY_BIT) != 0)
-        || physical && ((key & SDL_KEY_CAN_BE_PHYSICAL_BIT) == 0))
-        key = SDLK_UNKNOWN;
-    key &= ~X11_KEY_PHYSICAL_ONLY_BIT;
-    return key;
-}
+    SDL_scancode *table;
+    int table_size;
+} scancode_set[] = {
+    {
+    darwin_scancode_table, SDL_arraysize(darwin_scancode_table)}, {
+xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table)},};
 
 int
 X11_InitKeyboard(_THIS)
 {
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
     SDL_Keyboard keyboard;
-    SDLKey **table;
-    SDLKey *foundTable;
-    int i;
-    int code;
-    SDLKey sdlkey;
+    int i, j;
+    int min_keycode, max_keycode;
+    SDL_scancode fingerprint_scancodes[] = {
+        SDL_SCANCODE_HOME,
+        SDL_SCANCODE_PAGEUP,
+        SDL_SCANCODE_PAGEDOWN
+    };
+    int fingerprint[3];
+    SDL_bool fingerprint_detected;
 
     XAutoRepeatOn(data->display);
 
-    /* A random collection of KeySym/SDLKey pairs that should be valid
-       in any keyboard layout (if this isn't the case on yours,
-       please adjust). Using XKeysymToKeycode on these KeySyms
-       creates a "fingerprint" of the X server's key-to-KeyCode
-       mapping which is then matched against all our predefined
-       KeyCodeToSDLK tables to find the right one (if any).
-     */
-
-/* *INDENT-OFF* */
-    struct
-    {
-        KeySym sym;
-        SDLKey key;
-    } fingerprint[] = 
-      {
-        {XK_Tab, SDLK_TAB}, 
-        {XK_Return, SDLK_RETURN}, 
-        {XK_Escape, SDLK_ESCAPE}, 
-        {XK_space, SDLK_SPACE}
-    };
-/* *INDENT-ON* */
-
-    SDL_zero(keyboard);
-    data->keyboard = SDL_AddKeyboard(&keyboard, -1);
-
-    /* Determine which X11 KeyCode to SDL physical key code table to use */
-
-    foundTable = NULL;
-    table = keyCodeToSDLKeyTables;
-    while ((NULL == foundTable) && (NULL != (*table))) {
-        foundTable = *table;
-        for (i = 0; i < SDL_arraysize(fingerprint); i++) {
-            code = XKeysymToKeycode(data->display, fingerprint[i].sym);
-            if ((code != 0) && ((*table)[code] != fingerprint[i].key)) {
-                foundTable = NULL;
+    /* Try to determine which scancodes are being used based on fingerprint */
+    fingerprint_detected = SDL_FALSE;
+    XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
+    for (i = 0; i < SDL_arraysize(fingerprint_scancodes); ++i) {
+        fingerprint[i] =
+            XKeysymToKeycode(data->display,
+                             XKeySymTable[fingerprint_scancodes[i]]) -
+            min_keycode;
+    }
+    for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
+        /* Make sure the scancode set isn't too big */
+        if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) {
+            continue;
+        }
+        for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
+            if (fingerprint[j] < 0
+                || fingerprint[j] >= scancode_set[i].table_size) {
+                break;
+            }
+            if (scancode_set[i].table[fingerprint[j]] !=
+                fingerprint_scancodes[j]) {
                 break;
             }
         }
-        table++;
-    }
-
-    if (NULL != foundTable) {
-        /* Found a suitable one among the predefined tables */
-        data->keyCodeToSDLKTable = foundTable;
-    } else {
-        /* No suitable table found - build a makeshift table based on
-           the KeySyms, assuming a US keyboard layout */
-
-#if 1
-        fprintf(stderr,
-                "The key codes of your X server are unknown to SDL. Keys may not be recognized properly. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>.\n");
-#endif
-        data->keyCodeToSDLKTable =
-            SDL_malloc(KeyCodeTableSize * sizeof(SDLKey));
-        if (data->keyCodeToSDLKTable == NULL) {
-            SDL_OutOfMemory();
-            return -1;
-        }
-        for (code = KeyCodeTableSize; code >= 0; code--) {
-            data->keyCodeToSDLKTable[code] =
-                X11_KeySymToSDLKey(XKeycodeToKeysym(data->display, code, 0),
-                                   SDL_TRUE);
+        if (j == SDL_arraysize(fingerprint)) {
+            printf("Using scancode set %d\n", i);
+            SDL_memcpy(&data->key_layout[min_keycode], scancode_set[i].table,
+                       sizeof(SDL_scancode) * scancode_set[i].table_size);
+            fingerprint_detected = SDL_TRUE;
+            break;
         }
     }
 
-    /* Set some non-default key names */
+    if (!fingerprint_detected) {
+        printf
+            ("Keyboard layout unknown, please send the following to the SDL mailing list (sdl@libsdl.org):\n");
 
-    for (code = 0; code < KeyCodeTableSize; code++) {
-        sdlkey = data->keyCodeToSDLKTable[code];
-        switch (sdlkey) {
-            /* The SDLK_*META keys are used as XK_Meta_* by some X
-               servers, as XK_Super_* by others */
-        case SDLK_LMETA:
-        case SDLK_RMETA:
-            switch (XKeycodeToKeysym(data->display, code, 0)) {
-                /* nothing to do for XK_Meta_* because that's already the default name */
-            case XK_Super_L:
-                SDL_SetKeyName(sdlkey, "left super");
-                break;
-            case XK_Super_R:
-                SDL_SetKeyName(sdlkey, "right super");
-                break;
+        /* Determine key_layout - only works on US QWERTY layout */
+        for (i = min_keycode; i <= max_keycode; ++i) {
+            KeySym sym;
+            sym = XKeycodeToKeysym(data->display, i, 0);
+            if (sym) {
+                printf("code = %d, sym = 0x%X (%s) ", i - min_keycode, sym,
+                       XKeysymToString(sym));
+                for (j = 0; j < SDL_arraysize(XKeySymTable); ++j) {
+                    if (XKeySymTable[j] == sym) {
+                        data->key_layout[i] = (SDL_scancode) j;
+                        break;
+                    }
+                }
+                if (j == SDL_arraysize(XKeySymTable)) {
+                    printf("scancode not found\n");
+                } else {
+                    printf("scancode = %d (%s)\n", j, SDL_GetScancodeName(j));
+                }
             }
-            break;
         }
     }
-    SDL_SetKeyName(SDLK_APPLICATION, "menu");
+
+    SDL_zero(keyboard);
+    data->keyboard = SDL_AddKeyboard(&keyboard, -1);
+    X11_UpdateKeymap(this);
+
+    SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
 
     return 0;
 }
 
-SDLKey
-X11_GetLayoutKey(_THIS, SDLKey physicalKey)
+void
+X11_UpdateKeymap(_THIS)
 {
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
-    int code = 0;
-    KeySym sym;
-    SDLKey layoutKey;
-
-    switch (physicalKey) {
-    case SDLK_UNKNOWN:
-        return physicalKey;
+    int i;
+    SDL_scancode scancode;
+    SDLKey keymap[SDL_NUM_SCANCODES];
 
-        /* Shortcut handling of keypad numbers because on my PC their
-           primary KeySyms are not the numbers that I want but
-           XK_KP_Home, XK_KP_Up etc. The downside is that this gets us
-           latin numerals even on e.g. an Arabic layout. */
-    case SDLK_KP_1:
-        return '1';
-    case SDLK_KP_2:
-        return '2';
-    case SDLK_KP_3:
-        return '3';
-    case SDLK_KP_4:
-        return '4';
-    case SDLK_KP_5:
-        return '5';
-    case SDLK_KP_6:
-        return '6';
-    case SDLK_KP_7:
-        return '7';
-    case SDLK_KP_8:
-        return '8';
-    case SDLK_KP_9:
-        return '9';
-    case SDLK_KP_0:
-        return '0';
-    case SDLK_KP_PERIOD:
-        return '.';
-    default:
-        break;                  /* just to avoid a compiler warning */
-    }
+    SDL_GetDefaultKeymap(keymap);
+
+    for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
 
-    /* Look up physicalKey to get an X11 KeyCode - linear search isn't
-       terribly efficient, this might have to be optimized. */
-    while ((code < KeyCodeTableSize) &&
-           (physicalKey != data->keyCodeToSDLKTable[code])) {
-        code++;
-    }
-
-    if (code == KeyCodeTableSize) {
-        return physicalKey;
-    }
-    /* Get the corresponding KeySym - this is where the keyboard
-       layout comes into play */
-    sym = XKeycodeToKeysym(data->display, code, 0);
+        /* Make sure this scancode is a valid character scancode */
+        scancode = data->key_layout[i];
+        if (scancode == SDL_SCANCODE_UNKNOWN ||
+            (keymap[scancode] & SDLK_SCANCODE_MASK)) {
+            continue;
+        }
 
-    /* Try our own KeySym-to-layout-key-code table: it handles all
-       keys whose layout code is an SDLK_ one, including a few where
-       X11_KeySymToUcs4() would yield a character, but not a suitable
-       one as a key name (e.g. space), and some that are character
-       keys for our purposes, but aren't handled by X11_KeySymToUcs4()
-       (dead keys, keypad operations). */
-
-    layoutKey = X11_KeySymToSDLKey(sym, SDL_FALSE);
-
-    /* If it wasn't handled by X11_KeySymToSDLKey(), it's most
-       probably a plain character KeySym that X11_KeySymToUcs4()
-       (ripped from X.org) knows. */
-
-    if (layoutKey == SDLK_UNKNOWN) {
-        unsigned int ucs = X11_KeySymToUcs4(sym);
-        if (ucs != 0)
-            layoutKey = (SDLKey) ucs;
+        keymap[scancode] =
+            (SDLKey) X11_KeySymToUcs4(XKeycodeToKeysym(data->display, i, 0));
     }
-
-    /* Still no success? Give up. */
-    if (layoutKey == SDLK_UNKNOWN) {
-        return physicalKey;
-    }
-
-    return layoutKey;
+    SDL_SetKeymap(data->keyboard, 0, keymap, SDL_NUM_SCANCODES);
 }
 
 void
@@ -1032,18 +401,6 @@
 {
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
 
-    if (data->keyCodeToSDLKTable != NULL) {
-        /* If it's not one of the predefined tables, it was malloced
-           and must be freed */
-        SDLKey **table = keyCodeToSDLKeyTables;
-        while (*table != NULL && *table != data->keyCodeToSDLKTable) {
-            table++;
-        }
-        if (*table == NULL)
-            SDL_free(data->keyCodeToSDLKTable);
-        data->keyCodeToSDLKTable = NULL;
-    }
-
     SDL_DelKeyboard(data->keyboard);
 }
 
--- a/src/video/x11/SDL_x11keyboard.h	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/video/x11/SDL_x11keyboard.h	Thu Feb 07 15:31:09 2008 +0000
@@ -25,7 +25,7 @@
 #define _SDL_x11keyboard_h
 
 extern int X11_InitKeyboard(_THIS);
-extern SDLKey X11_GetLayoutKey(_THIS, SDLKey physicalKey);
+extern void X11_UpdateKeymap(_THIS);
 extern void X11_QuitKeyboard(_THIS);
 
 #endif /* _SDL_x11keyboard_h */
--- a/src/video/x11/SDL_x11sym.h	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/video/x11/SDL_x11sym.h	Thu Feb 07 15:31:09 2008 +0000
@@ -48,6 +48,7 @@
 SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c),(a,b,c),return)
 SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c),(a,b,c),return)
 SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b),(a,b),return)
+SDL_X11_SYM(int,XDisplayKeycodes,(Display* a,int* b,int* c),(a,b,c),return)
 SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a),(a),return)
 SDL_X11_SYM(int,XEventsQueued,(Display* a,int b),(a,b),return)
 SDL_X11_SYM(Bool,XFilterEvent,(XEvent *event,Window w),(event,w),return)
@@ -73,6 +74,7 @@
 SDL_X11_SYM(Status,XIconifyWindow,(Display* a,Window b,int c),(a,b,c),return)
 SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return)
 SDL_X11_SYM(KeyCode,XKeysymToKeycode,(Display* a,KeySym b),(a,b),return)
+SDL_X11_SYM(char*,XKeysymToString,(KeySym a),(a),return)
 SDL_X11_SYM(int,XKillClient,(Display* a,XID b),(a,b),return)
 SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return)
 SDL_X11_SYM(XPixmapFormatValues*,XListPixmapFormats,(Display* a,int* b),(a,b),return)
--- a/src/video/x11/SDL_x11video.c	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/video/x11/SDL_x11video.c	Thu Feb 07 15:31:09 2008 +0000
@@ -171,7 +171,6 @@
     device->SetDisplayGammaRamp = X11_SetDisplayGammaRamp;
     device->GetDisplayGammaRamp = X11_GetDisplayGammaRamp;
     device->PumpEvents = X11_PumpEvents;
-    device->GetLayoutKey = X11_GetLayoutKey;
 
     device->CreateWindow = X11_CreateWindow;
     device->CreateWindowFrom = X11_CreateWindowFrom;
--- a/src/video/x11/SDL_x11video.h	Tue Feb 05 07:30:50 2008 +0000
+++ b/src/video/x11/SDL_x11video.h	Thu Feb 07 15:31:09 2008 +0000
@@ -70,7 +70,7 @@
     int mouse;
     int keyboard;
     Atom WM_DELETE_WINDOW;
-    SDLKey *keyCodeToSDLKTable;
+    SDL_scancode key_layout[256];
 } SDL_VideoData;
 
 #endif /* _SDL_x11video_h */
--- a/test/checkkeys.c	Tue Feb 05 07:30:50 2008 +0000
+++ b/test/checkkeys.c	Thu Feb 07 15:31:09 2008 +0000
@@ -91,6 +91,7 @@
 static void
 PrintText(char *text)
 {
+    printf("Text: %s\n", text);
 }
 
 int
@@ -124,13 +125,6 @@
         quit(2);
     }
 
-    /* Enable UNICODE translation for keyboard input */
-    SDL_EnableUNICODE(1);
-
-    /* Enable auto repeat for keyboard input */
-    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,
-                        SDL_DEFAULT_REPEAT_INTERVAL);
-
     /* Watch keystrokes */
     done = 0;
     while (!done) {