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