Index: src/events/SDL_keyboard.c =================================================================== --- src/events/SDL_keyboard.c (revision 3501) +++ src/events/SDL_keyboard.c (working copy) @@ -36,6 +36,47 @@ static int SDL_current_keyboard; static SDL_Keyboard **SDL_keyboards; +/* Taken from SDL_iconv() */ +static char *encodeUtf8(Uint32 ch, char *dst) +{ + Uint8 *p = (Uint8 *) dst; + if (ch <= 0x7F) { + *p = (Uint8) ch; + ++dst; + } else if (ch <= 0x7FF) { + p[0] = 0xC0 | (Uint8) ((ch >> 6) & 0x1F); + p[1] = 0x80 | (Uint8) (ch & 0x3F); + dst += 2; + } else if (ch <= 0xFFFF) { + p[0] = 0xE0 | (Uint8) ((ch >> 12) & 0x0F); + p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); + p[2] = 0x80 | (Uint8) (ch & 0x3F); + dst += 3; + } else if (ch <= 0x1FFFFF) { + p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07); + p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); + p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); + p[3] = 0x80 | (Uint8) (ch & 0x3F); + dst += 4; + } else if (ch <= 0x3FFFFFF) { + p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03); + p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F); + p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); + p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); + p[4] = 0x80 | (Uint8) (ch & 0x3F); + dst += 5; + } else { + p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01); + p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F); + p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F); + p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F); + p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F); + p[5] = 0x80 | (Uint8) (ch & 0x3F); + dst += 6; + } + return dst; +} + /* Public functions */ int SDL_KeyboardInit(void) @@ -227,21 +268,14 @@ /* SDLK_INDEX(layoutKey) is the unicode code point of the character generated by the key */ static char buffer[9]; /* 6 (maximal UTF-8 char length) + 2 ([] for keypad) + 1 (null teminator) */ char *bufferPtr = &buffer[1]; - SDL_iconv_t cd; - size_t inbytesleft = 4, outbytesleft = 8; Uint32 codepoint = SDLK_INDEX(layoutKey); - const char *codepointPtr = (const char *) &codepoint; /* Unaccented letter keys on latin keyboards are normally labeled in upper case (and probably on others like Greek or Cyrillic too, so if you happen to know for sure, please adapt this). */ if (codepoint >= 'a' && codepoint <= 'z') { codepoint -= 32; } - cd = SDL_iconv_open("UTF-8", "UCS-4"); - if (cd == (SDL_iconv_t) (-1)) - return ""; - SDL_iconv(cd, &codepointPtr, &inbytesleft, &bufferPtr, &outbytesleft); - SDL_iconv_close(cd); + bufferPtr = encodeUtf8(codepoint, bufferPtr); *bufferPtr = '\0'; if ((layoutKey & SDL_KEY_KEYPAD_BIT) != 0) { Index: src/video/x11/SDL_x11events.c =================================================================== --- src/video/x11/SDL_x11events.c (revision 3501) +++ src/video/x11/SDL_x11events.c (working copy) @@ -30,6 +30,27 @@ #include "../../events/SDL_events_c.h" +/* Check to see if this is a repeated key. + (idea shamelessly lifted from GII -- thanks guys! :) + */ +static int X11_KeyRepeat(Display *display, XEvent *event) +{ + XEvent peekevent; + int repeated; + + repeated = 0; + if ( XPending(display) ) { + XPeekEvent(display, &peekevent); + if ( (peekevent.type == KeyPress) && + (peekevent.xkey.keycode == event->xkey.keycode) && + ((peekevent.xkey.time-event->xkey.time) < 2) ) { + repeated = 1; + XNextEvent(display, &peekevent); + } + } + return(repeated); +} + static void X11_DispatchEvent(_THIS) { @@ -167,6 +188,16 @@ /* Key press? */ case KeyPress:{ + KeyCode keycode = xevent.xkey.keycode; + if (!X11_KeyRepeat(videodata->display, &xevent)) { + SDLKey physicalKey = videodata->keyCodeToSDLKTable[keycode - 8]; + SDL_SendKeyboardKey(videodata->keyboard, SDL_PRESSED, (Uint8)keycode, physicalKey); +#if 1 + if (physicalKey == SDLK_UNKNOWN) { + fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL mailing list or to Christian Walther . X11 KeyCode is %d, X11 KeySym 0x%X.\n", (int)keycode, (unsigned int)XKeycodeToKeysym(videodata->display, keycode, 0)); + } +#endif + } #if 0 /* FIXME */ static SDL_keysym saved_keysym; SDL_keysym keysym; @@ -236,26 +267,17 @@ /* Key release? */ case KeyRelease:{ -#if 0 /* FIXME */ - SDL_keysym keysym; KeyCode keycode = xevent.xkey.keycode; #ifdef DEBUG_XEVENTS printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode); #endif /* Check to see if this is a repeated key */ - if (X11_KeyRepeat(SDL_Display, &xevent)) { + if (X11_KeyRepeat(videodata->display, &xevent)) { break; } - /* Get the translated SDL virtual keysym */ - keysym.scancode = keycode; - keysym.sym = X11_TranslateKeycode(SDL_Display, keycode); - keysym.mod = KMOD_NONE; - keysym.unicode = 0; - - posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym); -#endif // 0 + SDL_SendKeyboardKey(videodata->keyboard, SDL_RELEASED, (Uint8)keycode, videodata->keyCodeToSDLKTable[keycode - 8]); } break; Index: src/video/x11/SDL_x11keyboard.h =================================================================== --- src/video/x11/SDL_x11keyboard.h (revision 3501) +++ src/video/x11/SDL_x11keyboard.h (working copy) @@ -24,7 +24,8 @@ #ifndef _SDL_x11keyboard_h #define _SDL_x11keyboard_h -extern void X11_InitKeyboard(_THIS); +extern int X11_InitKeyboard(_THIS); +extern SDLKey X11_GetLayoutKey(_THIS, SDLKey physicalKey); extern void X11_QuitKeyboard(_THIS); #endif /* _SDL_x11keyboard_h */ Index: src/video/x11/SDL_x11video.c =================================================================== --- src/video/x11/SDL_x11video.c (revision 3501) +++ src/video/x11/SDL_x11video.c (working copy) @@ -171,6 +171,7 @@ device->SetDisplayGammaRamp = X11_SetDisplayGammaRamp; device->GetDisplayGammaRamp = X11_GetDisplayGammaRamp; device->PumpEvents = X11_PumpEvents; + device->GetLayoutKey = X11_GetLayoutKey; device->CreateWindow = X11_CreateWindow; device->CreateWindowFrom = X11_CreateWindowFrom; @@ -242,7 +243,7 @@ // GDI_AddRenderDriver(_this); //#endif - X11_InitKeyboard(_this); + if (X11_InitKeyboard(_this) != 0) return -1; X11_InitMouse(_this); return 0; Index: src/video/x11/SDL_x11video.h =================================================================== --- src/video/x11/SDL_x11video.h (revision 3501) +++ src/video/x11/SDL_x11video.h (working copy) @@ -70,6 +70,7 @@ int mouse; int keyboard; Atom WM_DELETE_WINDOW; + SDLKey *keyCodeToSDLKTable; } SDL_VideoData; #endif /* _SDL_x11video_h */ Index: src/video/x11/imKStoUCS.c =================================================================== --- src/video/x11/imKStoUCS.c (revision 0) +++ src/video/x11/imKStoUCS.c (revision 0) @@ -0,0 +1,344 @@ +/* Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is fur- +nished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- +NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the XFree86 Project shall not +be used in advertising or otherwise to promote the sale, use or other deal- +ings in this Software without prior written authorization from the XFree86 +Project. +*/ + +/* $XFree86: xc/lib/X11/imKStoUCS.c,v 1.4 2003/04/29 11:29:18 pascal Exp $ */ + +#include + +static unsigned short const keysym_to_unicode_1a1_1ff[] = { + 0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */ + 0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */ + 0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */ + 0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */ + 0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */ + 0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */ + 0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */ + 0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */ + 0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */ + 0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */ + 0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */ + 0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */ +}; + +static unsigned short const keysym_to_unicode_2a1_2fe[] = { + 0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */ + 0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */ + 0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */ + 0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */ + 0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */ + 0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */ +}; + +static unsigned short const keysym_to_unicode_3a2_3fe[] = { + 0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */ + 0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */ + 0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */ + 0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */ + 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */ + 0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */ + 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */ + 0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */ + 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */ +}; + +static unsigned short const keysym_to_unicode_4a1_4df[] = { + 0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */ + 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */ + 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */ + 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */ + 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */ + 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */ + 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */ + 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */ +}; + +static unsigned short const keysym_to_unicode_590_5fe[] = { + 0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */ + 0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */ + + 0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */ + 0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */ + 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */ + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */ + 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */ + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */ + 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */ + 0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */ +}; + +static unsigned short keysym_to_unicode_680_6ff[] = { + 0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */ + 0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */ + 0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */ + 0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */ + 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */ + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */ + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */ + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */ + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */ + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */ + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */ + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */ +}; + +static unsigned short const keysym_to_unicode_7a1_7f9[] = { + 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */ + 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */ + 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */ + 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */ + 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */ + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */ + 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */ + 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */ + 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */ + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */ + 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */ + 0x03c8, 0x03c9 /* 0x07f8-0x07ff */ +}; + +static unsigned short const keysym_to_unicode_8a4_8fe[] = { + 0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */ + 0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */ + 0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */ + 0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x22a2, 0x0000, /* 0x08c8-0x08cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */ + 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e8-0x08ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */ + 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */ +}; + +static unsigned short const keysym_to_unicode_9df_9f8[] = { + 0x2422, /* 0x09d8-0x09df */ + 0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */ + 0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */ + 0x2502 /* 0x09f8-0x09ff */ +}; + +static unsigned short const keysym_to_unicode_aa1_afe[] = { + 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */ + 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */ + 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */ + 0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */ + 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */ + 0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */ + 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */ + 0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */ + 0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */ + 0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */ + 0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */ + 0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */ +}; + +/* none of the APL keysyms match the Unicode characters */ + +static unsigned short const keysym_to_unicode_cdf_cfa[] = { + 0x2017, /* 0x0cd8-0x0cdf */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */ + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */ + 0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */ +}; + +static unsigned short const keysym_to_unicode_da1_df9[] = { + 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */ + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */ + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */ + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */ + 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */ + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */ + 0x0e58, 0x0e59 /* 0x0df8-0x0dff */ +}; + +static unsigned short const keysym_to_unicode_ea0_eff[] = { + 0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */ + 0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */ + 0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */ + 0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */ + 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */ + 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */ + 0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */ + 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */ + 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */ + 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */ + 0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */ + 0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */ +}; + +static unsigned short keysym_to_unicode_12a1_12fe[] = { + 0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */ + 0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */ + 0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */ + 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */ + 0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */ + 0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */ +}; + +static unsigned short const keysym_to_unicode_13bc_13be[] = { + 0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */ +}; + +static unsigned short keysym_to_unicode_14a1_14ff[] = { + 0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */ + 0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */ + 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */ + 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */ + 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */ + 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */ + 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */ + 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */ + 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */ + 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */ + 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */ + 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */ +}; + +static unsigned short keysym_to_unicode_15d0_15f6[] = { + 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */ + 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */ + 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */ + 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */ + 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */ +}; + +static unsigned short keysym_to_unicode_16a0_16f6[] = { + 0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */ + 0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */ + 0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */ + 0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */ + 0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */ + 0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */ +}; + +static unsigned short const keysym_to_unicode_1e9f_1eff[] = { + 0x0303, + 0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */ + 0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */ + 0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */ + 0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */ + 0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */ + 0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */ + 0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */ + 0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */ + 0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */ + 0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */ + 0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */ + 0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */ +}; + +static unsigned short const keysym_to_unicode_20a0_20ac[] = { + 0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */ + 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ +}; + +unsigned int +KeySymToUcs4(KeySym keysym) +{ + /* 'Unicode keysym' */ + if ((keysym & 0xff000000) == 0x01000000) + return (keysym & 0x00ffffff); + + if (keysym > 0 && keysym < 0x100) + return keysym; + else if (keysym > 0x1a0 && keysym < 0x200) + return keysym_to_unicode_1a1_1ff[keysym - 0x1a1]; + else if (keysym > 0x2a0 && keysym < 0x2ff) + return keysym_to_unicode_2a1_2fe[keysym - 0x2a1]; + else if (keysym > 0x3a1 && keysym < 0x3ff) + return keysym_to_unicode_3a2_3fe[keysym - 0x3a2]; + else if (keysym > 0x4a0 && keysym < 0x4e0) + return keysym_to_unicode_4a1_4df[keysym - 0x4a1]; + else if (keysym > 0x589 && keysym < 0x5ff) + return keysym_to_unicode_590_5fe[keysym - 0x590]; + else if (keysym > 0x67f && keysym < 0x700) + return keysym_to_unicode_680_6ff[keysym - 0x680]; + else if (keysym > 0x7a0 && keysym < 0x7fa) + return keysym_to_unicode_7a1_7f9[keysym - 0x7a1]; + else if (keysym > 0x8a3 && keysym < 0x8ff) + return keysym_to_unicode_8a4_8fe[keysym - 0x8a4]; + else if (keysym > 0x9de && keysym < 0x9f9) + return keysym_to_unicode_9df_9f8[keysym - 0x9df]; + else if (keysym > 0xaa0 && keysym < 0xaff) + return keysym_to_unicode_aa1_afe[keysym - 0xaa1]; + else if (keysym > 0xcde && keysym < 0xcfb) + return keysym_to_unicode_cdf_cfa[keysym - 0xcdf]; + else if (keysym > 0xda0 && keysym < 0xdfa) + return keysym_to_unicode_da1_df9[keysym - 0xda1]; + else if (keysym > 0xe9f && keysym < 0xf00) + return keysym_to_unicode_ea0_eff[keysym - 0xea0]; + else if (keysym > 0x12a0 && keysym < 0x12ff) + return keysym_to_unicode_12a1_12fe[keysym - 0x12a1]; + else if (keysym > 0x13bb && keysym < 0x13bf) + return keysym_to_unicode_13bc_13be[keysym - 0x13bc]; + else if (keysym > 0x14a0 && keysym < 0x1500) + return keysym_to_unicode_14a1_14ff[keysym - 0x14a1]; + else if (keysym > 0x15cf && keysym < 0x15f7) + return keysym_to_unicode_15d0_15f6[keysym - 0x15d0]; + else if (keysym > 0x169f && keysym < 0x16f7) + return keysym_to_unicode_16a0_16f6[keysym - 0x16a0]; + else if (keysym > 0x1e9e && keysym < 0x1f00) + return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f]; + else if (keysym > 0x209f && keysym < 0x20ad) + return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; + else + return 0; +} Property changes on: src/video/x11/imKStoUCS.c ___________________________________________________________________ Name: svn:keywords + Id Index: src/video/x11/SDL_x11keytables.h =================================================================== --- src/video/x11/SDL_x11keytables.h (revision 0) +++ src/video/x11/SDL_x11keytables.h (revision 0) @@ -0,0 +1,728 @@ +/* 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[] = { + macKeyCodeToSDLK, + xorgLinuxKeyCodeToSDLK, + 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. +*/ +static SDLKey macKeyCodeToSDLK[248] = { + /* 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 +}; + +/* 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[248] = { + /* 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 +}; + +/* *INDENT-ON* */ +/*---------------------------------------------------------------------------*/ + +/* 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[] = { + /* 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 */ +}; Property changes on: src/video/x11/SDL_x11keytables.h ___________________________________________________________________ Name: svn:keywords + Id Index: src/video/x11/SDL_x11keyboard.c =================================================================== --- src/video/x11/SDL_x11keyboard.c (revision 3501) +++ src/video/x11/SDL_x11keyboard.c (working copy) @@ -25,20 +25,192 @@ #include "../../events/SDL_keyboard_c.h" -void +#include +#include "SDL_x11keytables.h" + +unsigned int KeySymToUcs4(KeySym keysym); /* from imKStoUCS.c */ + +/* 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 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; +} + +int X11_InitKeyboard(_THIS) { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; SDL_Keyboard keyboard; + SDLKey **table; + SDL_bool ok; + int i; + KeyCode code; + SDLKey sdlkey; + + /* 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). + */ + struct { KeySym sym; SDLKey key; } fingerprint[] = { + {XK_Tab, SDLK_TAB}, + {XK_Return, SDLK_RETURN}, + {XK_Escape, SDLK_ESCAPE}, + {XK_space, SDLK_SPACE} + }; SDL_zero(keyboard); data->keyboard = SDL_AddKeyboard(&keyboard, -1); + + /* Determine which X11 KeyCode to SDL physical key code table to use */ + + for (table = keyCodeToSDLKeyTables; *table != NULL; table++) { + ok = SDL_TRUE; + for (i = 0; i < SDL_arraysize(fingerprint); i++) { + code = XKeysymToKeycode(data->display, fingerprint[i].sym); + if (code != 0 && (*table)[code - 8] != fingerprint[i].key) { + ok = SDL_FALSE; + break; + } + } + if (ok) break; + } + if (*table != NULL) { + /* Found a suitable one among the predefined tables */ + data->keyCodeToSDLKTable = *table; + } + 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 or to Christian Walther .\n"); +#endif + data->keyCodeToSDLKTable = SDL_malloc(248*sizeof(SDLKey)); + if (data->keyCodeToSDLKTable == NULL) { + SDL_OutOfMemory(); + return -1; + } + for (code = 255; code >= 8; code--) { + data->keyCodeToSDLKTable[code - 8] = X11_KeySymToSDLKey(XKeycodeToKeysym(data->display, code, 0), SDL_TRUE); + } + } + + /* Set some non-default key names */ + + for (code = 0; code < 248; 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+8, 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; + } + break; + } + } + SDL_SetKeyName(SDLK_APPLICATION, "menu"); + + return 0; } +SDLKey +X11_GetLayoutKey(_THIS, SDLKey physicalKey) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + KeyCode code = 0; + KeySym sym; + SDLKey layoutKey; + + switch (physicalKey) { + case SDLK_UNKNOWN: return physicalKey; + /* 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 */ + } + + /* Look up physicalKey to get an X11 KeyCode - linear search isn't terribly efficient, this might have to be optimized. */ + while (code < 248 && physicalKey != data->keyCodeToSDLKTable[code]) code++; + if (code == 248) return physicalKey; + code += 8; + /* Get the corresponding KeySym - this is where the keyboard layout comes into play */ + sym = XKeycodeToKeysym(data->display, code, 0); + + /* Try our own KeySym-to-layout-key-code table: it handles all keys whose layout code is an SDLK_ one, including a few where 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 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 KeySymToUcs4() (ripped from X.org) knows. */ + if (layoutKey == SDLK_UNKNOWN) { + unsigned int ucs = KeySymToUcs4(sym); + if (ucs != 0) layoutKey = (SDLKey)ucs; + } + + /* Still no success? Give up. */ + if (layoutKey == SDLK_UNKNOWN) return physicalKey; + + return layoutKey; +} + void X11_QuitKeyboard(_THIS) { 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); } Index: include/SDL_compat.h =================================================================== --- include/SDL_compat.h (revision 3501) +++ include/SDL_compat.h (working copy) @@ -185,7 +185,7 @@ #define SDLK_SCROLLOCK SDLK_SCROLLLOCK #define SDLK_PRINT SDLK_PRINTSCREEN -/* These key constants are obsoleted the new keyboard handling, their definitions here correspond to how they appear on a US keyboard. */ +/* These key constants are obsoleted by the new keyboard handling, their definitions here correspond to how they appear on a US keyboard. */ #define SDLK_EXCLAIM SDLK_1 #define SDLK_QUOTEDBL SDLK_APOSTROPHE #define SDLK_HASH SDLK_3