Annotation of hatari/src/keymap.c, revision 1.1.1.19

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - keymap.c
1.1.1.5   root        3: 
1.1.1.15  root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
1.1.1.3   root        7:   Here we process a key press and the remapping of the scancodes.
1.1       root        8: */
1.1.1.12  root        9: const char Keymap_fileid[] = "Hatari keymap.c : " __DATE__ " " __TIME__;
1.1       root       10: 
1.1.1.11  root       11: #include <ctype.h>
1.1       root       12: #include "main.h"
                     13: #include "keymap.h"
1.1.1.5   root       14: #include "configuration.h"
1.1.1.10  root       15: #include "file.h"
1.1.1.3   root       16: #include "ikbd.h"
                     17: #include "joy.h"
                     18: #include "shortcut.h"
1.1.1.11  root       19: #include "str.h"
1.1.1.3   root       20: #include "screen.h"
1.1.1.4   root       21: #include "debugui.h"
1.1.1.9   root       22: #include "log.h"
1.1       root       23: 
1.1.1.2   root       24: 
1.1.1.17  root       25: #if !WITH_SDL2
1.1.1.5   root       26: /* This table is used to translate a symbolic keycode to the (SDL) scancode */
                     27: static Uint8 SdlSymToSdlScan[SDLK_LAST];
1.1.1.17  root       28: #endif
1.1.1.5   root       29: 
1.1.1.17  root       30: /* Table for loaded keys: */
                     31: static int LoadedKeymap[KBD_MAX_SCANCODE][2];
1.1       root       32: 
1.1.1.3   root       33: /* List of ST scan codes to NOT de-bounce when running in maximum speed */
1.1.1.9   root       34: static const char DebounceExtendedKeys[] =
1.1.1.5   root       35: {
1.1.1.10  root       36:        0x1d,  /* CTRL */
                     37:        0x2a,  /* Left SHIFT */
                     38:        0x01,  /* ESC */
                     39:        0x38,  /* ALT */
                     40:        0x36,  /* Right SHIFT */
                     41:        0      /* term */
1.1.1.3   root       42: };
                     43: 
                     44: 
1.1.1.5   root       45: 
                     46: /*-----------------------------------------------------------------------*/
1.1.1.10  root       47: /**
                     48:  * Initialization.
                     49:  */
1.1.1.5   root       50: void Keymap_Init(void)
                     51: {
1.1.1.17  root       52: #if !WITH_SDL2
1.1.1.10  root       53:        memset(SdlSymToSdlScan, 0, sizeof(SdlSymToSdlScan));      /* Clear array */
1.1.1.17  root       54: #endif
1.1.1.10  root       55:        Keymap_LoadRemapFile(ConfigureParams.Keyboard.szMappingFileName);
1.1.1.5   root       56: }
                     57: 
1.1.1.17  root       58: /**
                     59:  * Map SDL symbolic key to ST scan code
                     60:  */
