Commit 3209bc5b authored by Sam Lantinga's avatar Sam Lantinga

Fixed bug #669

Generate a full set of SDLKey mappings when setting up the keyboard layout

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403463
parent fe0aae4a
...@@ -31,253 +31,107 @@ ...@@ -31,253 +31,107 @@
#include "imKStoUCS.h" #include "imKStoUCS.h"
static KeySym XKeySymTable[SDL_NUM_SCANCODES] = { /* *INDENT-OFF* */
0, 0, 0, 0, static struct {
XK_a, KeySym keysym;
XK_b, SDLKey sdlkey;
XK_c, } KeySymToSDLKey[] = {
XK_d, { XK_Return, SDLK_RETURN },
XK_e, { XK_Escape, SDLK_ESCAPE },
XK_f, { XK_BackSpace, SDLK_BACKSPACE },
XK_g, { XK_Tab, SDLK_TAB },
XK_h, { XK_Caps_Lock, SDLK_CAPSLOCK },
XK_i, { XK_F1, SDLK_F1 },
XK_j, { XK_F2, SDLK_F2 },
XK_k, { XK_F3, SDLK_F3 },
XK_l, { XK_F4, SDLK_F4 },
XK_m, { XK_F5, SDLK_F5 },
XK_n, { XK_F6, SDLK_F6 },
XK_o, { XK_F7, SDLK_F7 },
XK_p, { XK_F8, SDLK_F8 },
XK_q, { XK_F9, SDLK_F9 },
XK_r, { XK_F10, SDLK_F10 },
XK_s, { XK_F11, SDLK_F11 },
XK_t, { XK_F12, SDLK_F12 },
XK_u, { XK_Print, SDLK_PRINTSCREEN },
XK_v, { XK_Scroll_Lock, SDLK_SCROLLLOCK },
XK_w, { XK_Pause, SDLK_PAUSE },
XK_x, { XK_Insert, SDLK_INSERT },
XK_y, { XK_Home, SDLK_HOME },
XK_z, { XK_Prior, SDLK_PAGEUP },
XK_1, { XK_Delete, SDLK_DELETE },
XK_2, { XK_End, SDLK_END },
XK_3, { XK_Next, SDLK_PAGEDOWN },
XK_4, { XK_Right, SDLK_RIGHT },
XK_5, { XK_Left, SDLK_LEFT },
XK_6, { XK_Down, SDLK_DOWN },
XK_7, { XK_Up, SDLK_UP },
XK_8, { XK_Num_Lock, SDLK_NUMLOCKCLEAR },
XK_9, { XK_KP_Divide, SDLK_KP_DIVIDE },
XK_0, { XK_KP_Multiply, SDLK_KP_MULTIPLY },
XK_Return, { XK_KP_Subtract, SDLK_KP_MINUS },
XK_Escape, { XK_KP_Add, SDLK_KP_PLUS },
XK_BackSpace, { XK_KP_Enter, SDLK_KP_ENTER },
XK_Tab, { XK_KP_Delete, SDLK_KP_PERIOD },
XK_space, { XK_KP_End, SDLK_KP_1 },
XK_minus, { XK_KP_Down, SDLK_KP_2 },
XK_equal, { XK_KP_Next, SDLK_KP_3 },
XK_bracketleft, { XK_KP_Left, SDLK_KP_4 },
XK_bracketright, { XK_KP_Begin, SDLK_KP_5 },
XK_backslash, { XK_KP_Right, SDLK_KP_6 },
0, /* SDL_SCANCODE_NONUSHASH ? */ { XK_KP_Home, SDLK_KP_7 },
XK_semicolon, { XK_KP_Up, SDLK_KP_8 },
XK_apostrophe, { XK_KP_Prior, SDLK_KP_9 },
XK_grave, { XK_KP_Insert, SDLK_KP_0 },
XK_comma, { XK_KP_Decimal, SDLK_KP_PERIOD },
XK_period, { XK_KP_1, SDLK_KP_1 },
XK_slash, { XK_KP_2, SDLK_KP_2 },
XK_Caps_Lock, { XK_KP_3, SDLK_KP_3 },
XK_F1, { XK_KP_4, SDLK_KP_4 },
XK_F2, { XK_KP_5, SDLK_KP_5 },
XK_F3, { XK_KP_6, SDLK_KP_6 },
XK_F4, { XK_KP_7, SDLK_KP_7 },
XK_F5, { XK_KP_8, SDLK_KP_8 },
XK_F6, { XK_KP_9, SDLK_KP_9 },
XK_F7, { XK_KP_0, SDLK_KP_0 },
XK_F8, { XK_KP_Decimal, SDLK_KP_PERIOD },
XK_F9, { XK_Hyper_R, SDLK_APPLICATION },
XK_F10, { XK_KP_Equal, SDLK_KP_EQUALS },
XK_F11, { XK_F13, SDLK_F13 },
XK_F12, { XK_F14, SDLK_F14 },
XK_Print, { XK_F15, SDLK_F15 },
XK_Scroll_Lock, { XK_F16, SDLK_F16 },
XK_Pause, { XK_F17, SDLK_F17 },
XK_Insert, { XK_F18, SDLK_F18 },
XK_Home, { XK_F19, SDLK_F19 },
XK_Prior, { XK_F20, SDLK_F20 },
XK_Delete, { XK_F21, SDLK_F21 },
XK_End, { XK_F22, SDLK_F22 },
XK_Next, { XK_F23, SDLK_F23 },
XK_Right, { XK_F24, SDLK_F24 },
XK_Left, { XK_Execute, SDLK_EXECUTE },
XK_Down, { XK_Help, SDLK_HELP },
XK_Up, { XK_Menu, SDLK_MENU },
XK_Num_Lock, { XK_Select, SDLK_SELECT },
XK_KP_Divide, { XK_Cancel, SDLK_STOP },
XK_KP_Multiply, { XK_Redo, SDLK_AGAIN },
XK_KP_Subtract, { XK_Undo, SDLK_UNDO },
XK_KP_Add, { XK_Find, SDLK_FIND },
XK_KP_Enter, { XK_KP_Separator, SDLK_KP_COMMA },
XK_KP_1, { XK_Sys_Req, SDLK_SYSREQ },
XK_KP_2, { XK_Control_L, SDLK_LCTRL },
XK_KP_3, { XK_Shift_L, SDLK_LSHIFT },
XK_KP_4, { XK_Alt_L, SDLK_LALT },
XK_KP_5, { XK_Meta_L, SDLK_LGUI },
XK_KP_6, { XK_Super_L, SDLK_LGUI },
XK_KP_7, { XK_Control_R, SDLK_RCTRL },
XK_KP_8, { XK_Shift_R, SDLK_RSHIFT },
XK_KP_9, { XK_Alt_R, SDLK_RALT },
XK_KP_0, { XK_Meta_R, SDLK_RGUI },
XK_KP_Decimal, { XK_Super_R, SDLK_RGUI },
0, /* SDL_SCANCODE_NONUSBACKSLASH ? */ { XK_Mode_switch, SDLK_MODE },
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 ? */
}; };
/* *INDENT-OFF* */
static struct static struct
{ {
SDL_scancode *table; SDL_scancode *table;
...@@ -289,6 +143,31 @@ static struct ...@@ -289,6 +143,31 @@ static struct
}; };
/* *INDENT-OFF* */ /* *INDENT-OFF* */
static SDLKey
X11_KeyCodeToSDLKey(Display *display, KeyCode keycode)
{
KeySym keysym;
unsigned int ucs4;
int i;
keysym = XKeycodeToKeysym(display, keycode, 0);
if (keysym == NoSymbol) {
return SDLK_UNKNOWN;
}
ucs4 = X11_KeySymToUcs4(keysym);
if (ucs4) {
return (SDLKey) ucs4;
}
for (i = 0; i < SDL_arraysize(KeySymToSDLKey); ++i) {
if (keysym == KeySymToSDLKey[i].keysym) {
return KeySymToSDLKey[i].sdlkey;
}
}
return SDLK_UNKNOWN;
}
int int
X11_InitKeyboard(_THIS) X11_InitKeyboard(_THIS)
{ {
...@@ -296,12 +175,15 @@ X11_InitKeyboard(_THIS) ...@@ -296,12 +175,15 @@ X11_InitKeyboard(_THIS)
SDL_Keyboard keyboard; SDL_Keyboard keyboard;
int i, j; int i, j;
int min_keycode, max_keycode; int min_keycode, max_keycode;
SDL_scancode fingerprint_scancodes[] = { struct {
SDL_SCANCODE_HOME, SDL_scancode scancode;
SDL_SCANCODE_PAGEUP, KeySym keysym;
SDL_SCANCODE_PAGEDOWN int value;
} fingerprint[] = {
{ SDL_SCANCODE_HOME, XK_Home, 0 },
{ SDL_SCANCODE_PAGEUP, XK_Prior, 0 },
{ SDL_SCANCODE_PAGEDOWN, XK_Next, 0 },
}; };
int fingerprint[3];
SDL_bool fingerprint_detected; SDL_bool fingerprint_detected;
XAutoRepeatOn(data->display); XAutoRepeatOn(data->display);
...@@ -309,10 +191,9 @@ X11_InitKeyboard(_THIS) ...@@ -309,10 +191,9 @@ X11_InitKeyboard(_THIS)
/* Try to determine which scancodes are being used based on fingerprint */ /* Try to determine which scancodes are being used based on fingerprint */
fingerprint_detected = SDL_FALSE; fingerprint_detected = SDL_FALSE;
XDisplayKeycodes(data->display, &min_keycode, &max_keycode); XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
for (i = 0; i < SDL_arraysize(fingerprint_scancodes); ++i) { for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
fingerprint[i] = fingerprint[i].value =
XKeysymToKeycode(data->display, XKeysymToKeycode(data->display, fingerprint[i].keysym) -
XKeySymTable[fingerprint_scancodes[i]]) -
min_keycode; min_keycode;
} }
for (i = 0; i < SDL_arraysize(scancode_set); ++i) { for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
...@@ -321,12 +202,12 @@ X11_InitKeyboard(_THIS) ...@@ -321,12 +202,12 @@ X11_InitKeyboard(_THIS)
continue; continue;
} }
for (j = 0; j < SDL_arraysize(fingerprint); ++j) { for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
if (fingerprint[j] < 0 if (fingerprint[j].value < 0
|| fingerprint[j] >= scancode_set[i].table_size) { || fingerprint[j].value >= scancode_set[i].table_size) {
break; break;
} }
if (scancode_set[i].table[fingerprint[j]] != if (scancode_set[i].table[fingerprint[j].value] !=
fingerprint_scancodes[j]) { fingerprint[j].scancode) {
break; break;
} }
} }
...@@ -340,23 +221,28 @@ X11_InitKeyboard(_THIS) ...@@ -340,23 +221,28 @@ X11_InitKeyboard(_THIS)
} }
if (!fingerprint_detected) { if (!fingerprint_detected) {
SDLKey keymap[SDL_NUM_SCANCODES];
printf printf
("Keyboard layout unknown, please send the following to the SDL mailing list (sdl@libsdl.org):\n"); ("Keyboard layout unknown, please send the following to the SDL mailing list (sdl@libsdl.org):\n");
/* Determine key_layout - only works on US QWERTY layout */ /* Determine key_layout - only works on US QWERTY layout */
SDL_GetDefaultKeymap(keymap);
for (i = min_keycode; i <= max_keycode; ++i) { for (i = min_keycode; i <= max_keycode; ++i) {
KeySym sym; KeySym sym;
sym = XKeycodeToKeysym(data->display, i, 0); sym = XKeycodeToKeysym(data->display, i, 0);
if (sym) { if (sym != NoSymbol) {
SDLKey key;
printf("code = %d, sym = 0x%X (%s) ", i - min_keycode, sym, printf("code = %d, sym = 0x%X (%s) ", i - min_keycode, sym,
XKeysymToString(sym)); XKeysymToString(sym));
for (j = 0; j < SDL_arraysize(XKeySymTable); ++j) { key = X11_KeyCodeToSDLKey(data->display, i);
if (XKeySymTable[j] == sym) { for (j = 0; j < SDL_arraysize(keymap); ++j) {
if (keymap[j] == key) {
data->key_layout[i] = (SDL_scancode) j; data->key_layout[i] = (SDL_scancode) j;
break; break;
} }
} }
if (j == SDL_arraysize(XKeySymTable)) { if (j == SDL_arraysize(keymap)) {
printf("scancode not found\n"); printf("scancode not found\n");
} else { } else {
printf("scancode = %d (%s)\n", j, SDL_GetScancodeName(j)); printf("scancode = %d (%s)\n", j, SDL_GetScancodeName(j));
...@@ -382,19 +268,17 @@ X11_UpdateKeymap(_THIS) ...@@ -382,19 +268,17 @@ X11_UpdateKeymap(_THIS)
SDL_scancode scancode; SDL_scancode scancode;
SDLKey keymap[SDL_NUM_SCANCODES]; SDLKey keymap[SDL_NUM_SCANCODES];
SDL_GetDefaultKeymap(keymap); SDL_zero(keymap);
for (i = 0; i < SDL_arraysize(data->key_layout); i++) { for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
/* Make sure this scancode is a valid character scancode */ /* Make sure this is a valid scancode */
scancode = data->key_layout[i]; scancode = data->key_layout[i];
if (scancode == SDL_SCANCODE_UNKNOWN || if (scancode == SDL_SCANCODE_UNKNOWN) {
(keymap[scancode] & SDLK_SCANCODE_MASK)) {
continue; continue;
} }
keymap[scancode] = keymap[scancode] = X11_KeyCodeToSDLKey(data->display, (KeyCode)i);
(SDLKey) X11_KeySymToUcs4(XKeycodeToKeysym(data->display, i, 0));
} }
SDL_SetKeymap(data->keyboard, 0, keymap, SDL_NUM_SCANCODES); SDL_SetKeymap(data->keyboard, 0, keymap, SDL_NUM_SCANCODES);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment