|
|
1.1 root 1: /*
2: Hatari - keymap.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: Here we process a key press and the remapping of the scancodes.
8: */
9: const char Keymap_fileid[] = "Hatari keymap.c : " __DATE__ " " __TIME__;
10:
11: #include <ctype.h>
12: #include "main.h"
13: #include "keymap.h"
14: #include "configuration.h"
15: #include "file.h"
16: #include "shortcut.h"
17: #include "str.h"
18: #include "screen.h"
19: #include "debugui.h"
20: #include "log.h"
21: #include "kms.h"
22:
23: #include "SDL.h"
24:
25:
26: #define LOG_KEYMAP_LEVEL LOG_DEBUG
27:
28: Uint8 modifiers = 0;
29: bool capslock = false;
30:
31:
32: void Keymap_Init(void) {
33:
34: }
35:
36:
37: /* This function translates the scancodes provided by SDL to
38: * NeXT scancode values.
39: */
40:
41: static Uint8 Keymap_GetKeyFromScancode(SDL_Scancode sdlscancode) {
42: Log_Printf(LOG_KEYMAP_LEVEL, "[Keymap] Scancode: %i (%s)\n", sdlscancode, SDL_GetScancodeName(sdlscancode));
43:
44: switch (sdlscancode) {
45: case SDL_SCANCODE_ESCAPE: return 0x49;
46: case SDL_SCANCODE_1: return 0x4a;
47: case SDL_SCANCODE_2: return 0x4b;
48: case SDL_SCANCODE_3: return 0x4c;
49: case SDL_SCANCODE_4: return 0x4d;
50: case SDL_SCANCODE_5: return 0x50;
51: case SDL_SCANCODE_6: return 0x4f;
52: case SDL_SCANCODE_7: return 0x4e;
53: case SDL_SCANCODE_8: return 0x1e;
54: case SDL_SCANCODE_9: return 0x1f;
55: case SDL_SCANCODE_0: return 0x20;
56: case SDL_SCANCODE_MINUS: return 0x1d;
57: case SDL_SCANCODE_EQUALS: return 0x1c;
58: case SDL_SCANCODE_BACKSPACE: return 0x1b;
59:
60: case SDL_SCANCODE_TAB: return 0x41;
61: case SDL_SCANCODE_Q: return 0x42;
62: case SDL_SCANCODE_W: return 0x43;
63: case SDL_SCANCODE_E: return 0x44;
64: case SDL_SCANCODE_R: return 0x45;
65: case SDL_SCANCODE_T: return 0x48;
66: case SDL_SCANCODE_Y: return 0x47;
67: case SDL_SCANCODE_U: return 0x46;
68: case SDL_SCANCODE_I: return 0x06;
69: case SDL_SCANCODE_O: return 0x07;
70: case SDL_SCANCODE_P: return 0x08;
71: case SDL_SCANCODE_LEFTBRACKET: return 0x05;
72: case SDL_SCANCODE_RIGHTBRACKET: return 0x04;
73: case SDL_SCANCODE_BACKSLASH: return 0x03;
74:
75: case SDL_SCANCODE_A: return 0x39;
76: case SDL_SCANCODE_S: return 0x3a;
77: case SDL_SCANCODE_D: return 0x3b;
78: case SDL_SCANCODE_F: return 0x3c;
79: case SDL_SCANCODE_G: return 0x3d;
80: case SDL_SCANCODE_H: return 0x40;
81: case SDL_SCANCODE_J: return 0x3f;
82: case SDL_SCANCODE_K: return 0x3e;
83: case SDL_SCANCODE_L: return 0x2d;
84: case SDL_SCANCODE_SEMICOLON: return 0x2c;
85: case SDL_SCANCODE_APOSTROPHE: return 0x2b;
86: case SDL_SCANCODE_RETURN: return 0x2a;
87:
88: case SDL_SCANCODE_Z: return 0x31;
89: case SDL_SCANCODE_X: return 0x32;
90: case SDL_SCANCODE_C: return 0x33;
91: case SDL_SCANCODE_V: return 0x34;
92: case SDL_SCANCODE_B: return 0x35;
93: case SDL_SCANCODE_N: return 0x37;
94: case SDL_SCANCODE_M: return 0x36;
95: case SDL_SCANCODE_COMMA: return 0x2e;
96: case SDL_SCANCODE_PERIOD: return 0x2f;
97: case SDL_SCANCODE_SLASH: return 0x30;
98: case SDL_SCANCODE_SPACE: return 0x38;
99:
100: case SDL_SCANCODE_GRAVE:
101: case SDL_SCANCODE_NUMLOCKCLEAR: return 0x26;
102: case SDL_SCANCODE_KP_EQUALS: return 0x27;
103: case SDL_SCANCODE_KP_DIVIDE: return 0x28;
104: case SDL_SCANCODE_KP_MULTIPLY: return 0x25;
105: case SDL_SCANCODE_KP_7: return 0x21;
106: case SDL_SCANCODE_KP_8: return 0x22;
107: case SDL_SCANCODE_KP_9: return 0x23;
108: case SDL_SCANCODE_KP_MINUS: return 0x24;
109: case SDL_SCANCODE_KP_4: return 0x12;
110: case SDL_SCANCODE_KP_5: return 0x18;
111: case SDL_SCANCODE_KP_6: return 0x13;
112: case SDL_SCANCODE_KP_PLUS: return 0x15;
113: case SDL_SCANCODE_KP_1: return 0x11;
114: case SDL_SCANCODE_KP_2: return 0x17;
115: case SDL_SCANCODE_KP_3: return 0x14;
116: case SDL_SCANCODE_KP_0: return 0x0b;
117: case SDL_SCANCODE_KP_PERIOD: return 0x0c;
118: case SDL_SCANCODE_KP_ENTER: return 0x0d;
119:
120: case SDL_SCANCODE_LEFT: return 0x09;
121: case SDL_SCANCODE_RIGHT: return 0x10;
122: case SDL_SCANCODE_UP: return 0x16;
123: case SDL_SCANCODE_DOWN: return 0x0f;
124:
125: /* Special keys */
126: case SDL_SCANCODE_F10:
127: case SDL_SCANCODE_DELETE: return 0x58; /* Power */
128: case SDL_SCANCODE_F5:
129: case SDL_SCANCODE_END: return 0x02; /* Sound down */
130: case SDL_SCANCODE_F6:
131: case SDL_SCANCODE_HOME: return 0x1a; /* Sound up */
132: case SDL_SCANCODE_F1:
133: case SDL_SCANCODE_PAGEDOWN: return 0x01; /* Brightness down */
134: case SDL_SCANCODE_F2:
135: case SDL_SCANCODE_PAGEUP: return 0x19; /* Brightness up */
136:
137: default: return 0x00;
138: }
139: }
140:
141:
142: /* These functions translate the scancodes provided by SDL to
143: * NeXT modifier bits.
144: */
145:
146: static Uint8 Keymap_Keydown_GetModFromScancode(SDL_Scancode sdlscancode) {
147: switch (sdlscancode) {
148: case SDL_SCANCODE_LCTRL:
149: case SDL_SCANCODE_RCTRL:
150: modifiers|=0x01;
151: break;
152: case SDL_SCANCODE_LSHIFT:
153: modifiers|=0x02;
154: break;
155: case SDL_SCANCODE_RSHIFT:
156: modifiers|=0x04;
157: break;
158: case SDL_SCANCODE_LGUI:
159: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x20:0x08;
160: break;
161: case SDL_SCANCODE_RGUI:
162: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x40:0x10;
163: break;
164: case SDL_SCANCODE_LALT:
165: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x08:0x20;
166: break;
167: case SDL_SCANCODE_RALT:
168: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x10:0x40;
169: break;
170: case SDL_SCANCODE_CAPSLOCK:
171: capslock=capslock?false:true;
172: break;
173: default:
174: break;
175: }
176:
177: return modifiers|(capslock?0x02:0x00);
178: }
179:
180: static Uint8 Keymap_Keyup_GetModFromScancode(SDL_Scancode sdlscancode) {
181:
182: switch (sdlscancode) {
183: case SDL_SCANCODE_LCTRL:
184: case SDL_SCANCODE_RCTRL:
185: modifiers&=~0x01;
186: break;
187: case SDL_SCANCODE_LSHIFT:
188: modifiers&=~0x02;
189: break;
190: case SDL_SCANCODE_RSHIFT:
191: modifiers&=~0x04;
192: break;
193: case SDL_SCANCODE_LGUI:
194: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x20:0x08);
195: break;
196: case SDL_SCANCODE_RGUI:
197: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x40:0x10);
198: break;
199: case SDL_SCANCODE_LALT:
200: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x08:0x20);
201: break;
202: case SDL_SCANCODE_RALT:
203: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x10:0x40);
204: break;
205: case SDL_SCANCODE_CAPSLOCK:
206: //capslock=false;
207: break;
208: default:
209: break;
210: }
211:
212: return modifiers|(capslock?0x02:0x00);
213: }
214:
215:
216: /* This function translates the key symbols provided by SDL to
217: * NeXT scancode values.
218: */
219:
220: static Uint8 Keymap_GetKeyFromSymbol(SDL_Keycode sdlkey) {
221: Log_Printf(LOG_KEYMAP_LEVEL, "[Keymap] Symkey: %s\n", SDL_GetKeyName(sdlkey));
222:
223: switch (sdlkey) {
224: case SDLK_BACKSLASH: return 0x03;
225: case SDLK_RIGHTBRACKET: return 0x04;
226: case SDLK_LEFTBRACKET: return 0x05;
227: case SDLK_i: return 0x06;
228: case SDLK_o: return 0x07;
229: case SDLK_p: return 0x08;
230: case SDLK_LEFT: return 0x09;
231: case SDLK_KP_0: return 0x0B;
232: case SDLK_KP_PERIOD: return 0x0C;
233: case SDLK_KP_ENTER: return 0x0D;
234: case SDLK_DOWN: return 0x0F;
235: case SDLK_RIGHT: return 0x10;
236: case SDLK_KP_1: return 0x11;
237: case SDLK_KP_4: return 0x12;
238: case SDLK_KP_6: return 0x13;
239: case SDLK_KP_3: return 0x14;
240: case SDLK_KP_PLUS: return 0x15;
241: case SDLK_UP: return 0x16;
242: case SDLK_KP_2: return 0x17;
243: case SDLK_KP_5: return 0x18;
244: case SDLK_BACKSPACE: return 0x1B;
245: case SDLK_EQUALS: return 0x1C;
246: case SDLK_MINUS: return 0x1D;
247: case SDLK_8: return 0x1E;
248: case SDLK_9: return 0x1F;
249: case SDLK_0: return 0x20;
250: case SDLK_KP_7: return 0x21;
251: case SDLK_KP_8: return 0x22;
252: case SDLK_KP_9: return 0x23;
253: case SDLK_KP_MINUS: return 0x24;
254: case SDLK_KP_MULTIPLY: return 0x25;
255: case SDLK_BACKQUOTE: return 0x26;
256: case SDLK_KP_EQUALS: return 0x27;
257: case SDLK_KP_DIVIDE: return 0x28;
258: case SDLK_RETURN: return 0x2A;
259: case SDLK_QUOTE: return 0x2B;
260: case SDLK_SEMICOLON: return 0x2C;
261: case SDLK_l: return 0x2D;
262: case SDLK_COMMA: return 0x2E;
263: case SDLK_PERIOD: return 0x2F;
264: case SDLK_SLASH: return 0x30;
265: case SDLK_z: return 0x31;
266: case SDLK_x: return 0x32;
267: case SDLK_c: return 0x33;
268: case SDLK_v: return 0x34;
269: case SDLK_b: return 0x35;
270: case SDLK_m: return 0x36;
271: case SDLK_n: return 0x37;
272: case SDLK_SPACE: return 0x38;
273: case SDLK_a: return 0x39;
274: case SDLK_s: return 0x3A;
275: case SDLK_d: return 0x3B;
276: case SDLK_f: return 0x3C;
277: case SDLK_g: return 0x3D;
278: case SDLK_k: return 0x3E;
279: case SDLK_j: return 0x3F;
280: case SDLK_h: return 0x40;
281: case SDLK_TAB: return 0x41;
282: case SDLK_q: return 0x42;
283: case SDLK_w: return 0x43;
284: case SDLK_e: return 0x44;
285: case SDLK_r: return 0x45;
286: case SDLK_u: return 0x46;
287: case SDLK_y: return 0x47;
288: case SDLK_t: return 0x48;
289: case SDLK_ESCAPE: return 0x49;
290: case SDLK_1: return 0x4A;
291: case SDLK_2: return 0x4B;
292: case SDLK_3: return 0x4C;
293: case SDLK_4: return 0x4D;
294: case SDLK_7: return 0x4E;
295: case SDLK_6: return 0x4F;
296: case SDLK_5: return 0x50;
297:
298: /* Special Keys */
299: case SDLK_F10:
300: case SDLK_DELETE: return 0x58; /* Power */
301: case SDLK_F5:
302: case SDLK_END: return 0x02; /* Sound down */
303: case SDLK_F6:
304: case SDLK_HOME: return 0x1a; /* Sound up */
305: case SDLK_F1:
306: case SDLK_PAGEDOWN: return 0x01; /* Brightness down */
307: case SDLK_F2:
308: case SDLK_PAGEUP: return 0x19; /* Brightness up */
309:
310:
311: default: return 0x00;
312: break;
313: }
314: }
315:
316:
317: /* These functions translate the key symbols provided by SDL to
318: * NeXT modifier bits.
319: */
320:
321: static Uint8 Keymap_Keydown_GetModFromSymbol(SDL_Keycode sdl_modifier) {
322:
323: switch (sdl_modifier) {
324: case SDLK_LCTRL:
325: case SDLK_RCTRL:
326: modifiers|=0x01;
327: break;
328: case SDLK_LSHIFT:
329: modifiers|=0x02;
330: break;
331: case SDLK_RSHIFT:
332: modifiers|=0x04;
333: break;
334: case SDLK_LGUI:
335: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x20:0x08;
336: break;
337: case SDLK_RGUI:
338: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x40:0x10;
339: break;
340: case SDLK_LALT:
341: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x08:0x20;
342: break;
343: case SDLK_RALT:
344: modifiers|=ConfigureParams.Keyboard.bSwapCmdAlt?0x10:0x40;
345: break;
346: case SDLK_CAPSLOCK:
347: capslock=capslock?false:true;
348: break;
349: default:
350: break;
351: }
352:
353: return modifiers|(capslock?0x02:0x00);
354: }
355:
356: static Uint8 Keymap_Keyup_GetModFromSymbol(SDL_Keycode sdl_modifier) {
357:
358: switch (sdl_modifier) {
359: case SDLK_LCTRL:
360: case SDLK_RCTRL:
361: modifiers&=~0x01;
362: break;
363: case SDLK_LSHIFT:
364: modifiers&=~0x02;
365: break;
366: case SDLK_RSHIFT:
367: modifiers&=~0x04;
368: break;
369: case SDLK_LGUI:
370: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x20:0x08);
371: break;
372: case SDLK_RGUI:
373: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x40:0x10);
374: break;
375: case SDLK_LALT:
376: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x08:0x20);
377: break;
378: case SDLK_RALT:
379: modifiers&=~(ConfigureParams.Keyboard.bSwapCmdAlt?0x10:0x40);
380: break;
381: case SDLK_CAPSLOCK:
382: //capslock=false;
383: break;
384: default:
385: break;
386: }
387:
388: return modifiers|(capslock?0x02:0x00);
389: }
390:
391:
392: /*-----------------------------------------------------------------------*/
393: /**
394: * Mouse wheel mapped to cursor keys (currently disabled)
395: */
396:
397: static bool pendingX = true;
398: static bool pendingY = true;
399:
400: static void post_key_event(int sym, int scan) {
401: SDL_Event sdlevent;
402: sdlevent.type = SDL_KEYDOWN;
403: sdlevent.key.keysym.sym = sym;
404: sdlevent.key.keysym.scancode = scan;
405: SDL_PushEvent(&sdlevent);
406: sdlevent.type = SDL_KEYUP;
407: sdlevent.key.keysym.sym = sym;
408: sdlevent.key.keysym.scancode = scan;
409: SDL_PushEvent(&sdlevent);
410: }
411:
412: void Keymap_MouseWheel(SDL_MouseWheelEvent* event) {
413: if(!(pendingX)) {
414: pendingX = true;
415: if (event->x > 0) post_key_event(SDLK_LEFT, SDL_SCANCODE_LEFT);
416: else if(event->x < 0) post_key_event(SDLK_RIGHT, SDL_SCANCODE_RIGHT);
417: }
418:
419: if(!(pendingY)) {
420: pendingY = true;
421: if (event->y < 0) post_key_event(SDLK_UP, SDL_SCANCODE_UP);
422: else if(event->y > 0) post_key_event(SDLK_DOWN, SDL_SCANCODE_DOWN);
423: }
424: }
425:
426:
427: /*-----------------------------------------------------------------------*/
428: /**
429: * User pressed key down
430: */
431: void Keymap_KeyDown(SDL_Keysym *sdlkey)
432: {
433: Uint8 next_mod, next_key;
434:
435: if (ShortCut_CheckKeys(sdlkey->mod, sdlkey->sym, 1)) { // Check if we pressed a shortcut
436: ShortCut_ActKey();
437: return;
438: }
439:
440: if (ConfigureParams.Keyboard.nKeymapType==KEYMAP_SYMBOLIC) {
441: next_key = Keymap_GetKeyFromSymbol(sdlkey->sym);
442: next_mod = Keymap_Keydown_GetModFromSymbol(sdlkey->sym);
443: } else {
444: next_key = Keymap_GetKeyFromScancode(sdlkey->scancode);
445: next_mod = Keymap_Keydown_GetModFromScancode(sdlkey->scancode);
446: }
447:
448: Log_Printf(LOG_KEYMAP_LEVEL, "[Keymap] NeXT Keycode: $%02x, Modifiers: $%02x\n", next_key, next_mod);
449:
450: kms_keydown(next_mod, next_key);
451: }
452:
453:
454: /*-----------------------------------------------------------------------*/
455: /**
456: * User released key
457: */
458: void Keymap_KeyUp(SDL_Keysym *sdlkey) {
459: Uint8 next_mod, next_key;
460:
461: if (ShortCut_CheckKeys(sdlkey->mod, sdlkey->sym, 0))
462: return;
463:
464: if (ConfigureParams.Keyboard.nKeymapType==KEYMAP_SYMBOLIC) {
465: next_key = Keymap_GetKeyFromSymbol(sdlkey->sym);
466: next_mod = Keymap_Keyup_GetModFromSymbol(sdlkey->sym);
467: } else {
468: next_key = Keymap_GetKeyFromScancode(sdlkey->scancode);
469: next_mod = Keymap_Keyup_GetModFromScancode(sdlkey->scancode);
470: }
471:
472: Log_Printf(LOG_KEYMAP_LEVEL, "[Keymap] NeXT Keycode: $%02x, Modifiers: $%02x\n", next_key, next_mod);
473:
474: kms_keyup(next_mod, next_key);
475: }
476:
477: /*-----------------------------------------------------------------------*/
478: /**
479: * Simulate press or release of a key corresponding to given character
480: */
481: void Keymap_SimulateCharacter(char asckey, bool press)
482: {
483: SDL_Keysym sdlkey;
484:
485: sdlkey.mod = KMOD_NONE;
486: sdlkey.scancode = 0;
487: if (isupper(asckey)) {
488: if (press) {
489: sdlkey.sym = SDLK_LSHIFT;
490: Keymap_KeyDown(&sdlkey);
491: }
492: sdlkey.sym = tolower(asckey);
493: sdlkey.mod = KMOD_LSHIFT;
494: } else {
495: sdlkey.sym = asckey;
496: }
497: if (press) {
498: Keymap_KeyDown(&sdlkey);
499: } else {
500: Keymap_KeyUp(&sdlkey);
501: if (isupper(asckey)) {
502: sdlkey.sym = SDLK_LSHIFT;
503: Keymap_KeyUp(&sdlkey);
504: }
505: }
506: }
507:
508:
509: /*-----------------------------------------------------------------------*/
510: /**
511: * User moved mouse
512: */
513: void Keymap_MouseMove(int dx, int dy, float lin, float exp)
514: {
515: static bool s_left=false;
516: static bool s_up=false;
517: static float s_fdx=0.0;
518: static float s_fdy=0.0;
519:
520: bool left=false;
521: bool up=false;
522: float fdx;
523: float fdy;
524:
525: if ((dx!=0) || (dy!=0)) {
526: /* Remove the sign */
527: if (dx<0) {
528: dx=-dx;
529: left=true;
530: }
531: if (dy<0) {
532: dy=-dy;
533: up=true;
534: }
535:
536: /* Exponential adjustmend */
537: fdx = pow(dx, exp);
538: fdy = pow(dy, exp);
539:
540: /* Linear adjustment */
541: fdx *= lin;
542: fdy *= lin;
543:
544: /* Add residuals */
545: if (left==s_left) {
546: s_fdx+=fdx;
547: } else {
548: s_fdx=fdx;
549: s_left=left;
550: }
551: if (up==s_up) {
552: s_fdy+=fdy;
553: } else {
554: s_fdy=fdy;
555: s_up=up;
556: }
557:
558: /* Convert to integer and save residuals */
559: dx=s_fdx;
560: s_fdx-=dx;
561: dy=s_fdy;
562: s_fdy-=dy;
563: //printf("adjusted: dx=%i, dy=%i\n",dx,dy);
564: kms_mouse_move(dx, left, dy, up);
565: }
566: }
567:
568: /*-----------------------------------------------------------------------*/
569: /**
570: * User pressed mouse button
571: */
572: void Keymap_MouseDown(bool left)
573: {
574: kms_mouse_button(left,true);
575: }
576:
577: /*-----------------------------------------------------------------------*/
578: /**
579: * User released mouse button
580: */
581: void Keymap_MouseUp(bool left)
582: {
583: kms_mouse_button(left,false);
584: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.