1.1.1.18  root       61: static char Keymap_SymbolicToStScanCode(SDL_keysym* pKeySym)
1.1.1.17  root       62: {
                     63:        char code;
                     64: 
                     65:        switch (pKeySym->sym)
                     66:        {
                     67:         case SDLK_BACKSPACE: code = 0x0E; break;
                     68:         case SDLK_TAB: code = 0x0F; break;
                     69:         case SDLK_CLEAR: code = 0x47; break;
                     70:         case SDLK_RETURN: code = 0x1C; break;
                     71:         case SDLK_ESCAPE: code = 0x01; break;
                     72:         case SDLK_SPACE: code = 0x39; break;
                     73:         case SDLK_EXCLAIM: code = 0x09; break;     /* on azerty? */
                     74:         case SDLK_QUOTEDBL: code = 0x04; break;    /* on azerty? */
                     75:         case SDLK_HASH: code = 0x29; break;
                     76:         case SDLK_DOLLAR: code = 0x1b; break;      /* on azerty */
                     77:         case SDLK_AMPERSAND: code = 0x02; break;   /* on azerty? */
                     78:         case SDLK_QUOTE: code = 0x28; break;
                     79:         case SDLK_LEFTPAREN: code = 0x63; break;
                     80:         case SDLK_RIGHTPAREN: code = 0x64; break;
                     81:         case SDLK_ASTERISK: code = 0x66; break;
                     82:         case SDLK_PLUS: code = 0x1B; break;
                     83:         case SDLK_COMMA: code = 0x33; break;
                     84:         case SDLK_MINUS: code = 0x35; break;
                     85:         case SDLK_PERIOD: code = 0x34; break;
                     86:         case SDLK_SLASH: code = 0x35; break;
                     87:         case SDLK_0: code = 0x0B; break;
                     88:         case SDLK_1: code = 0x02; break;
                     89:         case SDLK_2: code = 0x03; break;
                     90:         case SDLK_3: code = 0x04; break;
                     91:         case SDLK_4: code = 0x05; break;
                     92:         case SDLK_5: code = 0x06; break;
                     93:         case SDLK_6: code = 0x07; break;
                     94:         case SDLK_7: code = 0x08; break;
                     95:         case SDLK_8: code = 0x09; break;
                     96:         case SDLK_9: code = 0x0A; break;
                     97:         case SDLK_COLON: code = 0x34; break;
                     98:         case SDLK_SEMICOLON: code = 0x27; break;
                     99:         case SDLK_LESS: code = 0x60; break;
                    100:         case SDLK_EQUALS: code = 0x0D; break;
1.1.1.18  root      101:         case SDLK_GREATER : code = 0x34; break;
                    102:         case SDLK_QUESTION: code = 0x35; break;
                    103:         case SDLK_AT: code = 0x28; break;
1.1.1.17  root      104:         case SDLK_LEFTBRACKET: code = 0x63; break;
                    105:         case SDLK_BACKSLASH: code = 0x2B; break;     /* Might be 0x60 for UK keyboards */
                    106:         case SDLK_RIGHTBRACKET: code = 0x64; break;
                    107:         case SDLK_CARET: code = 0x2B; break;
1.1.1.18  root      108:         case SDLK_UNDERSCORE: code = 0x0C; break;
1.1.1.17  root      109:         case SDLK_BACKQUOTE: code = 0x52; break;
                    110:         case SDLK_a: code = 0x1E; break;
                    111:         case SDLK_b: code = 0x30; break;
                    112:         case SDLK_c: code = 0x2E; break;
                    113:         case SDLK_d: code = 0x20; break;
                    114:         case SDLK_e: code = 0x12; break;
                    115:         case SDLK_f: code = 0x21; break;
                    116:         case SDLK_g: code = 0x22; break;
                    117:         case SDLK_h: code = 0x23; break;
                    118:         case SDLK_i: code = 0x17; break;
                    119:         case SDLK_j: code = 0x24; break;
                    120:         case SDLK_k: code = 0x25; break;
                    121:         case SDLK_l: code = 0x26; break;
                    122:         case SDLK_m: code = 0x32; break;
                    123:         case SDLK_n: code = 0x31; break;
                    124:         case SDLK_o: code = 0x18; break;
                    125:         case SDLK_p: code = 0x19; break;
                    126:         case SDLK_q: code = 0x10; break;
                    127:         case SDLK_r: code = 0x13; break;
                    128:         case SDLK_s: code = 0x1F; break;
                    129:         case SDLK_t: code = 0x14; break;
                    130:         case SDLK_u: code = 0x16; break;
                    131:         case SDLK_v: code = 0x2F; break;
                    132:         case SDLK_w: code = 0x11; break;
                    133:         case SDLK_x: code = 0x2D; break;
                    134:         case SDLK_y: code = 0x15; break;
                    135:         case SDLK_z: code = 0x2C; break;
                    136:         case SDLK_DELETE: code = 0x53; break;
                    137:         /* End of ASCII mapped keysyms */
                    138: #if WITH_SDL2
1.1.1.19! root      139:         case 180: code = 0x0D; break;
1.1.1.17  root      140:         case 223: code = 0x0C; break;
                    141:         case 228: code = 0x28; break;
                    142:         case 246: code = 0x27; break;
                    143:         case 252: code = 0x1A; break;
1.1.1.19! root      144: #else /* !WITH_SDL2 */
1.1.1.17  root      145:         case SDLK_WORLD_0: code = 0x0d; break;
                    146:         case SDLK_WORLD_1: code = 0x0c; break;
                    147:         case SDLK_WORLD_2: code = 0x1a; break;
                    148:         case SDLK_WORLD_3: code = 0x28; break;
                    149:         case SDLK_WORLD_4: code = 0x27; break;
                    150:         case SDLK_WORLD_20: code = 0x0D; break;
                    151:         case SDLK_WORLD_63: code = 0x0C; break;
                    152:         case SDLK_WORLD_68: code = 0x28; break;
                    153:         case SDLK_WORLD_86: code = 0x27; break;
                    154:         case SDLK_WORLD_92: code = 0x1A; break;
1.1.1.19! root      155: #endif /* !WITH_SDL2 */
1.1.1.17  root      156:         /* Numeric keypad: */
                    157:         case SDLK_KP0: code = 0x70; break;
                    158:         case SDLK_KP1: code = 0x6D; break;
                    159:         case SDLK_KP2: code = 0x6E; break;
                    160:         case SDLK_KP3: code = 0x6F; break;
                    161:         case SDLK_KP4: code = 0x6A; break;
                    162:         case SDLK_KP5: code = 0x6B; break;
                    163:         case SDLK_KP6: code = 0x6C; break;
                    164:         case SDLK_KP7: code = 0x67; break;
                    165:         case SDLK_KP8: code = 0x68; break;
                    166:         case SDLK_KP9: code = 0x69; break;
                    167:         case SDLK_KP_PERIOD: code = 0x71; break;
                    168:         case SDLK_KP_DIVIDE: code = 0x65; break;
                    169:         case SDLK_KP_MULTIPLY: code = 0x66; break;
                    170:         case SDLK_KP_MINUS: code = 0x4A; break;
                    171:         case SDLK_KP_PLUS: code = 0x4E; break;
                    172:         case SDLK_KP_ENTER: code = 0x72; break;
                    173:         case SDLK_KP_EQUALS: code = 0x61; break;
                    174:         /* Arrows + Home/End pad */
                    175:         case SDLK_UP: code = 0x48; break;
                    176:         case SDLK_DOWN: code = 0x50; break;
                    177:         case SDLK_RIGHT: code = 0x4D; break;
                    178:         case SDLK_LEFT: code = 0x4B; break;
                    179:         case SDLK_INSERT: code = 0x52; break;
                    180:         case SDLK_HOME: code = 0x47; break;
                    181:         case SDLK_END: code = 0x61; break;
                    182:         case SDLK_PAGEUP: code = 0x63; break;
                    183:         case SDLK_PAGEDOWN: code = 0x64; break;
                    184:         /* Function keys */
                    185:         case SDLK_F1: code = 0x3B; break;
                    186:         case SDLK_F2: code = 0x3C; break;
                    187:         case SDLK_F3: code = 0x3D; break;
                    188:         case SDLK_F4: code = 0x3E; break;
                    189:         case SDLK_F5: code = 0x3F; break;
                    190:         case SDLK_F6: code = 0x40; break;
                    191:         case SDLK_F7: code = 0x41; break;
                    192:         case SDLK_F8: code = 0x42; break;
                    193:         case SDLK_F9: code = 0x43; break;
                    194:         case SDLK_F10: code = 0x44; break;
1.1.1.19! root      195:         case SDLK_F11: code = 0x62; break;
        !           196:         case SDLK_F12: code = 0x61; break;
1.1.1.17  root      197:         case SDLK_F13: code = 0x62; break;
                    198:         /* Key state modifier keys */
                    199:         case SDLK_CAPSLOCK: code = 0x3A; break;
                    200:         case SDLK_SCROLLOCK: code = 0x61; break;
                    201:         case SDLK_RSHIFT: code = 0x36; break;
                    202:         case SDLK_LSHIFT: code = 0x2A; break;
                    203:         case SDLK_RCTRL: code = 0x1D; break;
                    204:         case SDLK_LCTRL: code = 0x1D; break;
                    205:         case SDLK_RALT: code = 0x38; break;
                    206:         case SDLK_LALT: code = 0x38; break;
                    207:         /* Miscellaneous function keys */
                    208:         case SDLK_HELP: code = 0x62; break;
                    209:         case SDLK_PRINT: code = 0x62; break;
                    210:         case SDLK_UNDO: code = 0x61; break;
                    211:         default: code = -1;
                    212:        }
                    213: 
                    214:        return code;
                    215: }
                    216: 
                    217: 
                    218: #if WITH_SDL2
                    219: 
                    220: /**
                    221:  * Remap SDL scancode key to ST Scan code - this is the version for SDL2
                    222:  */
                    223: static char Keymap_PcToStScanCode(SDL_keysym* pKeySym)
                    224: {
                    225:        switch (pKeySym->scancode)
                    226:        {
                    227:         case SDL_SCANCODE_A: return 0x1e;
                    228:         case SDL_SCANCODE_B: return 0x30;
                    229:         case SDL_SCANCODE_C: return 0x2e;
                    230:         case SDL_SCANCODE_D: return 0x20;
                    231:         case SDL_SCANCODE_E: return 0x12;
                    232:         case SDL_SCANCODE_F: return 0x21;
                    233:         case SDL_SCANCODE_G: return 0x22;
                    234:         case SDL_SCANCODE_H: return 0x23;
                    235:         case SDL_SCANCODE_I: return 0x17;
                    236:         case SDL_SCANCODE_J: return 0x24;
                    237:         case SDL_SCANCODE_K: return 0x25;
                    238:         case SDL_SCANCODE_L: return 0x26;
                    239:         case SDL_SCANCODE_M: return 0x32;
                    240:         case SDL_SCANCODE_N: return 0x31;
                    241:         case SDL_SCANCODE_O: return 0x18;
                    242:         case SDL_SCANCODE_P: return 0x19;
                    243:         case SDL_SCANCODE_Q: return 0x10;
                    244:         case SDL_SCANCODE_R: return 0x13;
                    245:         case SDL_SCANCODE_S: return 0x1f;
                    246:         case SDL_SCANCODE_T: return 0x14;
                    247:         case SDL_SCANCODE_U: return 0x16;
                    248:         case SDL_SCANCODE_V: return 0x2f;
                    249:         case SDL_SCANCODE_W: return 0x11;
                    250:         case SDL_SCANCODE_X: return 0x2d;
                    251:         case SDL_SCANCODE_Y: return 0x15;
                    252:         case SDL_SCANCODE_Z: return 0x2c;
                    253:         case SDL_SCANCODE_1: return 0x02;
                    254:         case SDL_SCANCODE_2: return 0x03;
                    255:         case SDL_SCANCODE_3: return 0x04;
                    256:         case SDL_SCANCODE_4: return 0x05;
                    257:         case SDL_SCANCODE_5: return 0x06;
                    258:         case SDL_SCANCODE_6: return 0x07;
                    259:         case SDL_SCANCODE_7: return 0x08;
                    260:         case SDL_SCANCODE_8: return 0x09;
                    261:         case SDL_SCANCODE_9: return 0x0a;
                    262:         case SDL_SCANCODE_0: return 0x0b;
                    263:         case SDL_SCANCODE_RETURN: return 0x1c;
                    264:         case SDL_SCANCODE_ESCAPE: return 0x01;
                    265:         case SDL_SCANCODE_BACKSPACE: return 0x0e;
                    266:         case SDL_SCANCODE_TAB: return 0x0f;
                    267:         case SDL_SCANCODE_SPACE: return 0x39;
                    268:         case SDL_SCANCODE_MINUS: return 0x0c;
                    269:         case SDL_SCANCODE_EQUALS: return 0x0d;
                    270:         case SDL_SCANCODE_LEFTBRACKET: return 0x1a;
                    271:         case SDL_SCANCODE_RIGHTBRACKET: return 0x1b;
1.1.1.19! root      272:         case SDL_SCANCODE_BACKSLASH: return 0x29;  /* for 0x60 see NONUSBACKSLASH */
1.1.1.17  root      273:         case SDL_SCANCODE_NONUSHASH: return 0x2b;
                    274:         case SDL_SCANCODE_SEMICOLON: return 0x27;
                    275:         case SDL_SCANCODE_APOSTROPHE: return 0x28;
                    276:         case SDL_SCANCODE_GRAVE: return 0x2b;      /* ok? */
                    277:         case SDL_SCANCODE_COMMA: return 0x33;
                    278:         case SDL_SCANCODE_PERIOD: return 0x34;
                    279:         case SDL_SCANCODE_SLASH: return 0x35;
                    280:         case SDL_SCANCODE_CAPSLOCK: return 0x3a;
                    281:         case SDL_SCANCODE_F1: return 0x3b;
                    282:         case SDL_SCANCODE_F2: return 0x3c;
                    283:         case SDL_SCANCODE_F3: return 0x3d;
                    284:         case SDL_SCANCODE_F4: return 0x3e;
                    285:         case SDL_SCANCODE_F5: return 0x3f;
                    286:         case SDL_SCANCODE_F6: return 0x40;
                    287:         case SDL_SCANCODE_F7: return 0x41;
                    288:         case SDL_SCANCODE_F8: return 0x42;
                    289:         case SDL_SCANCODE_F9: return 0x43;
                    290:         case SDL_SCANCODE_F10: return 0x44;
1.1.1.19! root      291:         case SDL_SCANCODE_F11: return 0x62;
        !           292:         case SDL_SCANCODE_F12: return 0x61;
1.1.1.17  root      293:         case SDL_SCANCODE_PRINTSCREEN: return 0x62;
                    294:         case SDL_SCANCODE_SCROLLLOCK: return 0x61;
                    295:         case SDL_SCANCODE_PAUSE: return 0x61;
                    296:         case SDL_SCANCODE_INSERT: return 0x52;
                    297:         case SDL_SCANCODE_HOME: return 0x47;
1.1.1.18  root      298:         case SDL_SCANCODE_PAGEUP: return 0x63;
1.1.1.17  root      299:         case SDL_SCANCODE_DELETE: return 0x53;
                    300:         case SDL_SCANCODE_END: return 0x2b;
1.1.1.18  root      301:         case SDL_SCANCODE_PAGEDOWN: return 0x64;
1.1.1.17  root      302:         case SDL_SCANCODE_RIGHT: return 0x4d;
                    303:         case SDL_SCANCODE_LEFT: return 0x4b;
                    304:         case SDL_SCANCODE_DOWN: return 0x50;
                    305:         case SDL_SCANCODE_UP: return 0x48;
                    306:         case SDL_SCANCODE_NUMLOCKCLEAR: return 0x64;
                    307:         case SDL_SCANCODE_KP_DIVIDE: return 0x65;
                    308:         case SDL_SCANCODE_KP_MULTIPLY: return 0x66;
                    309:         case SDL_SCANCODE_KP_MINUS: return 0x4a;
                    310:         case SDL_SCANCODE_KP_PLUS: return 0x4e;
                    311:         case SDL_SCANCODE_KP_ENTER: return 0x72;
                    312:         case SDL_SCANCODE_KP_1: return 0x6d;
                    313:         case SDL_SCANCODE_KP_2: return 0x6e;
                    314:         case SDL_SCANCODE_KP_3: return 0x6f;
                    315:         case SDL_SCANCODE_KP_4: return 0x6a;
                    316:         case SDL_SCANCODE_KP_5: return 0x6b;
                    317:         case SDL_SCANCODE_KP_6: return 0x6c;
                    318:         case SDL_SCANCODE_KP_7: return 0x67;
                    319:         case SDL_SCANCODE_KP_8: return 0x68;
                    320:         case SDL_SCANCODE_KP_9: return 0x69;
                    321:         case SDL_SCANCODE_KP_0: return 0x70;
                    322:         case SDL_SCANCODE_KP_PERIOD: return 0x71;
                    323:         case SDL_SCANCODE_NONUSBACKSLASH: return 0x60;
                    324:         //case SDL_SCANCODE_APPLICATION: return ;
                    325:         case SDL_SCANCODE_KP_EQUALS: return 0x63;
                    326:         case SDL_SCANCODE_F13: return 0x63;
                    327:         case SDL_SCANCODE_F14: return 0x64;
                    328:         case SDL_SCANCODE_HELP: return 0x62;
                    329:         case SDL_SCANCODE_UNDO: return 0x61;
                    330:         case SDL_SCANCODE_KP_COMMA: return 0x71;
                    331:         case SDL_SCANCODE_CLEAR: return 0x47;
                    332:         case SDL_SCANCODE_RETURN2: return 0x1c;
                    333:         case SDL_SCANCODE_KP_LEFTPAREN: return 0x63;
                    334:         case SDL_SCANCODE_KP_RIGHTPAREN: return 0x64;
                    335:         case SDL_SCANCODE_KP_LEFTBRACE: return 0x63;
                    336:         case SDL_SCANCODE_KP_RIGHTBRACE: return 0x64;
                    337:         case SDL_SCANCODE_KP_TAB: return 0x0f;
                    338:         case SDL_SCANCODE_KP_BACKSPACE: return 0x0e;
                    339:         case SDL_SCANCODE_KP_COLON: return 0x33;
                    340:         case SDL_SCANCODE_KP_HASH: return 0x0c;
                    341:         case SDL_SCANCODE_KP_SPACE: return 0x39;
                    342:         case SDL_SCANCODE_KP_CLEAR: return 0x47;
                    343:         case SDL_SCANCODE_LCTRL: return 0x1d;
                    344:         case SDL_SCANCODE_LSHIFT: return 0x2a;
                    345:         case SDL_SCANCODE_LALT: return 0x38;
                    346:         case SDL_SCANCODE_RCTRL: return 0x1d;
                    347:         case SDL_SCANCODE_RSHIFT: return 0x36;
                    348:         default:
1.1.1.19! root      349:                Log_Printf(LOG_WARN, "Unhandled scancode 0x%x!\n", pKeySym->scancode);
1.1.1.17  root      350:                return -1;
                    351:        }
                    352: }
                    353: 
