|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * SDL keyboard driver which maps SDL cooked keysyms to raw
5: * Amiga keycodes
6: *
7: * Copyright 2004 Richard Drummond
8: *
9: * Based on previous SDL keymapping
10: * Copyright 2001 Bernd Lachner (EMail: [email protected])
11: */
12:
13: #include "sysconfig.h"
14: #include "sysdeps.h"
15:
16: #include "options.h"
17: #include "inputdevice.h"
18: #include "keyboard.h"
19: #include "hotkeys.h"
20:
21: #include "sdlgfx.h"
22:
23: #include <SDL.h>
24:
25: /*
26: * This function knows about all keys that are common
27: * between different keyboard languages.
28: */
29: static int kc_decode (int keysym)
30: {
31: switch (keysym) {
32: case SDLK_b: return AK_B;
33: case SDLK_c: return AK_C;
34: case SDLK_d: return AK_D;
35: case SDLK_e: return AK_E;
36: case SDLK_f: return AK_F;
37: case SDLK_g: return AK_G;
38: case SDLK_h: return AK_H;
39: case SDLK_i: return AK_I;
40: case SDLK_j: return AK_J;
41: case SDLK_k: return AK_K;
42: case SDLK_l: return AK_L;
43: case SDLK_n: return AK_N;
44: case SDLK_o: return AK_O;
45: case SDLK_p: return AK_P;
46: case SDLK_r: return AK_R;
47: case SDLK_s: return AK_S;
48: case SDLK_t: return AK_T;
49: case SDLK_u: return AK_U;
50: case SDLK_v: return AK_V;
51: case SDLK_x: return AK_X;
52:
53: case SDLK_0: return AK_0;
54: case SDLK_1: return AK_1;
55: case SDLK_2: return AK_2;
56: case SDLK_3: return AK_3;
57: case SDLK_4: return AK_4;
58: case SDLK_5: return AK_5;
59: case SDLK_6: return AK_6;
60: case SDLK_7: return AK_7;
61: case SDLK_8: return AK_8;
62: case SDLK_9: return AK_9;
63:
64: case SDLK_KP0: return AK_NP0;
65: case SDLK_KP1: return AK_NP1;
66: case SDLK_KP2: return AK_NP2;
67: case SDLK_KP3: return AK_NP3;
68: case SDLK_KP4: return AK_NP4;
69: case SDLK_KP5: return AK_NP5;
70: case SDLK_KP6: return AK_NP6;
71: case SDLK_KP7: return AK_NP7;
72: case SDLK_KP8: return AK_NP8;
73: case SDLK_KP9: return AK_NP9;
74: case SDLK_KP_DIVIDE: return AK_NPDIV;
75: case SDLK_KP_MULTIPLY: return AK_NPMUL;
76: case SDLK_KP_MINUS: return AK_NPSUB;
77: case SDLK_KP_PLUS: return AK_NPADD;
78: case SDLK_KP_PERIOD: return AK_NPDEL;
79: case SDLK_KP_ENTER: return AK_ENT;
80:
81: case SDLK_F1: return AK_F1;
82: case SDLK_F2: return AK_F2;
83: case SDLK_F3: return AK_F3;
84: case SDLK_F4: return AK_F4;
85: case SDLK_F5: return AK_F5;
86: case SDLK_F6: return AK_F6;
87: case SDLK_F7: return AK_F7;
88: case SDLK_F8: return AK_F8;
89: case SDLK_F9: return AK_F9;
90: case SDLK_F10: return AK_F10;
91:
92: case SDLK_BACKSPACE: return AK_BS;
93: case SDLK_DELETE: return AK_DEL;
94: case SDLK_LCTRL: return AK_CTRL;
95: case SDLK_RCTRL: return AK_RCTRL;
96: case SDLK_TAB: return AK_TAB;
97: case SDLK_LALT: return AK_LALT;
98: case SDLK_RALT: return AK_RALT;
99: case SDLK_RMETA: return AK_RAMI;
100: case SDLK_LMETA: return AK_LAMI;
101: case SDLK_RETURN: return AK_RET;
102: case SDLK_SPACE: return AK_SPC;
103: case SDLK_LSHIFT: return AK_LSH;
104: case SDLK_RSHIFT: return AK_RSH;
105: case SDLK_ESCAPE: return AK_ESC;
106:
107: case SDLK_INSERT: return AK_HELP;
108: case SDLK_HOME: return AK_NPLPAREN;
109: case SDLK_END: return AK_NPRPAREN;
110: case SDLK_CAPSLOCK: return AK_CAPSLOCK;
111:
112: case SDLK_UP: return AK_UP;
113: case SDLK_DOWN: return AK_DN;
114: case SDLK_LEFT: return AK_LF;
115: case SDLK_RIGHT: return AK_RT;
116:
117: case SDLK_PAGEUP:
118: case SDLK_RSUPER: return AK_RAMI;
119:
120: case SDLK_PAGEDOWN:
121: case SDLK_LSUPER: return AK_LAMI;
122:
123: case SDLK_PAUSE: return AKS_PAUSE;
124: case SDLK_SCROLLOCK: return AKS_INHIBITSCREEN;
125: case SDLK_PRINT: return AKS_SCREENSHOT;
126: default: return -1;
127: }
128: }
129:
130: /*
131: * Handle keys specific to French (and Belgian) keymaps.
132: *
133: * Number keys are broken
134: */
135: static int decode_fr (int keysym)
136: {
137: switch (keysym) {
138: case SDLK_a: return AK_Q;
139: case SDLK_m: return AK_SEMICOLON;
140: case SDLK_q: return AK_A;
141: case SDLK_y: return AK_Y;
142: case SDLK_w: return AK_Z;
143: case SDLK_z: return AK_W;
144: case SDLK_LEFTBRACKET: return AK_LBRACKET;
145: case SDLK_RIGHTBRACKET: return AK_RBRACKET;
146: case SDLK_COMMA: return AK_M;
147: case SDLK_LESS:
148: case SDLK_GREATER: return AK_LTGT;
149: case SDLK_PERIOD:
150: case SDLK_SEMICOLON: return AK_COMMA;
151: case SDLK_RIGHTPAREN: return AK_MINUS;
152: case SDLK_EQUALS: return AK_SLASH;
153: case SDLK_HASH: return AK_NUMBERSIGN;
154: case SDLK_SLASH: return AK_PERIOD;
155: case SDLK_MINUS: return AK_EQUAL;
156: case SDLK_BACKSLASH: return AK_BACKSLASH;
157: default: return -1;
158: }
159: }
160:
161: /*
162: * Handle keys specific to US keymaps.
163: */
164: static int decode_us (int keysym)
165: {
166: switch (keysym) {
167: case SDLK_a: return AK_A;
168: case SDLK_m: return AK_M;
169: case SDLK_q: return AK_Q;
170: case SDLK_y: return AK_Y;
171: case SDLK_w: return AK_W;
172: case SDLK_z: return AK_Z;
173: case SDLK_LEFTBRACKET: return AK_LBRACKET;
174: case SDLK_RIGHTBRACKET: return AK_RBRACKET;
175: case SDLK_COMMA: return AK_COMMA;
176: case SDLK_PERIOD: return AK_PERIOD;
177: case SDLK_SLASH: return AK_SLASH;
178: case SDLK_SEMICOLON: return AK_SEMICOLON;
179: case SDLK_MINUS: return AK_MINUS;
180: case SDLK_EQUALS: return AK_EQUAL;
181: case SDLK_QUOTE: return AK_QUOTE;
182: case SDLK_BACKQUOTE: return AK_BACKQUOTE;
183: case SDLK_BACKSLASH: return AK_BACKSLASH;
184: default: return -1;
185: }
186: }
187:
188: /*
189: * Handle keys specific to German keymaps.
190: */
191: static int decode_de (int keysym)
192: {
193: switch (keysym) {
194: case SDLK_a: return AK_A;
195: case SDLK_m: return AK_M;
196: case SDLK_q: return AK_Q;
197: case SDLK_w: return AK_W;
198: case SDLK_y: return AK_Z;
199: case SDLK_z: return AK_Y;
200: /* German umlaut oe */
201: case SDLK_WORLD_86: return AK_SEMICOLON;
202: /* German umlaut ae */
203: case SDLK_WORLD_68: return AK_QUOTE;
204: /* German umlaut ue */
205: case SDLK_WORLD_92: return AK_LBRACKET;
206: case SDLK_PLUS:
207: case SDLK_ASTERISK: return AK_RBRACKET;
208: case SDLK_COMMA: return AK_COMMA;
209: case SDLK_PERIOD: return AK_PERIOD;
210: case SDLK_LESS:
211: case SDLK_GREATER: return AK_LTGT;
212: case SDLK_HASH: return AK_NUMBERSIGN;
213: /* German sharp s */
214: case SDLK_WORLD_63: return AK_MINUS;
215: case SDLK_QUOTE: return AK_EQUAL;
216: case SDLK_CARET: return AK_BACKQUOTE;
217: case SDLK_MINUS: return AK_SLASH;
218: default: return -1;
219: }
220: }
221:
222: /*
223: * Handle keys specific to Danish keymaps.
224: *
225: * Incomplete. SDL (up to 1.2.6 at least) doesn't define
226: * enough keysms for a complete Danish mapping.
227: * Missing dead-key support for diaeresis, acute and circumflex
228: */
229: static int decode_dk (int keysym)
230: {
231: switch (keysym) {
232: case SDLK_a: return AK_A;
233: case SDLK_m: return AK_M;
234: case SDLK_q: return AK_Q;
235: case SDLK_w: return AK_W;
236: case SDLK_y: return AK_Y;
237: case SDLK_z: return AK_Z;
238: /* Danish AE */
239: case SDLK_WORLD_88: return AK_SEMICOLON;
240: /* Danish o oblique */
241: case SDLK_WORLD_68: return AK_QUOTE;
242: /* Danish A ring */
243: case SDLK_WORLD_69: return AK_LBRACKET;
244: /* one half - SDL has no 'section'? */
245: case SDLK_WORLD_70: return AK_BACKQUOTE;
246: case SDLK_COMMA: return AK_COMMA;
247: case SDLK_PERIOD: return AK_PERIOD;
248: case SDLK_LESS:
249: case SDLK_GREATER: return AK_LTGT;
250: case SDLK_HASH: return AK_NUMBERSIGN;
251: case SDLK_PLUS: return AK_MINUS;
252: case SDLK_MINUS: return AK_SLASH;
253: default: return -1;
254: }
255: }
256:
257: /*
258: * Handle keys specific to SE keymaps.
259: */
260: static int decode_se (int keysym)
261: {
262: switch (keysym) {
263: case SDLK_a: return AK_A;
264: case SDLK_m: return AK_M;
265: case SDLK_q: return AK_Q;
266: case SDLK_w: return AK_W;
267: case SDLK_y: return AK_Y;
268: case SDLK_z: return AK_Z;
269: case SDLK_WORLD_86: return AK_SEMICOLON;
270: case SDLK_WORLD_68: return AK_QUOTE;
271: case SDLK_WORLD_69: return AK_LBRACKET;
272: case SDLK_COMMA: return AK_COMMA;
273: case SDLK_PERIOD: return AK_PERIOD;
274: case SDLK_MINUS: return AK_SLASH;
275: case SDLK_LESS:
276: case SDLK_GREATER: return AK_LTGT;
277: case SDLK_PLUS:
278: case SDLK_QUESTION: return AK_EQUAL;
279: case SDLK_AT:
280: case SDLK_WORLD_29: return AK_BACKQUOTE;
281: case SDLK_CARET: return AK_RBRACKET;
282: case SDLK_BACKSLASH: return AK_MINUS;
283: case SDLK_HASH: return AK_NUMBERSIGN;
284: default: return -1;
285: }
286: }
287:
288: /*
289: * Handle keys specific to Italian keymaps.
290: */
291: static int decode_it (int keysym)
292: {
293: switch (keysym) {
294: case SDLK_a: return AK_A;
295: case SDLK_m: return AK_M;
296: case SDLK_q: return AK_Q;
297: case SDLK_w: return AK_W;
298: case SDLK_y: return AK_Y;
299: case SDLK_z: return AK_Z;
300: case SDLK_WORLD_82: return AK_SEMICOLON;
301: case SDLK_WORLD_64: return AK_QUOTE;
302: case SDLK_WORLD_72: return AK_LBRACKET;
303: case SDLK_PLUS:
304: case SDLK_ASTERISK: return AK_RBRACKET;
305: case SDLK_COMMA: return AK_COMMA;
306: case SDLK_PERIOD: return AK_PERIOD;
307: case SDLK_LESS:
308: case SDLK_GREATER: return AK_LTGT;
309: case SDLK_BACKSLASH: return AK_BACKQUOTE;
310: case SDLK_QUOTE: return AK_MINUS;
311: case SDLK_WORLD_76: return AK_EQUAL;
312: case SDLK_MINUS: return AK_SLASH;
313: case SDLK_HASH: return AK_NUMBERSIGN;
314: default: return -1;
315: }
316: }
317:
318: /*
319: * Handle keys specific to Spanish keymaps.
320: */
321: static int decode_es (int keysym)
322: {
323: switch (keysym) {
324: case SDLK_a: return AK_A;
325: case SDLK_m: return AK_M;
326: case SDLK_q: return AK_Q;
327: case SDLK_w: return AK_W;
328: case SDLK_y: return AK_Y;
329: case SDLK_z: return AK_Z;
330: case SDLK_WORLD_81: return AK_SEMICOLON;
331: case SDLK_PLUS:
332: case SDLK_ASTERISK: return AK_RBRACKET;
333: case SDLK_COMMA: return AK_COMMA;
334: case SDLK_PERIOD: return AK_PERIOD;
335: case SDLK_LESS:
336: case SDLK_GREATER: return AK_LTGT;
337: case SDLK_BACKSLASH: return AK_BACKQUOTE;
338: case SDLK_QUOTE: return AK_MINUS;
339: case SDLK_WORLD_76: return AK_EQUAL;
340: case SDLK_MINUS: return AK_SLASH;
341: case SDLK_HASH: return AK_NUMBERSIGN;
342: default: return -1;
343: }
344: }
345:
346: int keysym2amiga (int keysym)
347: {
348: int amiga_keycode = kc_decode (keysym);
349:
350: if (amiga_keycode == -1) {
351: switch (currprefs.keyboard_lang) {
352: case KBD_LANG_FR:
353: amiga_keycode = decode_fr (keysym); break;
354: case KBD_LANG_US:
355: amiga_keycode = decode_us (keysym); break;
356: case KBD_LANG_DE:
357: amiga_keycode = decode_de (keysym); break;
358: case KBD_LANG_DK:
359: amiga_keycode = decode_dk (keysym); break;
360: case KBD_LANG_SE:
361: amiga_keycode = decode_se (keysym); break;
362: case KBD_LANG_IT:
363: amiga_keycode = decode_it (keysym); break;
364: case KBD_LANG_ES:
365: amiga_keycode = decode_es (keysym); break;
366: }
367: }
368: return amiga_keycode;
369: }
370:
371:
372: /*
373: * Default hotkeys
374: *
375: * We need a better way of doing this. ;-)
376: */
377: static struct uae_hotkeyseq sdl_hotkeys[] =
378: {
379: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_q, -1, -1, INPUTEVENT_SPC_QUIT) },
380: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_r, -1, -1, INPUTEVENT_SPC_SOFTRESET) },
381: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_LSHIFT, SDLK_r, -1, INPUTEVENT_SPC_HARDRESET)}, \
382: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_d, -1, -1, INPUTEVENT_SPC_ENTERDEBUGGER)}, \
383: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_s, -1, -1, INPUTEVENT_SPC_TOGGLEFULLSCREEN) },
384: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_g, -1, -1, INPUTEVENT_SPC_TOGGLEMOUSEGRAB) },
385: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_i, -1, -1, INPUTEVENT_SPC_INHIBITSCREEN) },
386: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_p, -1, -1, INPUTEVENT_SPC_SCREENSHOT) },
387: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_a, -1, -1, INPUTEVENT_SPC_SWITCHINTERPOL) },
388: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_KP_PLUS, -1, -1, INPUTEVENT_SPC_INCREASE_REFRESHRATE) },
389: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_KP_MINUS, -1, -1, INPUTEVENT_SPC_DECREASE_REFRESHRATE) },
390: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_F1, -1, -1, INPUTEVENT_SPC_FLOPPY0) },
391: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_F2, -1, -1, INPUTEVENT_SPC_FLOPPY1) },
392: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_F3, -1, -1, INPUTEVENT_SPC_FLOPPY2) },
393: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_F4, -1, -1, INPUTEVENT_SPC_FLOPPY3) },
394: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_LSHIFT, SDLK_F1, -1, INPUTEVENT_SPC_EFLOPPY0) },
395: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_LSHIFT, SDLK_F2, -1, INPUTEVENT_SPC_EFLOPPY1) },
396: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_LSHIFT, SDLK_F3, -1, INPUTEVENT_SPC_EFLOPPY2) },
397: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_LSHIFT, SDLK_F4, -1, INPUTEVENT_SPC_EFLOPPY3) },
398: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_RETURN, -1, -1, INPUTEVENT_SPC_ENTERGUI) },
399: { MAKE_HOTKEYSEQ (SDLK_F12, SDLK_f, -1, -1, INPUTEVENT_SPC_FREEZEBUTTON) },
400: { HOTKEYS_END }
401: };
402:
403: /* Hotkeys for OS X
404: * The F12 key doesn't seem to work under MacOS X (at least on the two systems
405: * I've tried): key up/down events are only generated when the key is released,
406: * so it's no use as a hot-key modifier. Use F11 instead.
407: */
408: static struct uae_hotkeyseq sdl_quartz_hotkeys[] =
409: {
410: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_q, -1, -1, INPUTEVENT_SPC_QUIT) },
411: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_r, -1, -1, INPUTEVENT_SPC_SOFTRESET) },
412: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_LSHIFT, SDLK_r, -1, INPUTEVENT_SPC_HARDRESET) },
413: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_d, -1, -1, INPUTEVENT_SPC_ENTERDEBUGGER) },
414: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_s, -1, -1, INPUTEVENT_SPC_TOGGLEFULLSCREEN) },
415: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_g, -1, -1, INPUTEVENT_SPC_TOGGLEMOUSEGRAB) },
416: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_i, -1, -1, INPUTEVENT_SPC_INHIBITSCREEN) },
417: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_p, -1, -1, INPUTEVENT_SPC_SCREENSHOT) },
418: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_a, -1, -1, INPUTEVENT_SPC_SWITCHINTERPOL) },
419: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_KP_PLUS, -1, -1, INPUTEVENT_SPC_INCREASE_REFRESHRATE) },
420: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_KP_MINUS, -1, -1, INPUTEVENT_SPC_DECREASE_REFRESHRATE) },
421: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_F1, -1, -1, INPUTEVENT_SPC_FLOPPY0) },
422: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_F2, -1, -1, INPUTEVENT_SPC_FLOPPY1) },
423: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_F3, -1, -1, INPUTEVENT_SPC_FLOPPY2) },
424: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_F4, -1, -1, INPUTEVENT_SPC_FLOPPY3) },
425: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_LSHIFT, SDLK_F1, -1, INPUTEVENT_SPC_EFLOPPY0) },
426: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_LSHIFT, SDLK_F2, -1, INPUTEVENT_SPC_EFLOPPY1) },
427: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_LSHIFT, SDLK_F3, -1, INPUTEVENT_SPC_EFLOPPY2) },
428: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_LSHIFT, SDLK_F4, -1, INPUTEVENT_SPC_EFLOPPY3) },
429: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_RETURN, -1, -1, INPUTEVENT_SPC_ENTERGUI) },
430: { MAKE_HOTKEYSEQ (SDLK_F11, SDLK_f, -1, -1, INPUTEVENT_SPC_FREEZEBUTTON) },
431: { HOTKEYS_END }
432: };
433:
434: struct uae_hotkeyseq *get_default_cooked_hotkeys (void)
435: {
436: if (get_sdlgfx_type() == SDLGFX_DRIVER_QUARTZ)
437: return sdl_quartz_hotkeys;
438: else
439: return sdl_hotkeys;
440: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.