|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Additional Win32 helper functions not calling any system routines
5: *
6: * (c) 1997 Mathias Ortmann
1.1.1.2 ! root 7: * (c) 1999-2001 Brian King
! 8: * (c) 2000-2001 Bernd Roesch
1.1 root 9: */
10:
11: #include "config.h"
12: #include "sysconfig.h"
13:
14: #include <assert.h>
15: #include <ctype.h>
16: #include <signal.h>
17: #include <windows.h>
18:
19: #include "sysdeps.h"
20: #include "uae.h"
21: #include "options.h"
1.1.1.2 ! root 22: #include "memory.h"
1.1 root 23: #include "custom.h"
24: #include "newcpu.h"
25: #include "keyboard.h"
26: #include "xwin.h"
1.1.1.2 ! root 27: #include "drawing.h"
1.1 root 28: #include "disk.h"
29: #include "keybuf.h"
30: #include "gui.h"
1.1.1.2 ! root 31: #include "osdep/win32.h"
! 32: #include "osdep/win32gui.h"
! 33: #include "debug.h"
! 34:
! 35: //#define DBG_KEYBD 1
! 36: static int keystate[AK_RCTRL+1];
! 37: static HKL keyboardlayoutid;
! 38: static WORD keyboardlangid;
1.1 root 39:
40: static int helppressed (void)
41: {
42: return GetAsyncKeyState (VK_END) & 0x8000;
43: }
44:
45: static int shiftpressed (void)
46: {
47: return GetAsyncKeyState (VK_SHIFT) & 0x8000 ? 1 : 0;
48: }
49:
50: static int getcapslock (void)
51: {
52: BYTE keyState[256];
1.1.1.2 ! root 53: #ifdef _WIN32_WCE
! 54: return( GetKeyState( VK_CAPITAL ) & 1 );
! 55: #else
1.1 root 56: GetKeyboardState (keyState);
57: return keyState[VK_CAPITAL] & 1;
1.1.1.2 ! root 58: #endif
1.1 root 59: }
60:
1.1.1.2 ! root 61: static char getascii( UINT vk, UINT scancode )
! 62: {
! 63: BYTE keyState[256];
! 64: char buffer[2];
! 65: int result;
! 66: #ifndef _WIN32_WCE
! 67: GetKeyboardState (keyState);
! 68: result = ToAscii( vk, scancode, keyState, (LPWORD)buffer, 0 );
! 69: if( result == 1 )
! 70: result = buffer[0];
! 71: #endif
! 72: return result;
! 73: }
1.1 root 74:
75: /* there's a problem remaining with the semantics of the '#' key on U.S. keyboards */
76: static int scancode2amiga (int keycode, int scancode)
77: {
1.1.1.2 ! root 78: static int firstscan=0;
! 79: if (!firstscan)
! 80: {
! 81: keyboardlayoutid=GetKeyboardLayout(0);
! 82: keyboardlangid=LOWORD(keyboardlayoutid);
! 83: firstscan=1;
! 84: }
! 85: #if DEBUG_KBD
! 86: write_log( "keycode = 0x%x, scancode = 0x%x\n", keycode, scancode );
! 87: #endif
! 88:
! 89: if(keyboardlangid==MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN))
! 90: {
! 91: if (keystate[AK_CTRL] &&
! 92: keystate[AK_RALT])
! 93: {
! 94: switch (keycode & 0xff)
! 95: {
! 96: case 0xdb:
! 97: return AK_BACKSLASH;
! 98: case 0x51: //@
! 99: record_key ((AK_CTRL << 1)+1);
! 100: return 0x10;
! 101: case 0xbb: //~
! 102: record_key ((AK_CTRL << 1)+1);
! 103: return 0x1b;
! 104:
! 105: }
! 106: }
! 107: }
! 108:
! 109: #define USE_OLD_SHIFT_CODE
! 110:
! 111: switch (keycode & 0xff)
! 112: {
! 113: #ifndef USE_OLD_SHIFT_CODE
! 114: case VK_SHIFT:
! 115: {
! 116: SHORT lsh, rsh;
! 117: lsh = GetKeyState( VK_LSHIFT );
! 118: rsh = GetKeyState( VK_RSHIFT );
! 119: if( !keystate[AK_RSH] && (rsh & 0x8000))
! 120: return AK_RSH;
! 121: if( keystate[AK_RSH] && !(rsh & 0x8000))
! 122: return AK_RSH;
! 123: if( !keystate[AK_LSH] && (lsh & 0x8000))
! 124: return AK_LSH;
! 125: if( keystate[AK_LSH] && !(lsh & 0x8000))
! 126: return AK_LSH;
! 127: }
! 128: #endif
1.1 root 129: case VK_INSERT:
130: case VK_LWIN:
1.1.1.2 ! root 131: return AK_LAMI;
1.1 root 132: case VK_HOME:
133: case VK_RWIN:
1.1.1.2 ! root 134: return AK_RAMI;
! 135: case VK_MENU:
! 136: return scancode & KF_EXTENDED ? AK_RALT:AK_LALT;
! 137: case VK_APPS: /* Map Windows "Menu" key to Right-Alt of Amiga, for Stefan Stuntz */
! 138: return AK_RALT;
1.1 root 139: case VK_SCROLL:
140: return AK_inhibit;
1.1.1.2 ! root 141: case VK_F11:
! 142: #if 0
! 143: if( currprefs.win32_ctrl_F11_is_quit )
! 144: {
! 145: if (GetAsyncKeyState (VK_CONTROL)&0x8000)
! 146: uae_quit();
! 147: }
! 148: #endif
! 149: return AK_BACKSLASH;
1.1 root 150: case VK_F12:
1.1.1.2 ! root 151: if (GetAsyncKeyState (VK_CONTROL)&0x8000)
! 152: return -6;
! 153: if( shiftpressed() )
! 154: return -5;
! 155: else
! 156: return -2;
! 157: break;
1.1 root 158: case VK_PAUSE:
159: return -3;
1.1.1.2 ! root 160: case VK_DECIMAL:
! 161: return AK_NPDEL;
1.1 root 162: case VK_DIVIDE:
1.1.1.2 ! root 163: return AK_NPDIV;
1.1 root 164: case VK_MULTIPLY:
1.1.1.2 ! root 165: return AK_NPMUL;
1.1 root 166: case VK_SUBTRACT:
1.1.1.2 ! root 167: return AK_NPSUB;
1.1 root 168: case VK_ADD:
1.1.1.2 ! root 169: return AK_NPADD;
1.1 root 170: case VK_NUMPAD0:
1.1.1.2 ! root 171: return AK_NP0;
1.1 root 172: case VK_NUMPAD1:
1.1.1.2 ! root 173: return AK_NP1;
1.1 root 174: case VK_NUMPAD2:
1.1.1.2 ! root 175: return AK_NP2;
1.1 root 176: case VK_NUMPAD3:
1.1.1.2 ! root 177: return AK_NP3;
1.1 root 178: case VK_NUMPAD4:
1.1.1.2 ! root 179: return AK_NP4;
1.1 root 180: case VK_NUMPAD5:
1.1.1.2 ! root 181: return AK_NP5;
1.1 root 182: case VK_NUMPAD6:
1.1.1.2 ! root 183: return AK_NP6;
1.1 root 184: case VK_NUMPAD7:
1.1.1.2 ! root 185: return AK_NP7;
1.1 root 186: case VK_NUMPAD8:
1.1.1.2 ! root 187: return AK_NP8;
1.1 root 188: case VK_NUMPAD9:
1.1.1.2 ! root 189: return AK_NP9;
1.1 root 190: case VK_UP:
1.1.1.2 ! root 191: return AK_UP;
1.1 root 192: case VK_DOWN:
1.1.1.2 ! root 193: return AK_DN;
1.1 root 194: case VK_LEFT:
1.1.1.2 ! root 195: return AK_LF;
1.1 root 196: case VK_RIGHT:
1.1.1.2 ! root 197: return AK_RT;
1.1 root 198: case VK_CONTROL:
1.1.1.2 ! root 199: return scancode & KF_EXTENDED ? AK_RCTRL : AK_CTRL;
1.1 root 200: case VK_RETURN:
1.1.1.2 ! root 201: return scancode & KF_EXTENDED ? AK_ENT : AK_RET;
1.1 root 202: case VK_CAPITAL:
203: return -4;
204: case VK_F1:
205: if (helppressed ())
206: return -10 - shiftpressed ();
1.1.1.2 ! root 207: return AK_F1;
1.1 root 208: case VK_F2:
209: if (helppressed ())
210: return -12 - shiftpressed ();
1.1.1.2 ! root 211: return AK_F2;
1.1 root 212: case VK_F3:
213: if (helppressed ())
214: return -14 - shiftpressed ();
1.1.1.2 ! root 215: return AK_F3;
1.1 root 216: case VK_F4:
217: if (helppressed ())
218: return -16 - shiftpressed ();
1.1.1.2 ! root 219: return AK_F4;
1.1 root 220: case VK_F5:
1.1.1.2 ! root 221: return AK_F5;
1.1 root 222: case VK_F6:
1.1.1.2 ! root 223: return AK_F6;
1.1 root 224: case VK_F7:
1.1.1.2 ! root 225: return AK_F7;
1.1 root 226: case VK_F8:
1.1.1.2 ! root 227: return AK_F8;
1.1 root 228: case VK_F9:
1.1.1.2 ! root 229: return AK_F9;
1.1 root 230: case VK_F10:
1.1.1.2 ! root 231: return AK_F10;
1.1 root 232: case VK_NEXT:
1.1.1.2 ! root 233: return AK_HELP;
1.1 root 234: }
235:
236: switch (scancode) {
237: case 0x01:
238: return 0x45;
239: case 0x29:
240: return 0x00;
241: case 0x02:
242: return 0x01;
243: case 0x03:
244: return 0x02;
245: case 0x04:
246: return 0x03;
247: case 0x05:
248: return 0x04;
249: case 0x06:
250: return 0x05;
251: case 0x07:
252: return 0x06;
253: case 0x08:
254: return 0x07;
255: case 0x09:
256: return 0x08;
257: case 0x0a:
258: return 0x09;
259: case 0x0b:
260: return 0x0a;
261: case 0x0c:
262: return 0x0b;
263: case 0x0d:
264: return 0x0c;
1.1.1.2 ! root 265: case 0x57: /* This is F11 */
! 266: return AK_BACKSLASH;
1.1 root 267: case 0x0e:
268: return 0x41;
269: case 0x0f:
270: return 0x42;
271: case 0x10:
272: return 0x10;
273: case 0x11:
274: return 0x11;
275: case 0x12:
276: return 0x12;
277: case 0x13:
278: return 0x13;
279: case 0x14:
280: return 0x14;
281: case 0x15:
282: return 0x15;
283: case 0x16:
284: return 0x16;
285: case 0x17:
286: return 0x17;
287: case 0x18:
288: return 0x18;
289: case 0x19:
290: return 0x19;
291: case 0x1a:
292: return 0x1a;
293: case 0x1b:
294: return 0x1b;
295: /* special handling for caps lock: return 0x63*/
296: case 0x3a:
297: return 0x62;
298: case 0x1e:
299: return 0x20;
300: case 0x1f:
301: return 0x21;
302: case 0x20:
303: return 0x22;
304: case 0x21:
305: return 0x23;
306: case 0x22:
307: return 0x24;
308: case 0x23:
309: return 0x25;
310: case 0x24:
311: return 0x26;
312: case 0x25:
313: return 0x27;
314: case 0x26:
315: return 0x28;
316: case 0x27:
1.1.1.2 ! root 317: return AK_SEMICOLON;
1.1 root 318: case 0x28:
1.1.1.2 ! root 319: return AK_QUOTE;
! 320: case 0x2b: /* This scancode is \ on US keyboards, but # on German ones - figure out which! */
! 321: if( getascii( keycode & 0xFF, scancode ) == '#' )
! 322: return AK_NUMBERSIGN;
! 323: else
! 324: return AK_BACKSLASH;
! 325: break;
! 326: #ifdef USE_OLD_SHIFT_CODE
1.1 root 327: case 0x2a:
1.1.1.2 ! root 328: return AK_LSH;
! 329: case 0x36:
! 330: return AK_RSH;
! 331: #endif
1.1 root 332: case 0x56:
1.1.1.2 ! root 333: return AK_LTGT;
1.1 root 334: case 0x2c:
335: return 0x31;
336: case 0x2d:
337: return 0x32;
338: case 0x2e:
339: return 0x33;
340: case 0x2f:
341: return 0x34;
342: case 0x30:
343: return 0x35;
344: case 0x31:
345: return 0x36;
346: case 0x32:
347: return 0x37;
348: case 0x33:
349: return 0x38;
350: case 0x34:
351: return 0x39;
352: case 0x35:
353: return 0x3a;
354: case 0x38:
355: return 0x64;
356: case 0x39:
357: return 0x40;
358: case 0x153:
359: return 0x46;
360: case 0x51:
361: return 0x5f;
362: case 0x52:
1.1.1.2 ! root 363: return AK_LAMI;
1.1 root 364: case 0x47:
1.1.1.2 ! root 365: return AK_RAMI;
1.1 root 366: case 0x4b:
367: return 0x4f;
368: case 0x50:
369: return 0x4d;
370: case 0x4d:
371: return 0x4e;
372: case 0x48:
373: return 0x4c;
374: case 0x4e:
375: return 0x5e;
376: case 0x4a:
377: return 0x4a;
378: case 0x37:
379: return 0x5d;
380: }
381:
382: return -1;
383: }
384:
1.1.1.2 ! root 385: void clearallkeys()
! 386: {
! 387: int i;
! 388: for(i = 0; i <AK_CTRL + 1; i++)
! 389: my_kbd_handler (0, i, 0);
! 390: for(i = 0; i < AK_CTRL + 1; i++)
! 391: my_kbd_handler (i, 0, 0);
! 392: buttonstate[0] = 0;
! 393: buttonstate[1] = 0;
! 394: buttonstate[2] = 0;
! 395: }
! 396:
1.1 root 397: int my_kbd_handler (int keycode, int scancode, int newstate)
398: {
399: int akey = scancode2amiga (keycode, scancode);
400:
1.1.1.2 ! root 401: #ifdef DEBUG_KBD
! 402: write_log( "kbd_handler: keycode 0x%x, scancode 0x%x, newstate %d\n", keycode, scancode, newstate );
! 403: #endif
1.1 root 404: if (akey < 0) {
1.1.1.2 ! root 405:
1.1 root 406: switch (akey) {
1.1.1.2 ! root 407: #ifndef _WIN32_WCE
1.1 root 408: case -2:
409: if (newstate)
1.1.1.2 ! root 410: {
! 411: clearallkeys();
! 412: WIN32GUI_DisplayGUI(-1);
! 413: }
1.1 root 414: return 0;
415:
416: case -3:
417: if (newstate)
1.1.1.2 ! root 418: toggle_sound = 1;
1.1 root 419: return 0;
420: case -4:
421: if (newstate) {
422: akey = 0x62;
423: newstate = getcapslock ();
424: }
425: break;
1.1.1.2 ! root 426: case -5:
! 427: if( newstate )
! 428: {
! 429: // Bring up GUI-based debugger here
! 430: if(currprefs.illegal_mem)
! 431: {
! 432:
! 433:
! 434: if(picasso_on)changed_prefs.gfx_pfullscreen=0;
! 435: else changed_prefs.gfx_afullscreen=0;
! 436:
! 437: check_prefs_changed_gfx();
! 438: activate_debugger();
! 439:
! 440:
! 441: }
! 442:
! 443: }
! 444: return 0;
! 445: break;
! 446: case -6:
! 447: if(newstate)
! 448: {
! 449: if(picasso_on)changed_prefs.gfx_pfullscreen=!changed_prefs.gfx_pfullscreen;
! 450: else changed_prefs.gfx_afullscreen=!changed_prefs.gfx_afullscreen;
! 451:
! 452: return 0;
! 453: }
! 454: break;
1.1 root 455: default:
456:
1.1.1.2 ! root 457: if (newstate && akey >= -17 && akey <= -10)
! 458: {
! 459: akey = -10 - akey;
! 460:
! 461: if (akey & 1)
! 462: {
! 463: akey >>= 1;
! 464: disk_eject (akey);
! 465: return 0;
! 466: }
! 467: akey >>= 1;
! 468:
! 469: WIN32GUI_DisplayGUI( akey );
! 470: }
! 471: return 0;
! 472: #endif
1.1 root 473: }
474: }
475: if (akey == AK_inhibit) {
476: if (newstate)
1.1.1.2 ! root 477: toggle_inhibit_frame (IHF_SCROLLLOCK);
1.1 root 478: return 0;
479: }
1.1.1.2 ! root 480: if( akey > AK_RCTRL )
! 481: return 0;
1.1 root 482: if (keystate[akey] == newstate)
483: return 0;
484: keystate[akey] = newstate;
485:
486: if (newstate)
487: record_key (akey << 1);
488: else
489: record_key ((akey << 1) + 1);
490:
491: /* "Affengriff" */
1.1.1.2 ! root 492: if( (keystate[AK_CTRL] || keystate[AK_RCTRL] ) && keystate[AK_LAMI] && keystate[AK_RAMI])uae_reset();
! 493: //if( (keystate[AK_CTRL] || keystate[AK_RCTRL] ) && keystate[AK_RAMI])uae_reset();
1.1 root 494:
495: return 0;
496: }
497:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.