1.1.1.19! root      354: #else /* !WITH_SDL2 */
1.1.1.5   root      355: 
1.1.1.10  root      356: /**
                    357:  * Heuristic analysis to find out the obscure scancode offset.
                    358:  * Some keys like 'z' can't be used for detection since they are on different
                    359:  * locations on "qwertz" and "azerty" keyboards.
                    360:  * This clever code has originally been taken from the emulator Aranym. (cheers!)
                    361:  */
1.1.1.5   root      362: static int Keymap_FindScanCodeOffset(SDL_keysym* keysym)
                    363: {
1.1.1.10  root      364:        int offset = -1;    /* uninitialized scancode offset */
                    365:        int scanPC = keysym->scancode;
1.1.1.5   root      366: 
1.1.1.10  root      367:        if (scanPC == 0)  return -1; /* Ignore illegal scancode */
1.1.1.5   root      368: 
1.1.1.10  root      369:        switch (keysym->sym)
                    370:        {
                    371:         case SDLK_ESCAPE: offset = scanPC - 0x01; break;
                    372:         case SDLK_1:  offset = scanPC - 0x02; break;
                    373:         case SDLK_2:  offset = scanPC - 0x03; break;
                    374:         case SDLK_3:  offset = scanPC - 0x04; break;
                    375:         case SDLK_4:  offset = scanPC - 0x05; break;
                    376:         case SDLK_5:  offset = scanPC - 0x06; break;
                    377:         case SDLK_6:  offset = scanPC - 0x07; break;
                    378:         case SDLK_7:  offset = scanPC - 0x08; break;
                    379:         case SDLK_8:  offset = scanPC - 0x09; break;
                    380:         case SDLK_9:  offset = scanPC - 0x0a; break;
                    381:         case SDLK_0:  offset = scanPC - 0x0b; break;
                    382:         case SDLK_BACKSPACE: offset = scanPC - 0x0e; break;
                    383:         case SDLK_TAB:    offset = scanPC - 0x0f; break;
                    384:         case SDLK_RETURN: offset = scanPC - 0x1c; break;
                    385:         case SDLK_SPACE:  offset = scanPC - 0x39; break;
                    386:         /*case SDLK_q:  offset = scanPC - 0x10; break;*/  /* different on azerty */
                    387:         /*case SDLK_w:  offset = scanPC - 0x11; break;*/  /* different on azerty */
                    388:         case SDLK_e:  offset = scanPC - 0x12; break;
                    389:         case SDLK_r:  offset = scanPC - 0x13; break;
                    390:         case SDLK_t:  offset = scanPC - 0x14; break;
                    391:         /*case SDLK_y:  offset = scanPC - 0x15; break;*/  /* different on qwertz */
                    392:         case SDLK_u:  offset = scanPC - 0x16; break;
                    393:         case SDLK_i:  offset = scanPC - 0x17; break;
                    394:         case SDLK_o:  offset = scanPC - 0x18; break;
                    395:         case SDLK_p:  offset = scanPC - 0x19; break;
                    396:         /*case SDLK_a:  offset = scanPC - 0x1e; break;*/  /* different on azerty */
                    397:         case SDLK_s:  offset = scanPC - 0x1f; break;
                    398:         case SDLK_d:  offset = scanPC - 0x20; break;
                    399:         case SDLK_f:  offset = scanPC - 0x21; break;
                    400:         case SDLK_g:  offset = scanPC - 0x22; break;
                    401:         case SDLK_h:  offset = scanPC - 0x23; break;
                    402:         case SDLK_j:  offset = scanPC - 0x24; break;
                    403:         case SDLK_k:  offset = scanPC - 0x25; break;
                    404:         case SDLK_l:  offset = scanPC - 0x26; break;
                    405:         /*case SDLK_z:  offset = scanPC - 0x2c; break;*/  /* different on qwertz and azerty */
                    406:         case SDLK_x:  offset = scanPC - 0x2d; break;
                    407:         case SDLK_c:  offset = scanPC - 0x2e; break;
                    408:         case SDLK_v:  offset = scanPC - 0x2f; break;
                    409:         case SDLK_b:  offset = scanPC - 0x30; break;
                    410:         case SDLK_n:  offset = scanPC - 0x31; break;
                    411:         /*case SDLK_m:  offset = scanPC - 0x32; break;*/  /* different on azerty */
                    412:         case SDLK_CAPSLOCK:  offset = scanPC - 0x3a; break;
                    413:         case SDLK_LSHIFT: offset = scanPC - 0x2a; break;
                    414:         case SDLK_LCTRL: offset = scanPC - 0x1d; break;
                    415:         case SDLK_LALT: offset = scanPC - 0x38; break;
                    416:         case SDLK_F1:  offset = scanPC - 0x3b; break;
                    417:         case SDLK_F2:  offset = scanPC - 0x3c; break;
                    418:         case SDLK_F3:  offset = scanPC - 0x3d; break;
                    419:         case SDLK_F4:  offset = scanPC - 0x3e; break;
                    420:         case SDLK_F5:  offset = scanPC - 0x3f; break;
                    421:         case SDLK_F6:  offset = scanPC - 0x40; break;
                    422:         case SDLK_F7:  offset = scanPC - 0x41; break;
                    423:         case SDLK_F8:  offset = scanPC - 0x42; break;
                    424:         case SDLK_F9:  offset = scanPC - 0x43; break;
                    425:         case SDLK_F10: offset = scanPC - 0x44; break;
                    426:         default:  break;
                    427:        }
                    428: 
                    429:        if (offset != -1)
                    430:        {
1.1.1.19! root      431:                Log_Printf(LOG_WARN, "Detected scancode offset = %d (key: '%s' with scancode $%02x)\n",
1.1.1.10  root      432:                        offset, SDL_GetKeyName(keysym->sym), scanPC);
                    433:        }
1.1.1.5   root      434: 
1.1.1.10  root      435:        return offset;
1.1.1.5   root      436: }
                    437: 
                    438: 
