|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * X keysym support ! 5: * ! 6: * Copyright 1995, 1996 Bernd Schmidt ! 7: * Copyright 1996 Ed Hanway, Andre Beck, Samuel Devulder, Bruno Coste ! 8: * Copyright 1998 Marcus Sundberg ! 9: * DGA support by Kai Kollmorgen ! 10: * X11/DGA merge, hotkeys and grabmouse by Marcus Sundberg ! 11: * Copyright 2003-2004 Richard Drummond ! 12: */ ! 13: ! 14: #include "sysconfig.h" ! 15: #include "sysdeps.h" ! 16: ! 17: #include <X11/Xlib.h> ! 18: #include <X11/keysym.h> ! 19: ! 20: #include "options.h" ! 21: #include "inputdevice.h" ! 22: #include "keyboard.h" ! 23: #include "hotkeys.h" ! 24: ! 25: ! 26: /* Decode KeySyms. This function knows about all keys that are common ! 27: * between different keyboard languages. */ ! 28: static int kc_decode (KeySym ks) ! 29: { ! 30: switch (ks) { ! 31: case XK_B: case XK_b: return AK_B; ! 32: case XK_C: case XK_c: return AK_C; ! 33: case XK_D: case XK_d: return AK_D; ! 34: case XK_E: case XK_e: return AK_E; ! 35: case XK_F: case XK_f: return AK_F; ! 36: case XK_G: case XK_g: return AK_G; ! 37: case XK_H: case XK_h: return AK_H; ! 38: case XK_I: case XK_i: return AK_I; ! 39: case XK_J: case XK_j: return AK_J; ! 40: case XK_K: case XK_k: return AK_K; ! 41: case XK_L: case XK_l: return AK_L; ! 42: case XK_N: case XK_n: return AK_N; ! 43: case XK_O: case XK_o: return AK_O; ! 44: case XK_P: case XK_p: return AK_P; ! 45: case XK_R: case XK_r: return AK_R; ! 46: case XK_S: case XK_s: return AK_S; ! 47: case XK_T: case XK_t: return AK_T; ! 48: case XK_U: case XK_u: return AK_U; ! 49: case XK_V: case XK_v: return AK_V; ! 50: case XK_X: case XK_x: return AK_X; ! 51: ! 52: case XK_0: return AK_0; ! 53: case XK_1: return AK_1; ! 54: case XK_2: return AK_2; ! 55: case XK_3: return AK_3; ! 56: case XK_4: return AK_4; ! 57: case XK_5: return AK_5; ! 58: case XK_6: return AK_6; ! 59: case XK_7: return AK_7; ! 60: case XK_8: return AK_8; ! 61: case XK_9: return AK_9; ! 62: ! 63: /* You never know which Keysyms might be missing on some workstation ! 64: * This #ifdef should be enough. */ ! 65: #if defined(XK_KP_Prior) && defined(XK_KP_Left) && defined(XK_KP_Insert) && defined (XK_KP_End) ! 66: case XK_KP_0: case XK_KP_Insert: return AK_NP0; ! 67: case XK_KP_1: case XK_KP_End: return AK_NP1; ! 68: case XK_KP_2: case XK_KP_Down: return AK_NP2; ! 69: case XK_KP_3: case XK_KP_Next: return AK_NP3; ! 70: case XK_KP_4: case XK_KP_Left: return AK_NP4; ! 71: case XK_KP_5: case XK_KP_Begin: return AK_NP5; ! 72: case XK_KP_6: case XK_KP_Right: return AK_NP6; ! 73: case XK_KP_7: case XK_KP_Home: return AK_NP7; ! 74: case XK_KP_8: case XK_KP_Up: return AK_NP8; ! 75: case XK_KP_9: case XK_KP_Prior: return AK_NP9; ! 76: #else ! 77: case XK_KP_0: return AK_NP0; ! 78: case XK_KP_1: return AK_NP1; ! 79: case XK_KP_2: return AK_NP2; ! 80: case XK_KP_3: return AK_NP3; ! 81: case XK_KP_4: return AK_NP4; ! 82: case XK_KP_5: return AK_NP5; ! 83: case XK_KP_6: return AK_NP6; ! 84: case XK_KP_7: return AK_NP7; ! 85: case XK_KP_8: return AK_NP8; ! 86: case XK_KP_9: return AK_NP9; ! 87: #endif ! 88: case XK_KP_Divide: return AK_NPDIV; ! 89: case XK_KP_Multiply: return AK_NPMUL; ! 90: case XK_KP_Subtract: return AK_NPSUB; ! 91: case XK_KP_Add: return AK_NPADD; ! 92: case XK_KP_Decimal: return AK_NPDEL; ! 93: case XK_KP_Enter: return AK_ENT; ! 94: ! 95: case XK_F1: return AK_F1; ! 96: case XK_F2: return AK_F2; ! 97: case XK_F3: return AK_F3; ! 98: case XK_F4: return AK_F4; ! 99: case XK_F5: return AK_F5; ! 100: case XK_F6: return AK_F6; ! 101: case XK_F7: return AK_F7; ! 102: case XK_F8: return AK_F8; ! 103: case XK_F9: return AK_F9; ! 104: case XK_F10: return AK_F10; ! 105: ! 106: case XK_BackSpace: return AK_BS; ! 107: case XK_Delete: return AK_DEL; ! 108: case XK_Control_L: return AK_CTRL; ! 109: case XK_Control_R: return AK_RCTRL; ! 110: case XK_Tab: return AK_TAB; ! 111: case XK_Alt_L: return AK_LALT; ! 112: case XK_Alt_R: return AK_RALT; ! 113: case XK_Meta_R: case XK_Hyper_R: return AK_RAMI; ! 114: case XK_Meta_L: case XK_Hyper_L: return AK_LAMI; ! 115: case XK_Return: return AK_RET; ! 116: case XK_space: return AK_SPC; ! 117: case XK_Shift_L: return AK_LSH; ! 118: case XK_Shift_R: return AK_RSH; ! 119: case XK_Escape: return AK_ESC; ! 120: ! 121: case XK_Insert: return AK_HELP; ! 122: case XK_Home: return AK_NPLPAREN; ! 123: case XK_End: return AK_NPRPAREN; ! 124: case XK_Caps_Lock: return AK_CAPSLOCK; ! 125: ! 126: case XK_Up: return AK_UP; ! 127: case XK_Down: return AK_DN; ! 128: case XK_Left: return AK_LF; ! 129: case XK_Right: return AK_RT; ! 130: ! 131: #ifdef XK_Page_Up /* These are missing occasionally */ ! 132: case XK_Page_Up: return AK_RAMI; /* PgUp mapped to right amiga */ ! 133: case XK_Page_Down: return AK_LAMI; /* PgDn mapped to left amiga */ ! 134: #endif ! 135: ! 136: #ifdef XK_Super_L ! 137: case XK_Super_L: return AK_LAMI; ! 138: case XK_Super_R: return AK_RAMI; ! 139: #endif ! 140: case XK_Scroll_Lock: return AKS_INHIBITSCREEN; ! 141: case XK_Print: return AKS_SCREENSHOT; ! 142: } ! 143: return -1; ! 144: } ! 145: ! 146: static int decode_fr (KeySym ks) ! 147: { ! 148: switch(ks) { /* FR specific */ ! 149: case XK_A: case XK_a: return AK_Q; ! 150: case XK_M: case XK_m: return AK_SEMICOLON; ! 151: case XK_Q: case XK_q: return AK_A; ! 152: case XK_Y: case XK_y: return AK_Y; ! 153: case XK_W: case XK_w: return AK_Z; ! 154: case XK_Z: case XK_z: return AK_W; ! 155: #if 0 ! 156: case XK_bracketleft: return AK_LBRACKET; ! 157: case XK_bracketright: return AK_RBRACKET; ! 158: case XK_comma: return AK_M; ! 159: case XK_less: case XK_greater: return AK_LTGT; ! 160: case XK_period: return AK_COMMA; ! 161: case XK_parenright: return AK_MINUS; ! 162: case XK_equal: return AK_SLASH; ! 163: case XK_numbersign: return AK_NUMBERSIGN; ! 164: case XK_slash: return AK_PERIOD; ! 165: case XK_minus: return AK_EQUAL; ! 166: case XK_backslash: return AK_BACKSLASH; ! 167: #else ! 168: /* not sure for this one: my X 3.3 server doesn't handle this key always ! 169: * correctly... But anyway, on new french keyboards, no more bracket key ! 170: * at this place. ! 171: */ ! 172: case XK_dead_circumflex: ! 173: case XK_dead_diaeresis: return AK_LBRACKET; ! 174: case XK_dollar: ! 175: case XK_sterling: return AK_RBRACKET; ! 176: case XK_comma: case XK_question: return AK_M; ! 177: case XK_less: case XK_greater: return AK_LTGT; ! 178: case XK_semicolon: case XK_period: return AK_COMMA; ! 179: case XK_parenright: case XK_degree: return AK_MINUS; ! 180: case XK_equal: case XK_plus: return AK_SLASH; ! 181: case XK_numbersign: return AK_NUMBERSIGN; ! 182: case XK_colon: case XK_slash: return AK_PERIOD; ! 183: case XK_minus: case XK_6: return AK_6; ! 184: case XK_ugrave: case XK_percent: return AK_QUOTE; ! 185: /* found a spare key - I hope it deserves this place. */ ! 186: case XK_asterisk: case XK_mu: return AK_BACKSLASH; ! 187: case XK_exclam: case XK_section: return AK_EQUAL; ! 188: case XK_twosuperior: case XK_asciitilde: return AK_BACKQUOTE; ! 189: case XK_Multi_key: return AK_RAMI; ! 190: case XK_Mode_switch: return AK_RALT; ! 191: #endif ! 192: } ! 193: ! 194: return -1; ! 195: } ! 196: ! 197: static int decode_us (KeySym ks) ! 198: { ! 199: switch(ks) { /* US specific */ ! 200: case XK_A: case XK_a: return AK_A; ! 201: case XK_M: case XK_m: return AK_M; ! 202: case XK_Q: case XK_q: return AK_Q; ! 203: case XK_Y: case XK_y: return AK_Y; ! 204: case XK_W: case XK_w: return AK_W; ! 205: case XK_Z: case XK_z: return AK_Z; ! 206: case XK_bracketleft: return AK_LBRACKET; ! 207: case XK_bracketright: return AK_RBRACKET; ! 208: case XK_comma: return AK_COMMA; ! 209: case XK_period: return AK_PERIOD; ! 210: case XK_slash: return AK_SLASH; ! 211: case XK_semicolon: return AK_SEMICOLON; ! 212: case XK_minus: return AK_MINUS; ! 213: case XK_equal: return AK_EQUAL; ! 214: /* this doesn't work: */ ! 215: case XK_quoteright: return AK_QUOTE; ! 216: case XK_quoteleft: return AK_BACKQUOTE; ! 217: case XK_backslash: return AK_BACKSLASH; ! 218: } ! 219: ! 220: return -1; ! 221: } ! 222: ! 223: static int decode_de (KeySym ks) ! 224: { ! 225: switch(ks) { ! 226: /* DE specific */ ! 227: case XK_A: case XK_a: return AK_A; ! 228: case XK_M: case XK_m: return AK_M; ! 229: case XK_Q: case XK_q: return AK_Q; ! 230: case XK_W: case XK_w: return AK_W; ! 231: case XK_Y: case XK_y: return AK_Z; ! 232: case XK_Z: case XK_z: return AK_Y; ! 233: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON; ! 234: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE; ! 235: case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET; ! 236: case XK_plus: case XK_asterisk: return AK_RBRACKET; ! 237: case XK_comma: return AK_COMMA; ! 238: case XK_period: return AK_PERIOD; ! 239: case XK_less: case XK_greater: return AK_LTGT; ! 240: case XK_numbersign: return AK_NUMBERSIGN; ! 241: case XK_ssharp: return AK_MINUS; ! 242: case XK_apostrophe: return AK_EQUAL; ! 243: case XK_asciicircum: return AK_BACKQUOTE; ! 244: case XK_minus: return AK_SLASH; ! 245: } ! 246: ! 247: return -1; ! 248: } ! 249: ! 250: static int decode_dk (KeySym ks) ! 251: { ! 252: switch(ks) { ! 253: /* DK specific */ ! 254: case XK_A: case XK_a: return AK_A; ! 255: case XK_M: case XK_m: return AK_M; ! 256: case XK_Q: case XK_q: return AK_Q; ! 257: case XK_W: case XK_w: return AK_W; ! 258: case XK_Y: case XK_y: return AK_Y; ! 259: case XK_Z: case XK_z: return AK_Z; ! 260: case XK_AE: case XK_ae: return AK_SEMICOLON; ! 261: case XK_Ooblique: case XK_oslash: return AK_QUOTE; ! 262: case XK_Aring: case XK_aring: return AK_LBRACKET; ! 263: case XK_apostrophe: case XK_asterisk: return AK_NUMBERSIGN; ! 264: case XK_dead_diaeresis: case XK_dead_circumflex: return AK_RBRACKET; ! 265: case XK_dead_acute: case XK_dead_grave: return AK_BACKSLASH; ! 266: case XK_onehalf: case XK_section: return AK_BACKQUOTE; ! 267: case XK_comma: return AK_COMMA; ! 268: case XK_period: return AK_PERIOD; ! 269: case XK_less: case XK_greater: return AK_LTGT; ! 270: case XK_numbersign: return AK_NUMBERSIGN; ! 271: case XK_plus: return AK_MINUS; ! 272: case XK_asciicircum: return AK_BACKQUOTE; ! 273: case XK_minus: return AK_SLASH; ! 274: } ! 275: ! 276: return -1; ! 277: } ! 278: ! 279: static int decode_se (KeySym ks) ! 280: { ! 281: switch(ks) { ! 282: /* SE specific */ ! 283: case XK_A: case XK_a: return AK_A; ! 284: case XK_M: case XK_m: return AK_M; ! 285: case XK_Q: case XK_q: return AK_Q; ! 286: case XK_W: case XK_w: return AK_W; ! 287: case XK_Y: case XK_y: return AK_Y; ! 288: case XK_Z: case XK_z: return AK_Z; ! 289: case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON; ! 290: case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE; ! 291: case XK_Aring: case XK_aring: return AK_LBRACKET; ! 292: case XK_comma: return AK_COMMA; ! 293: case XK_period: return AK_PERIOD; ! 294: case XK_minus: return AK_SLASH; ! 295: case XK_less: case XK_greater: return AK_LTGT; ! 296: case XK_plus: case XK_question: return AK_EQUAL; ! 297: case XK_at: case XK_onehalf: return AK_BACKQUOTE; ! 298: case XK_asciitilde: case XK_asciicircum: return AK_RBRACKET; ! 299: case XK_backslash: case XK_bar: return AK_MINUS; ! 300: ! 301: case XK_numbersign: return AK_NUMBERSIGN; ! 302: } ! 303: ! 304: return -1; ! 305: } ! 306: ! 307: static int decode_it (KeySym ks) ! 308: { ! 309: switch(ks) { ! 310: /* IT specific */ ! 311: case XK_A: case XK_a: return AK_A; ! 312: case XK_M: case XK_m: return AK_M; ! 313: case XK_Q: case XK_q: return AK_Q; ! 314: case XK_W: case XK_w: return AK_W; ! 315: case XK_Y: case XK_y: return AK_Y; ! 316: case XK_Z: case XK_z: return AK_Z; ! 317: case XK_Ograve: case XK_ograve: return AK_SEMICOLON; ! 318: case XK_Agrave: case XK_agrave: return AK_QUOTE; ! 319: case XK_Egrave: case XK_egrave: return AK_LBRACKET; ! 320: case XK_plus: case XK_asterisk: return AK_RBRACKET; ! 321: case XK_comma: return AK_COMMA; ! 322: case XK_period: return AK_PERIOD; ! 323: case XK_less: case XK_greater: return AK_LTGT; ! 324: case XK_backslash: case XK_bar: return AK_BACKQUOTE; ! 325: case XK_apostrophe: return AK_MINUS; ! 326: case XK_Igrave: case XK_igrave: return AK_EQUAL; ! 327: case XK_minus: return AK_SLASH; ! 328: case XK_numbersign: return AK_NUMBERSIGN; ! 329: } ! 330: ! 331: return -1; ! 332: } ! 333: ! 334: static int decode_es (KeySym ks) ! 335: { ! 336: switch(ks) { ! 337: /* ES specific */ ! 338: case XK_A: case XK_a: return AK_A; ! 339: case XK_M: case XK_m: return AK_M; ! 340: case XK_Q: case XK_q: return AK_Q; ! 341: case XK_W: case XK_w: return AK_W; ! 342: case XK_Y: case XK_y: return AK_Y; ! 343: case XK_Z: case XK_z: return AK_Z; ! 344: case XK_ntilde: case XK_Ntilde: return AK_SEMICOLON; ! 345: #ifdef XK_dead_acute ! 346: case XK_dead_acute: case XK_dead_diaeresis: return AK_QUOTE; ! 347: case XK_dead_grave: case XK_dead_circumflex: return AK_LBRACKET; ! 348: #endif ! 349: case XK_plus: case XK_asterisk: return AK_RBRACKET; ! 350: case XK_comma: return AK_COMMA; ! 351: case XK_period: return AK_PERIOD; ! 352: case XK_less: case XK_greater: return AK_LTGT; ! 353: case XK_backslash: case XK_bar: return AK_BACKQUOTE; ! 354: case XK_apostrophe: return AK_MINUS; ! 355: case XK_Igrave: case XK_igrave: return AK_EQUAL; ! 356: case XK_minus: return AK_SLASH; ! 357: case XK_numbersign: return AK_NUMBERSIGN; ! 358: } ! 359: ! 360: return -1; ! 361: } ! 362: ! 363: int xkeysym2amiga (KeySym ks) ! 364: { ! 365: int as = kc_decode (ks); ! 366: ! 367: if (as == -1) { ! 368: switch (currprefs.keyboard_lang) { ! 369: case KBD_LANG_FR: ! 370: as = decode_fr (ks); break; ! 371: case KBD_LANG_US: ! 372: as = decode_us (ks); break; ! 373: case KBD_LANG_DE: ! 374: as = decode_de (ks); break; ! 375: case KBD_LANG_DK: ! 376: as = decode_dk (ks); break; ! 377: case KBD_LANG_SE: ! 378: as = decode_se (ks); break; ! 379: case KBD_LANG_IT: ! 380: as = decode_it (ks); break; ! 381: case KBD_LANG_ES: ! 382: as = decode_es (ks); break; ! 383: } ! 384: } ! 385: return as; ! 386: } ! 387: ! 388: /* ! 389: * Default hotkeys ! 390: * ! 391: * We need a better way of doing this. ;-) ! 392: */ ! 393: static struct uae_hotkeyseq x11_hotkeys[] = ! 394: { ! 395: { MAKE_HOTKEYSEQ (XK_F12, XK_q, -1, -1, INPUTEVENT_SPC_QUIT) }, ! 396: { MAKE_HOTKEYSEQ (XK_F12, XK_r, -1, -1, INPUTEVENT_SPC_SOFTRESET) }, ! 397: { MAKE_HOTKEYSEQ (XK_F12, XK_Shift_L, XK_r, -1, INPUTEVENT_SPC_HARDRESET) }, ! 398: { MAKE_HOTKEYSEQ (XK_F12, XK_d, -1, -1, INPUTEVENT_SPC_ENTERDEBUGGER) }, ! 399: { MAKE_HOTKEYSEQ (XK_F12, XK_s, -1, -1, INPUTEVENT_SPC_TOGGLEFULLSCREEN) }, ! 400: { MAKE_HOTKEYSEQ (XK_F12, XK_g, -1, -1, INPUTEVENT_SPC_TOGGLEMOUSEGRAB) }, ! 401: { MAKE_HOTKEYSEQ (XK_F12, XK_i, -1, -1, INPUTEVENT_SPC_INHIBITSCREEN) }, ! 402: { MAKE_HOTKEYSEQ (XK_F12, XK_p, -1, -1, INPUTEVENT_SPC_SCREENSHOT) }, ! 403: { MAKE_HOTKEYSEQ (XK_F12, XK_a, -1, -1, INPUTEVENT_SPC_SWITCHINTERPOL) }, ! 404: { MAKE_HOTKEYSEQ (XK_F12, XK_KP_Add, -1, -1, INPUTEVENT_SPC_INCREASE_REFRESHRATE) }, ! 405: { MAKE_HOTKEYSEQ (XK_F12, XK_KP_Subtract, -1, -1, INPUTEVENT_SPC_DECREASE_REFRESHRATE) }, ! 406: { MAKE_HOTKEYSEQ (XK_F12, XK_F1, -1, -1, INPUTEVENT_SPC_FLOPPY0) }, ! 407: { MAKE_HOTKEYSEQ (XK_F12, XK_F2, -1, -1, INPUTEVENT_SPC_FLOPPY1) }, ! 408: { MAKE_HOTKEYSEQ (XK_F12, XK_F3, -1, -1, INPUTEVENT_SPC_FLOPPY2) }, ! 409: { MAKE_HOTKEYSEQ (XK_F12, XK_F4, -1, -1, INPUTEVENT_SPC_FLOPPY3) }, ! 410: { MAKE_HOTKEYSEQ (XK_F12, XK_Shift_L, XK_F1, -1, INPUTEVENT_SPC_EFLOPPY0) }, ! 411: { MAKE_HOTKEYSEQ (XK_F12, XK_Shift_L, XK_F2, -1, INPUTEVENT_SPC_EFLOPPY1) }, ! 412: { MAKE_HOTKEYSEQ (XK_F12, XK_Shift_L, XK_F3, -1, INPUTEVENT_SPC_EFLOPPY2) }, ! 413: { MAKE_HOTKEYSEQ (XK_F12, XK_Shift_L, XK_F4, -1, INPUTEVENT_SPC_EFLOPPY3) }, ! 414: { MAKE_HOTKEYSEQ (XK_F12, XK_Return, -1, -1, INPUTEVENT_SPC_ENTERGUI) }, ! 415: { MAKE_HOTKEYSEQ (XK_F12, XK_f, -1, -1, INPUTEVENT_SPC_FREEZEBUTTON) }, ! 416: { HOTKEYS_END } ! 417: }; ! 418: ! 419: struct uae_hotkeyseq *get_x11_default_hotkeys (void) ! 420: { ! 421: return x11_hotkeys; ! 422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.