1.1.1.10  root      439: /**
                    440:  * Map PC scancode to ST scancode.
                    441:  * This code was heavily inspired by the emulator Aranym. (cheers!)
                    442:  */
1.1.1.5   root      443: static char Keymap_PcToStScanCode(SDL_keysym* keysym)
                    444: {
1.1.1.10  root      445:        static int offset = -1;    /* uninitialized scancode offset */
1.1.1.5   root      446: 
1.1.1.17  root      447:        /* We sometimes enter here with an illegal (=0) scancode, so we keep
                    448:         * track of the right scancodes in a table and then use a value from there.
                    449:         */
                    450:        if (keysym->scancode != 0)
                    451:        {
                    452:                SdlSymToSdlScan[keysym->sym] = keysym->scancode;
                    453:        }
                    454:        else
                    455:        {
                    456:                keysym->scancode = SdlSymToSdlScan[keysym->sym];
                    457:                if (keysym->scancode == 0)
1.1.1.19! root      458:                        Log_Printf(LOG_WARN, "Key scancode is 0!\n");
1.1.1.17  root      459:        }
                    460: 
1.1.1.10  root      461:        switch (keysym->sym)
                    462:        {
                    463:         /* Numeric Pad */
                    464:         /* note that the numbers are handled in Keymap_GetKeyPadScanCode()! */
                    465:         case SDLK_KP_DIVIDE:   return 0x65;  /* Numpad / */
                    466:         case SDLK_KP_MULTIPLY: return 0x66;  /* NumPad * */
                    467:         case SDLK_KP_MINUS:    return 0x4a;  /* NumPad - */
                    468:         case SDLK_KP_PLUS:     return 0x4e;  /* NumPad + */
                    469:         case SDLK_KP_PERIOD:   return 0x71;  /* NumPad . */
                    470:         case SDLK_KP_ENTER:    return 0x72;  /* NumPad Enter */
                    471: 
                    472:         /* Special Keys */
1.1.1.18  root      473:         case SDLK_PRINT:    return 0x62;  /* Help */
                    474:         case SDLK_SCROLLOCK: return 0x61; /* Undo */
                    475:         case SDLK_PAGEUP:   return 0x63;  /* Keypad ( */
                    476:         case SDLK_PAGEDOWN: return 0x64;  /* Keypad ) */
1.1.1.10  root      477:         case SDLK_HOME:     return 0x47;  /* Home */
                    478:         case SDLK_END:      return 0x60;  /* End => "<>" on German Atari kbd */
                    479:         case SDLK_UP:       return 0x48;  /* Arrow Up */
                    480:         case SDLK_LEFT:     return 0x4b;  /* Arrow Left */
                    481:         case SDLK_RIGHT:    return 0x4d;  /* Arrow Right */
                    482:         case SDLK_DOWN:     return 0x50;  /* Arrow Down */
                    483:         case SDLK_INSERT:   return 0x52;  /* Insert */
                    484:         case SDLK_DELETE:   return 0x53;  /* Delete */
                    485:         case SDLK_LESS:     return 0x60;  /* "<" */
                    486: 
                    487:         /* Map Right Alt/Alt Gr/Control to the Atari keys */
                    488:         case SDLK_RCTRL:  return 0x1d;  /* Control */
                    489:         case SDLK_RALT:   return 0x38;  /* Alternate */
                    490: 
                    491:         default:
                    492:                /* Process remaining keys: assume that it's PC101 keyboard
                    493:                 * and that it is compatible with Atari ST keyboard (basically
                    494:                 * same scancodes but on different platforms with different
                    495:                 * base offset (framebuffer = 0, X11 = 8).
                    496:                 * Try to detect the offset using a little bit of black magic.
                    497:                 * If offset is known then simply pass the scancode. */
                    498:                if (offset == -1)
                    499:                {
                    500:                        offset = Keymap_FindScanCodeOffset(keysym);
                    501:                }
                    502: 
                    503:                if (offset >= 0)
                    504:                {
                    505:                        /* offset is defined so pass the scancode directly */
                    506:                        return (keysym->scancode - offset);
                    507:                }
                    508:                else
                    509:                {
                    510:                        /* Failed to detect offset, so use default value 8 */
1.1.1.19! root      511:                        Log_Printf(LOG_WARN, "Offset detection failed with "
1.1.1.10  root      512:                                "key '%s', scancode = 0x%02x, symcode =  0x%02x\n",
                    513:                                SDL_GetKeyName(keysym->sym), keysym->scancode, keysym->sym);
                    514:                        return (keysym->scancode - 8);
                    515:                }
                    516:                break;
                    517:        }
1.1.1.5   root      518: }
                    519: 
1.1.1.19! root      520: #endif /* !WITH_SDL2 */
1.1.1.17  root      521: 
1.1.1.5   root      522: 
1.1.1.10  root      523: /**
                    524:  * Remap a keypad key to ST scan code. We use a separate function for this
                    525:  * so that we can easily toggle between number and cursor mode with the
                    526:  * numlock key.
                    527:  */
1.1.1.5   root      528: static char Keymap_GetKeyPadScanCode(SDL_keysym* pKeySym)
                    529: {
1.1.1.10  root      530:        if (SDL_GetModState() & KMOD_NUM)
                    531:        {
                    532:                switch (pKeySym->sym)
                    533:                {
                    534:                 case SDLK_KP0:  return 0x70;  /* NumPad 0 */
                    535:                 case SDLK_KP1:  return 0x6d;  /* NumPad 1 */
                    536:                 case SDLK_KP2:  return 0x6e;  /* NumPad 2 */
                    537:                 case SDLK_KP3:  return 0x6f;  /* NumPad 3 */
                    538:                 case SDLK_KP4:  return 0x6a;  /* NumPad 4 */
                    539:                 case SDLK_KP5:  return 0x6b;  /* NumPad 5 */
                    540:                 case SDLK_KP6:  return 0x6c;  /* NumPad 6 */
                    541:                 case SDLK_KP7:  return 0x67;  /* NumPad 7 */
                    542:                 case SDLK_KP8:  return 0x68;  /* NumPad 8 */
                    543:                 case SDLK_KP9:  return 0x69;  /* NumPad 9 */
                    544:                 default:  break;
                    545:                }
                    546:        }
                    547:        else
                    548:        {
                    549:                switch (pKeySym->sym)
                    550:                {
                    551:                 case SDLK_KP0:  return 0x70;  /* NumPad 0 */
                    552:                 case SDLK_KP1:  return 0x6d;  /* NumPad 1 */
                    553:                 case SDLK_KP2:  return 0x50;  /* Cursor down */
                    554:                 case SDLK_KP3:  return 0x6f;  /* NumPad 3 */
                    555:                 case SDLK_KP4:  return 0x4b;  /* Cursor left */
                    556:                 case SDLK_KP5:  return 0x50;  /* Cursor down (again?) */
                    557:                 case SDLK_KP6:  return 0x4d;  /* Cursor right */
                    558:                 case SDLK_KP7:  return 0x52;  /* Insert - good for Dungeon Master */
                    559:                 case SDLK_KP8:  return 0x48;  /* Cursor up */
                    560:                 case SDLK_KP9:  return 0x47;  /* Home - again for Dungeon Master */
                    561:                 default:  break;
                    562:                }
                    563:        }
1.1.1.5   root      564: 
1.1.1.10  root      565:        return -1;
1.1.1.5   root      566: }
1.1       root      567: 
                    568: 
1.1.1.10  root      569: /**
                    570:  * Remap SDL Key to ST Scan code
                    571:  */
1.1.1.16  root      572: static char Keymap_RemapKeyToSTScanCode(SDL_keysym* pKeySym)
1.1       root      573: {
1.1.1.10  root      574:        /* Check for keypad first so we can handle numlock */
                    575:        if (ConfigureParams.Keyboard.nKeymapType != KEYMAP_LOADED)
                    576:        {
                    577:                if (pKeySym->sym >= SDLK_KP0 && pKeySym->sym <= SDLK_KP9)
                    578:                {
                    579:                        return Keymap_GetKeyPadScanCode(pKeySym);
                    580:                }
                    581:        }
                    582: 
                    583:        /* Remap from PC scancodes? */
                    584:        if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_SCANCODE)
                    585:        {
                    586:                return Keymap_PcToStScanCode(pKeySym);
                    587:        }
                    588: 
1.1.1.17  root      589:        /* Use loaded keymap? */
1.1.1.10  root      590:        if (ConfigureParams.Keyboard.nKeymapType == KEYMAP_LOADED)
1.1.1.17  root      591:        {
                    592:                int i;
                    593:                for (i = 0; i < KBD_MAX_SCANCODE && LoadedKeymap[i][1] != 0; i++)
                    594:                {
                    595:                        if (pKeySym->sym == (SDLKey)LoadedKeymap[i][0])
                    596:                                return LoadedKeymap[i][1];
                    597:                }
                    598:        }
                    599: 
                    600:        /* Use symbolic mapping */
                    601:        return Keymap_SymbolicToStScanCode(pKeySym);
1.1       root      602: }
                    603: 
1.1.1.2   root      604: 
                    605: /*-----------------------------------------------------------------------*/
1.1.1.10  root      606: /**
                    607:  * Load keyboard remap file
                    608:  */
1.1       root      609: void Keymap_LoadRemapFile(char *pszFileName)
                    610: {
1.1.1.10  root      611:        char szString[1024];
                    612:        int STScanCode, PCKeyCode;
                    613:        FILE *in;
1.1.1.17  root      614:        int idx = 0;
1.1.1.10  root      615: 
                    616:        /* Initialize table with default values */
1.1.1.17  root      617:        memset(LoadedKeymap, 0, sizeof(LoadedKeymap));
1.1.1.10  root      618: 
1.1.1.11  root      619:        if (!*pszFileName)
                    620:                return;
                    621:        
1.1.1.10  root      622:        /* Attempt to load file */
1.1.1.11  root      623:        if (!File_Exists(pszFileName))
1.1.1.10  root      624:        {
1.1.1.11  root      625:                Log_Printf(LOG_DEBUG, "Keymap_LoadRemapFile: '%s' not a file\n", pszFileName);
                    626:                return;
                    627:        }
                    628:        in = fopen(pszFileName, "r");
                    629:        if (!in)
                    630:        {
1.1.1.18  root      631:                Log_Printf(LOG_ERROR, "Keymap_LoadRemapFile: failed to "
1.1.1.11  root      632:                           " open keymap file '%s'\n", pszFileName);
                    633:                return;
                    634:        }
                    635:        
1.1.1.17  root      636:        while (!feof(in) && idx < KBD_MAX_SCANCODE)
1.1.1.11  root      637:        {
                    638:                /* Read line from file */
                    639:                if (fgets(szString, sizeof(szString), in) == NULL)
                    640:                        break;
                    641:                /* Remove white-space from start of line */
                    642:                Str_Trim(szString);
                    643:                if (strlen(szString)>0)
                    644:                {
1.1.1.18  root      645:                        char *p;
1.1.1.11  root      646:                        /* Is a comment? */
1.1.1.18  root      647:                        if (szString[0] == ';' || szString[0] == '#')
1.1.1.11  root      648:                                continue;
1.1.1.18  root      649:                        /* Cut out the values */
                    650:                        p = strtok(szString, ",");
                    651:                        if (!p)
                    652:                                continue;
                    653:                        Str_Trim(szString);
                    654:                        PCKeyCode = atoi(szString);    /* Direct key code? */
                    655:                        if (PCKeyCode < 10)
                    656:                        {
                    657:                                /* If it's not a valid number >= 10, then
                    658:                                 * assume we've got a symbolic key name
                    659:                                 */
                    660:                                int offset = 0;
                    661:                                /* quoted character (e.g. comment line char)? */
                    662:                                if (*szString == '\\' && strlen(szString) == 2)
                    663:                                        offset = 1;
                    664:                                PCKeyCode = Keymap_GetKeyFromName(szString+offset);
                    665:                        }
                    666:                        p = strtok(NULL, "\n");
                    667:                        if (!p)
                    668:                                continue;
                    669:                        STScanCode = atoi(p);
1.1.1.11  root      670:                        /* Store into remap table, check both value within range */
1.1.1.18  root      671:                        if (STScanCode > 0 && STScanCode <= KBD_MAX_SCANCODE
1.1.1.17  root      672:                            && PCKeyCode >= 8)
                    673:                        {
1.1.1.18  root      674:                                LOG_TRACE(TRACE_KEYMAP,
                    675:                                          "keymap from file: sym=%i --> scan=%i\n",
                    676:                                          PCKeyCode, STScanCode);
1.1.1.17  root      677:                                LoadedKeymap[idx][0] = PCKeyCode;
                    678:                                LoadedKeymap[idx][1] = STScanCode;
                    679:                                idx += 1;
                    680:                        }
1.1.1.18  root      681:                        else
                    682:                        {
                    683:                                Log_Printf(LOG_WARN, "Could not parse keymap file:"
                    684:                                           " '%s' (%d >= 8), '%s' (0 > %d <= %d)\n",
                    685:                                           szString, PCKeyCode, p, STScanCode, KBD_MAX_SCANCODE);
                    686:                        }
1.1.1.10  root      687:                }
                    688:        }
1.1.1.17  root      689: 
1.1.1.11  root      690:        fclose(in);
1.1       root      691: }
1.1.1.3   root      692: 
                    693: 
                    694: /*-----------------------------------------------------------------------*/
1.1.1.10  root      695: /**
                    696:  * Scan list of keys to NOT de-bounce when running in maximum speed, eg ALT,SHIFT,CTRL etc...
1.1.1.13  root      697:  * @return true if key requires de-bouncing
1.1.1.10  root      698:  */
1.1.1.11  root      699: static bool Keymap_DebounceSTKey(char STScanCode)
1.1.1.3   root      700: {
1.1.1.10  root      701:        int i=0;
1.1.1.3   root      702: 
1.1.1.11  root      703:        /* Are we in fast forward, and have disabled key repeat? */
1.1.1.13  root      704:        if ((ConfigureParams.System.bFastForward == true)
1.1.1.10  root      705:            && (ConfigureParams.Keyboard.bDisableKeyRepeat))
                    706:        {
                    707:                /* We should de-bounce all non extended keys,
                    708:                 * e.g. leave ALT, SHIFT, CTRL etc... held */
                    709:                while (DebounceExtendedKeys[i])
                    710:                {
                    711:                        if (STScanCode == DebounceExtendedKeys[i])
1.1.1.13  root      712:                                return false;
1.1.1.10  root      713:                        i++;
                    714:                }
                    715: 
                    716:                /* De-bounce key */
1.1.1.13  root      717:                return true;
1.1.1.10  root      718:        }
1.1.1.3   root      719: 
1.1.1.10  root      720:        /* Do not de-bounce key */
1.1.1.13  root      721:        return false;
1.1.1.3   root      722: }
                    723: 
                    724: 
                    725: /*-----------------------------------------------------------------------*/
1.1.1.10  root      726: /**
                    727:  * Debounce any PC key held down if running with key repeat disabled.
                    728:  * This is called each ST frame, so keys get held down for one VBL which
                    729:  * is enough for 68000 code to scan.
                    730:  */
1.1.1.3   root      731: void Keymap_DebounceAllKeys(void)
                    732: {
1.1.1.16  root      733:        uint8_t nScanCode;
1.1.1.10  root      734: 
1.1.1.11  root      735:        /* Return if we aren't in fast forward or have not disabled key repeat */
1.1.1.13  root      736:        if ((ConfigureParams.System.bFastForward == false)
1.1.1.10  root      737:                || (!ConfigureParams.Keyboard.bDisableKeyRepeat))
                    738:        {
                    739:                return;
                    740:        }
                    741: 
1.1.1.16  root      742:        /* Now run through each key looking for ones held down */
                    743:        for (nScanCode = 1; nScanCode <= KBD_MAX_SCANCODE; nScanCode++)
1.1.1.10  root      744:        {
                    745:                /* Is key held? */
1.1.1.16  root      746:                if (Keyboard.KeyStates[nScanCode])
1.1.1.10  root      747:                {
1.1.1.16  root      748:                        /* Does this require de-bouncing? */
                    749:                        if (Keymap_DebounceSTKey(nScanCode))
1.1.1.10  root      750:                        {
1.1.1.16  root      751:                                IKBD_PressSTKey(nScanCode, false);
                    752:                                Keyboard.KeyStates[nScanCode] = false;
1.1.1.10  root      753:                        }
                    754:                }
                    755:        }
1.1.1.3   root      756: 
                    757: }
                    758: 
                    759: 
                    760: /*-----------------------------------------------------------------------*/
1.1.1.10  root      761: /**
                    762:  * User press key down
                    763:  */
1.1.1.5   root      764: void Keymap_KeyDown(SDL_keysym *sdlkey)
1.1.1.3   root      765: {
1.1.1.16  root      766:        uint8_t STScanCode;
1.1.1.10  root      767:        int symkey = sdlkey->sym;
                    768:        int modkey = sdlkey->mod;
                    769: 
1.1.1.18  root      770:        LOG_TRACE(TRACE_KEYMAP, "key down: sym=%i scan=%i mod=0x%x name='%s'\n",
                    771:                  symkey, sdlkey->scancode, modkey, Keymap_GetKeyName(symkey));
1.1.1.10  root      772: 
1.1.1.19! root      773:        if (ShortCut_CheckKeys(modkey, symkey, true))
1.1.1.10  root      774:                return;
                    775: 
                    776:        /* If using joystick emulation via keyboard, DON'T send keys to keyboard processor!!!
                    777:         * Some games use keyboard as pause! */
                    778:        if (Joy_KeyDown(symkey, modkey))
                    779:                return;
                    780: 
                    781:        /* Handle special keys */
                    782:        if (symkey == SDLK_RALT || symkey == SDLK_LMETA || symkey == SDLK_RMETA
                    783:                || symkey == SDLK_MODE || symkey == SDLK_NUMLOCK)
                    784:        {
                    785:                /* Ignore modifier keys that aren't passed to the ST */
                    786:                return;
                    787:        }
                    788: 
                    789:        STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
1.1.1.17  root      790:        LOG_TRACE(TRACE_KEYMAP, "key map: sym=0x%x to ST-scan=0x%02x\n", symkey, STScanCode);
1.1.1.16  root      791:        if (STScanCode != (uint8_t)-1)
1.1.1.10  root      792:        {
1.1.1.16  root      793:                if (!Keyboard.KeyStates[STScanCode])
                    794:                {
                    795:                        /* Set down */
                    796:                        Keyboard.KeyStates[STScanCode] = true;
1.1.1.13  root      797:                        IKBD_PressSTKey(STScanCode, true);
1.1.1.16  root      798:                }
1.1.1.10  root      799:        }
1.1.1.3   root      800: }
                    801: 
                    802: 
                    803: /*-----------------------------------------------------------------------*/
1.1.1.10  root      804: /**
                    805:  * User released key
                    806:  */
1.1.1.5   root      807: void Keymap_KeyUp(SDL_keysym *sdlkey)
1.1.1.3   root      808: {
1.1.1.16  root      809:        uint8_t STScanCode;
1.1.1.10  root      810:        int symkey = sdlkey->sym;
                    811:        int modkey = sdlkey->mod;
                    812: 
1.1.1.18  root      813:        LOG_TRACE(TRACE_KEYMAP, "key up: sym=%i scan=%i mod=0x%x name='%s'\n",
                    814:                  symkey, sdlkey->scancode, modkey, Keymap_GetKeyName(symkey));
1.1.1.10  root      815: 
                    816:        /* Ignore short-cut keys here */
1.1.1.19! root      817:        if (ShortCut_CheckKeys(modkey, symkey, false))
1.1.1.10  root      818:                return;
                    819: 
                    820:        /* If using keyboard emulation, DON'T send keys to keyboard processor!!!
                    821:         * Some games use keyboard as pause! */
                    822:        if (Joy_KeyUp(symkey, modkey))
                    823:                return;
                    824: 
                    825:        /* Handle special keys */
                    826:        if (symkey == SDLK_RALT || symkey == SDLK_LMETA || symkey == SDLK_RMETA
                    827:                || symkey == SDLK_MODE || symkey == SDLK_NUMLOCK)
                    828:        {
                    829:                /* Ignore modifier keys that aren't passed to the ST */
                    830:                return;
                    831:        }
                    832: 
1.1.1.16  root      833:        STScanCode = Keymap_RemapKeyToSTScanCode(sdlkey);
1.1.1.10  root      834:        /* Release key (only if was pressed) */
1.1.1.16  root      835:        if (STScanCode != (uint8_t)-1)
1.1.1.10  root      836:        {
1.1.1.16  root      837:                if (Keyboard.KeyStates[STScanCode])
1.1.1.10  root      838:                {
1.1.1.13  root      839:                        IKBD_PressSTKey(STScanCode, false);
1.1.1.16  root      840:                        Keyboard.KeyStates[STScanCode] = false;
1.1.1.10  root      841:                }
                    842:        }
1.1.1.3   root      843: }
                    844: 
1.1.1.11  root      845: /*-----------------------------------------------------------------------*/
                    846: /**
                    847:  * Simulate press or release of a key corresponding to given character
                    848:  */
                    849: void Keymap_SimulateCharacter(char asckey, bool press)
                    850: {
                    851:        SDL_keysym sdlkey;
                    852: 
1.1.1.13  root      853:        sdlkey.mod = KMOD_NONE;
1.1.1.11  root      854:        sdlkey.scancode = 0;
1.1.1.16  root      855:        if (isupper((unsigned char)asckey)) {
1.1.1.11  root      856:                if (press) {
                    857:                        sdlkey.sym = SDLK_LSHIFT;
                    858:                        Keymap_KeyDown(&sdlkey);
                    859:                }
1.1.1.16  root      860:                sdlkey.sym = tolower((unsigned char)asckey);
1.1.1.13  root      861:                sdlkey.mod = KMOD_LSHIFT;
1.1.1.11  root      862:        } else {
                    863:                sdlkey.sym = asckey;
                    864:        }
                    865:        if (press) {
                    866:                Keymap_KeyDown(&sdlkey);
                    867:        } else {
                    868:                Keymap_KeyUp(&sdlkey);
1.1.1.16  root      869:                if (isupper((unsigned char)asckey)) {
1.1.1.11  root      870:                        sdlkey.sym = SDLK_LSHIFT;
                    871:                        Keymap_KeyUp(&sdlkey);
                    872:                }
                    873:        }
                    874: }
1.1.1.18  root      875: 
                    876: 
                    877: #if WITH_SDL2
                    878: 
                    879: int Keymap_GetKeyFromName(const char *name)
                    880: {
                    881:        return SDL_GetKeyFromName(name);
                    882: }
                    883: 
                    884: const char *Keymap_GetKeyName(int keycode)
                    885: {
                    886:        if (!keycode)
                    887:                return "";
                    888: 
                    889:        return SDL_GetKeyName(keycode);
                    890: }
                    891: 
1.1.1.19! root      892: #else  /* !WITH_SDL2 */
1.1.1.18  root      893: 
                    894: static struct {
                    895:        int code;
                    896:        const char *name;
                    897: } const sdl_keytab[] = {
                    898:        { SDLK_BACKSPACE, "Backspace" },
                    899:        { SDLK_TAB, "Tab" },
                    900:        { SDLK_CLEAR, "Clear" },
                    901:        { SDLK_RETURN, "Return" },
                    902:        { SDLK_PAUSE, "Pause" },
                    903:        { SDLK_ESCAPE, "Escape" },
                    904:        { SDLK_SPACE, "Space" },
                    905:        { SDLK_EXCLAIM, "!" },
                    906:        { SDLK_QUOTEDBL, "\"" },
                    907:        { SDLK_HASH, "#" },
                    908:        { SDLK_DOLLAR, "$" },
                    909:        { SDLK_AMPERSAND, "&" },
                    910:        { SDLK_QUOTE, "'" },
                    911:        { SDLK_LEFTPAREN, "(" },
                    912:        { SDLK_RIGHTPAREN, ")" },
                    913:        { SDLK_ASTERISK, "*" },
                    914:        { SDLK_PLUS, "+" },
                    915:        { SDLK_COMMA, "," },
                    916:        { SDLK_MINUS, "-" },
                    917:        { SDLK_PERIOD, "." },
                    918:        { SDLK_SLASH, "/" },
                    919:        { SDLK_0, "0" },
                    920:        { SDLK_1, "1" },
                    921:        { SDLK_2, "2" },
                    922:        { SDLK_3, "3" },
                    923:        { SDLK_4, "4" },
                    924:        { SDLK_5, "5" },
                    925:        { SDLK_6, "6" },
                    926:        { SDLK_7, "7" },
                    927:        { SDLK_8, "8" },
                    928:        { SDLK_9, "9" },
                    929:        { SDLK_COLON, ":" },
                    930:        { SDLK_SEMICOLON, ";" },
                    931:        { SDLK_LESS, "<" },
                    932:        { SDLK_EQUALS, "=" },
                    933:        { SDLK_GREATER, ">" },
                    934:        { SDLK_QUESTION, "?" },
                    935:        { SDLK_AT, "@" },
                    936:        { SDLK_LEFTBRACKET, "[" },
                    937:        { SDLK_BACKSLASH, "\\" },
                    938:        { SDLK_RIGHTBRACKET, "]" },
                    939:        { SDLK_CARET, "^" },
                    940:        { SDLK_UNDERSCORE, "_" },
                    941:        { SDLK_BACKQUOTE, "`" },
                    942:        { SDLK_a, "A" },
                    943:        { SDLK_b, "B" },
                    944:        { SDLK_c, "C" },
                    945:        { SDLK_d, "D" },
                    946:        { SDLK_e, "E" },
                    947:        { SDLK_f, "F" },
                    948:        { SDLK_g, "G" },
                    949:        { SDLK_h, "H" },
                    950:        { SDLK_i, "I" },
                    951:        { SDLK_j, "J" },
                    952:        { SDLK_k, "K" },
                    953:        { SDLK_l, "L" },
                    954:        { SDLK_m, "M" },
                    955:        { SDLK_n, "N" },
                    956:        { SDLK_o, "O" },
                    957:        { SDLK_p, "P" },
                    958:        { SDLK_q, "Q" },
                    959:        { SDLK_r, "R" },
                    960:        { SDLK_s, "S" },
                    961:        { SDLK_t, "T" },
                    962:        { SDLK_u, "U" },
                    963:        { SDLK_v, "V" },
                    964:        { SDLK_w, "W" },
                    965:        { SDLK_x, "X" },
                    966:        { SDLK_y, "Y" },
                    967:        { SDLK_z, "Z" },
                    968:        { SDLK_DELETE, "Delete" },
                    969:        { SDLK_KP0, "Keypad 0" },
                    970:        { SDLK_KP1, "Keypad 1" },
                    971:        { SDLK_KP2, "Keypad 2" },
                    972:        { SDLK_KP3, "Keypad 3" },
                    973:        { SDLK_KP4, "Keypad 4" },
                    974:        { SDLK_KP5, "Keypad 5" },
                    975:        { SDLK_KP6, "Keypad 6" },
                    976:        { SDLK_KP7, "Keypad 7" },
                    977:        { SDLK_KP8, "Keypad 8" },
                    978:        { SDLK_KP9, "Keypad 9" },
                    979:        { SDLK_KP_PERIOD, "Keypad ." },
                    980:        { SDLK_KP_DIVIDE, "Keypad /" },
                    981:        { SDLK_KP_MULTIPLY, "Keypad *" },
                    982:        { SDLK_KP_MINUS, "Keypad -" },
                    983:        { SDLK_KP_PLUS, "Keypad +" },
                    984:        { SDLK_KP_ENTER, "Keypad Enter" },
                    985:        { SDLK_KP_EQUALS, "Keypad =" },
                    986:        { SDLK_UP, "Up" },
                    987:        { SDLK_DOWN, "Down" },
                    988:        { SDLK_RIGHT, "Right" },
                    989:        { SDLK_LEFT, "Left" },
                    990:        { SDLK_INSERT, "Insert" },
                    991:        { SDLK_HOME, "Home" },
                    992:        { SDLK_END, "End" },
                    993:        { SDLK_PAGEUP, "PageUp" },
                    994:        { SDLK_PAGEDOWN, "PageDown" },
                    995:        { SDLK_F1, "F1" },
                    996:        { SDLK_F2, "F2" },
                    997:        { SDLK_F3, "F3" },
                    998:        { SDLK_F4, "F4" },
                    999:        { SDLK_F5, "F5" },
                   1000:        { SDLK_F6, "F6" },
                   1001:        { SDLK_F7, "F7" },
                   1002:        { SDLK_F8, "F8" },
                   1003:        { SDLK_F9, "F9" },
                   1004:        { SDLK_F10, "F10" },
                   1005:        { SDLK_F11, "F11" },
                   1006:        { SDLK_F12, "F12" },
                   1007:        { SDLK_F13, "F13" },
                   1008:        { SDLK_F14, "F14" },
                   1009:        { SDLK_F15, "F15" },
                   1010:        { SDLK_NUMLOCK, "Numlock" },
                   1011:        { SDLK_CAPSLOCK, "CapsLock" },
                   1012:        { SDLK_SCROLLOCK, "ScrollLock" },
                   1013:        { SDLK_RSHIFT, "Right Shift" },
                   1014:        { SDLK_LSHIFT, "Left Shift" },
                   1015:        { SDLK_RCTRL, "Right Ctrl" },
                   1016:        { SDLK_LCTRL, "Left Ctrl" },
                   1017:        { SDLK_RALT, "Right Alt" },
                   1018:        { SDLK_LALT, "Left Alt" },
                   1019:        { SDLK_RMETA, "Right GUI" },
                   1020:        { SDLK_LMETA, "Left GUI" },
                   1021:        { SDLK_MODE, "ModeSwitch" },
                   1022:        { SDLK_HELP, "Help" },
                   1023:        { SDLK_PRINT, "PrintScreen" },
                   1024:        { SDLK_SYSREQ, "SysReq" },
                   1025:        { SDLK_BREAK, "Cancel" },
                   1026:        { SDLK_MENU, "Menu" },
                   1027:        { SDLK_POWER, "Power" },
                   1028:        { SDLK_UNDO, "Undo" },
                   1029: 
                   1030:        { SDLK_WORLD_1, "¡" }, /* 161 */
                   1031:        { SDLK_WORLD_2, "¢" }, /* 162 */
                   1032:        { SDLK_WORLD_3, "£" }, /* 163 */
                   1033:        { SDLK_WORLD_4, "¤" }, /* 164 */
                   1034:        { SDLK_WORLD_5, "¥" }, /* 165 */
                   1035:        { SDLK_WORLD_6, "¦" }, /* 166 */
                   1036:        { SDLK_WORLD_7, "§" }, /* 167 */
                   1037:        { SDLK_WORLD_8, "¨" }, /* 168 */
                   1038:        { SDLK_WORLD_9, "©" }, /* 169 */
                   1039:        { SDLK_WORLD_10, "ª" },        /* 170 */
                   1040:        { SDLK_WORLD_11, "«" },        /* 171 */
                   1041:        { SDLK_WORLD_12, "¬" },        /* 172 */
                   1042:        { SDLK_WORLD_14, "®" },        /* 174 */
                   1043:        { SDLK_WORLD_15, "¯" },        /* 175 */
                   1044:        { SDLK_WORLD_16, "°" },        /* 176 */
                   1045:        { SDLK_WORLD_17, "±" },        /* 177 */
                   1046:        { SDLK_WORLD_18, "²" },        /* 178 */
                   1047:        { SDLK_WORLD_19, "³" },        /* 179 */
                   1048:        { SDLK_WORLD_20, "´" },        /* 180 */
                   1049:        { SDLK_WORLD_21, "µ" },        /* 181 */
                   1050:        { SDLK_WORLD_22, "¶" },        /* 182 */
                   1051:        { SDLK_WORLD_23, "·" },        /* 183 */
                   1052:        { SDLK_WORLD_24, "¸" },        /* 184 */
                   1053:        { SDLK_WORLD_25, "¹" },        /* 185 */
                   1054:        { SDLK_WORLD_26, "º" },        /* 186 */
                   1055:        { SDLK_WORLD_27, "»" },        /* 187 */
                   1056:        { SDLK_WORLD_28, "¼" },        /* 188 */
                   1057:        { SDLK_WORLD_29, "½" },        /* 189 */
                   1058:        { SDLK_WORLD_30, "¾" },        /* 190 */
                   1059:        { SDLK_WORLD_31, "¿" },        /* 191 */
                   1060:        { SDLK_WORLD_32, "À" },        /* 192 */
                   1061:        { SDLK_WORLD_33, "Á" },        /* 193 */
                   1062:        { SDLK_WORLD_34, "Â" },        /* 194 */
                   1063:        { SDLK_WORLD_35, "Ã" },        /* 195 */
                   1064:        { SDLK_WORLD_36, "Ä" },        /* 196 */
                   1065:        { SDLK_WORLD_37, "Å" },        /* 197 */
                   1066:        { SDLK_WORLD_38, "Æ" },        /* 198 */
                   1067:        { SDLK_WORLD_39, "Ç" },        /* 199 */
                   1068:        { SDLK_WORLD_40, "È" },        /* 200 */
                   1069:        { SDLK_WORLD_41, "É" },        /* 201 */
                   1070:        { SDLK_WORLD_42, "Ê" },        /* 202 */
                   1071:        { SDLK_WORLD_43, "Ë" },        /* 203 */
                   1072:        { SDLK_WORLD_44, "Ì" },        /* 204 */
                   1073:        { SDLK_WORLD_45, "Í" },        /* 205 */
                   1074:        { SDLK_WORLD_46, "Î" },        /* 206 */
                   1075:        { SDLK_WORLD_47, "Ï" },        /* 207 */
                   1076:        { SDLK_WORLD_48, "Ð" },        /* 208 */
                   1077:        { SDLK_WORLD_49, "Ñ" },        /* 209 */
                   1078:        { SDLK_WORLD_50, "Ò" },        /* 210 */
                   1079:        { SDLK_WORLD_51, "Ó" },        /* 211 */
                   1080:        { SDLK_WORLD_52, "Ô" },        /* 212 */
                   1081:        { SDLK_WORLD_53, "Õ" },        /* 213 */
                   1082:        { SDLK_WORLD_54, "Ö" },        /* 214 */
                   1083:        { SDLK_WORLD_55, "×" },        /* 215 */
                   1084:        { SDLK_WORLD_56, "Ø" },        /* 216 */
                   1085:        { SDLK_WORLD_57, "Ù" },        /* 217 */
                   1086:        { SDLK_WORLD_58, "Ú" },        /* 218 */
                   1087:        { SDLK_WORLD_59, "Û" },        /* 219 */
                   1088:        { SDLK_WORLD_60, "Ü" },        /* 220 */
                   1089:        { SDLK_WORLD_61, "Ý" },        /* 221 */
                   1090:        { SDLK_WORLD_62, "Þ" },        /* 222 */
                   1091:        { SDLK_WORLD_63, "ß" },        /* 223 */
                   1092:        { SDLK_WORLD_64, "à" },        /* 224 */
                   1093:        { SDLK_WORLD_65, "á" },        /* 225 */
                   1094:        { SDLK_WORLD_66, "â" },        /* 226 */
                   1095:        { SDLK_WORLD_67, "ã" },        /* 227 */
                   1096:        { SDLK_WORLD_68, "ä" },        /* 228 */
                   1097:        { SDLK_WORLD_69, "å" },        /* 229 */
                   1098:        { SDLK_WORLD_70, "æ" },        /* 230 */
                   1099:        { SDLK_WORLD_71, "ç" },        /* 231 */
                   1100:        { SDLK_WORLD_72, "è" },        /* 232 */
                   1101:        { SDLK_WORLD_73, "é" },        /* 233 */
                   1102:        { SDLK_WORLD_74, "ê" },        /* 234 */
                   1103:        { SDLK_WORLD_75, "ë" },        /* 235 */
                   1104:        { SDLK_WORLD_76, "ì" },        /* 236 */
                   1105:        { SDLK_WORLD_77, "í" },        /* 237 */
                   1106:        { SDLK_WORLD_78, "î" },        /* 238 */
                   1107:        { SDLK_WORLD_79, "ï" },        /* 239 */
                   1108:        { SDLK_WORLD_80, "ð" },        /* 240 */
                   1109:        { SDLK_WORLD_81, "ñ" },        /* 241 */
                   1110:        { SDLK_WORLD_82, "ò" },        /* 242 */
                   1111:        { SDLK_WORLD_83, "ó" },        /* 243 */
                   1112:        { SDLK_WORLD_84, "ô" },        /* 244 */
                   1113:        { SDLK_WORLD_85, "õ" },        /* 245 */
                   1114:        { SDLK_WORLD_86, "ö" },        /* 246 */
                   1115:        { SDLK_WORLD_87, "÷" },        /* 247 */
                   1116:        { SDLK_WORLD_88, "ø" },        /* 248 */
                   1117:        { SDLK_WORLD_89, "ù" },        /* 249 */
                   1118:        { SDLK_WORLD_90, "ú" },        /* 250 */
                   1119:        { SDLK_WORLD_91, "û" },        /* 251 */
                   1120:        { SDLK_WORLD_92, "ü" },        /* 252 */
                   1121:        { SDLK_WORLD_93, "ý" },        /* 253 */
                   1122:        { SDLK_WORLD_94, "þ" },        /* 254 */
                   1123:        { SDLK_WORLD_95, "ÿ" },        /* 255 */
                   1124: 
                   1125:        { -1, NULL }
                   1126: };
                   1127: 
                   1128: int Keymap_GetKeyFromName(const char *name)
                   1129: {
                   1130:        int i;
                   1131: 
                   1132:        if (!name[0])
                   1133:                return 0;
                   1134: 
                   1135:        for (i = 0; sdl_keytab[i].name != NULL; i++)
                   1136:        {
                   1137:                if (strcasecmp(name, sdl_keytab[i].name) == 0)
                   1138:                        return sdl_keytab[i].code;
                   1139:        }
                   1140: 
                   1141:        return 0;
                   1142: }
                   1143: 
                   1144: const char *Keymap_GetKeyName(int keycode)
                   1145: {
                   1146:        int i;
                   1147: 
                   1148:        if (!keycode)
                   1149:                return "";
                   1150: 
                   1151:        for (i = 0; sdl_keytab[i].name != NULL; i++)
                   1152:        {
                   1153:                if (keycode == sdl_keytab[i].code)
                   1154:                        return sdl_keytab[i].name;
                   1155:        }
                   1156: 
                   1157:        return "";
                   1158: }
                   1159: 
1.1.1.19! root     1160: #endif /* !WITH_SDL2 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.