1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 /* Handle the event stream, converting Amiga events into SDL events */
25 #include "SDL.h"
26
27 #include "SDL_syswm.h"
28 #include "../SDL_sysvideo.h"
29 #include "../../events/SDL_sysevents.h"
30 #include "../../events/SDL_events_c.h"
31 #include "SDL_cgxvideo.h"
32 #include "SDL_cgxmodes_c.h"
33 #include "SDL_cgximage_c.h"
34 #include "SDL_cgxwm_c.h"
35 #include "SDL_amigaevents_c.h"
36
37
38 /* The translation tables from an Amiga keysym to a SDL keysym */
39 static SDLKey MISC_keymap[256];
40 SDL_keysym *amiga_TranslateKey(int code, SDL_keysym *keysym);
41 struct IOStdReq *ConReq=NULL;
42 struct MsgPort *ConPort=NULL;
43
44 /* Note: The X server buffers and accumulates mouse motion events, so
45 the motion event generated by the warp may not appear exactly as we
46 expect it to. We work around this (and improve performance) by only
47 warping the pointer when it reaches the edge, and then wait for it.
48 */
49 #define MOUSE_FUDGE_FACTOR 8
50
51 #if 0
52
53 static inline int amiga_WarpedMotion(_THIS, struct IntuiMessage *m)
54 {
55 int w, h, i;
56 int deltax, deltay;
57 int posted;
58
59 w = SDL_VideoSurface->w;
60 h = SDL_VideoSurface->h;
61 deltax = xevent->xmotion.x - mouse_last.x;
62 deltay = xevent->xmotion.y - mouse_last.y;
63 #ifdef DEBUG_MOTION
64 printf("Warped mouse motion: %d,%d\n", deltax, deltay);
65 #endif
66 mouse_last.x = xevent->xmotion.x;
67 mouse_last.y = xevent->xmotion.y;
68 posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay);
69
70 if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) ||
71 (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) ||
72 (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) ||
73 (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) {
74 /* Get the events that have accumulated */
75 while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) {
76 deltax = xevent->xmotion.x - mouse_last.x;
77 deltay = xevent->xmotion.y - mouse_last.y;
78 #ifdef DEBUG_MOTION
79 printf("Extra mouse motion: %d,%d\n", deltax, deltay);
80 #endif
81 mouse_last.x = xevent->xmotion.x;
82 mouse_last.y = xevent->xmotion.y;
83 posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay);
84 }
85 mouse_last.x = w/2;
86 mouse_last.y = h/2;
87 XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0,
88 mouse_last.x, mouse_last.y);
89 for ( i=0; i<10; ++i ) {
90 XMaskEvent(SDL_Display, PointerMotionMask, xevent);
91 if ( (xevent->xmotion.x >
92 (mouse_last.x-MOUSE_FUDGE_FACTOR)) &&
93 (xevent->xmotion.x <
94 (mouse_last.x+MOUSE_FUDGE_FACTOR)) &&
95 (xevent->xmotion.y >
96 (mouse_last.y-MOUSE_FUDGE_FACTOR)) &&
97 (xevent->xmotion.y <
98 (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) {
99 break;
100 }
101 #ifdef DEBUG_XEVENTS
102 printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y);
103 #endif
104 }
105 #ifdef DEBUG_XEVENTS
106 if ( i == 10 ) {
107 printf("Warning: didn't detect mouse warp motion\n");
108 }
109 #endif
110 }
111 return(posted);
112 }
113
114 #endif
115
amiga_GetButton(int code)116 static int amiga_GetButton(int code)
117 {
118 switch(code)
119 {
120 case IECODE_MBUTTON:
121 return SDL_BUTTON_MIDDLE;
122 case IECODE_RBUTTON:
123 return SDL_BUTTON_RIGHT;
124 default:
125 return SDL_BUTTON_LEFT;
126 }
127 }
128
amiga_DispatchEvent(_THIS,struct IntuiMessage * msg)129 static int amiga_DispatchEvent(_THIS,struct IntuiMessage *msg)
130 {
131 int class=msg->Class,code=msg->Code;
132 int posted;
133
134 posted = 0;
135 switch (class) {
136 /* Gaining mouse coverage? */
137 case IDCMP_ACTIVEWINDOW:
138 posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
139 break;
140
141 /* Losing mouse coverage? */
142 case IDCMP_INACTIVEWINDOW:
143 posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
144 break;
145 #if 0
146 /* Gaining input focus? */
147 case IDCMP_ACTIVEWINDOW:
148 posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
149
150 /* Queue entry into fullscreen mode */
151 switch_waiting = 0x01 | SDL_FULLSCREEN;
152 switch_time = SDL_GetTicks() + 1500;
153 break;
154
155 /* Losing input focus? */
156 case IDCMP_INACTIVEWINDOW:
157 posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
158
159 /* Queue leaving fullscreen mode */
160 switch_waiting = 0x01;
161 switch_time = SDL_GetTicks() + 200;
162 break;
163 #endif
164 /* Mouse motion? */
165 case IDCMP_MOUSEMOVE:
166 if ( SDL_VideoSurface ) {
167 posted = SDL_PrivateMouseMotion(0, 0,
168 msg->MouseX-SDL_Window->BorderLeft,
169 msg->MouseY-SDL_Window->BorderTop);
170 }
171 break;
172
173 /* Mouse button press? */
174 case IDCMP_MOUSEBUTTONS:
175
176 if(!(code&IECODE_UP_PREFIX))
177 {
178 posted = SDL_PrivateMouseButton(SDL_PRESSED,
179 amiga_GetButton(code), 0, 0);
180 }
181 /* Mouse button release? */
182 else
183 {
184 code&=~IECODE_UP_PREFIX;
185 posted = SDL_PrivateMouseButton(SDL_RELEASED,
186 amiga_GetButton(code), 0, 0);
187 }
188 break;
189
190 case IDCMP_RAWKEY:
191
192 /* Key press? */
193
194 if( !(code&IECODE_UP_PREFIX) )
195 {
196 SDL_keysym keysym;
197 posted = SDL_PrivateKeyboard(SDL_PRESSED,
198 amiga_TranslateKey(code, &keysym));
199 }
200 else
201 {
202 /* Key release? */
203
204 SDL_keysym keysym;
205 code&=~IECODE_UP_PREFIX;
206
207 /* Check to see if this is a repeated key */
208 /* if ( ! X11_KeyRepeat(SDL_Display, &xevent) ) */
209
210 posted = SDL_PrivateKeyboard(SDL_RELEASED,
211 amiga_TranslateKey(code, &keysym));
212 }
213 break;
214 /* Have we been iconified? */
215 #if 0
216 case UnmapNotify: {
217 #ifdef DEBUG_XEVENTS
218 printf("UnmapNotify!\n");
219 #endif
220 posted=SDL_PrivateAppActive(0, SDL_APPACTIVE|SDL_APPINPUTFOCUS);
221 }
222 break;
223
224 /* Have we been restored? */
225
226 case MapNotify: {
227 #ifdef DEBUG_XEVENTS
228 printf("MapNotify!\n");
229 #endif
230
231 posted = SDL_PrivateAppActive(1, SDL_APPACTIVE);
232
233 if ( SDL_VideoSurface &&
234 (SDL_VideoSurface->flags & SDL_FULLSCREEN) )
235 {
236 CGX_EnterFullScreen(this);
237 } else {
238 X11_GrabInputNoLock(this, this->input_grab);
239 }
240 if ( SDL_VideoSurface ) {
241 CGX_RefreshDisplay(this);
242 }
243 }
244 break;
245 case Expose:
246 if ( SDL_VideoSurface && (xevent.xexpose.count == 0) ) {
247 CGX_RefreshDisplay(this);
248 }
249 break;
250 #endif
251
252 /* Have we been resized? */
253 case IDCMP_NEWSIZE:
254 SDL_PrivateResize(SDL_Window->Width-SDL_Window->BorderLeft-SDL_Window->BorderRight,
255 SDL_Window->Height-SDL_Window->BorderTop-SDL_Window->BorderBottom);
256
257 break;
258
259 /* Have we been requested to quit? */
260 case IDCMP_CLOSEWINDOW:
261 posted = SDL_PrivateQuit();
262 break;
263
264 /* Do we need to refresh ourselves? */
265
266 default: {
267 /* Only post the event if we're watching for it */
268 if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
269 SDL_SysWMmsg wmmsg;
270
271 SDL_VERSION(&wmmsg.version);
272 #if 0
273 wmmsg.subsystem = SDL_SYSWM_CGX;
274 wmmsg.event.xevent = xevent;
275 #endif
276 posted = SDL_PrivateSysWMEvent(&wmmsg);
277 }
278 }
279 break;
280 }
281 ReplyMsg((struct Message *)msg);
282
283
284 return(posted);
285 }
286
amiga_PumpEvents(_THIS)287 void amiga_PumpEvents(_THIS)
288 {
289 int pending;
290 struct IntuiMessage *m;
291
292 /* Keep processing pending events */
293 pending = 0;
294 while ( m=(struct IntuiMessage *)GetMsg(SDL_Window->UserPort) ) {
295 amiga_DispatchEvent(this,m);
296 ++pending;
297 }
298 }
299
amiga_InitKeymap(void)300 void amiga_InitKeymap(void)
301 {
302 int i;
303
304 /* Map the miscellaneous keys */
305 for ( i=0; i<SDL_arraysize(MISC_keymap); ++i )
306 MISC_keymap[i] = SDLK_UNKNOWN;
307
308 /* These X keysyms have 0xFF as the high byte */
309 MISC_keymap[65] = SDLK_BACKSPACE;
310 MISC_keymap[66] = SDLK_TAB;
311 MISC_keymap[70] = SDLK_CLEAR;
312 MISC_keymap[70] = SDLK_DELETE;
313 MISC_keymap[68] = SDLK_RETURN;
314 // MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE;
315 MISC_keymap[69] = SDLK_ESCAPE;
316 MISC_keymap[70] = SDLK_DELETE;
317 /*
318 SDLK_SPACE = 32,
319 SDLK_MINUS = 45,
320 SDLK_LESS = 60,
321 SDLK_COMMA = 44,
322 SDLK_PERIOD = 46,
323 SDLK_0 = 48,
324 SDLK_1 = 49,
325 SDLK_2 = 50,
326 SDLK_3 = 51,
327 SDLK_4 = 52,
328 SDLK_5 = 53,
329 SDLK_6 = 54,
330 SDLK_7 = 55,
331 SDLK_8 = 56,
332 SDLK_9 = 57,
333 SDLK_BACKQUOTE = 96,
334 SDLK_BACKSLASH = 92,
335 SDLK_a = 97,
336 SDLK_b = 98,
337 SDLK_c = 99,
338 SDLK_d = 100,
339 SDLK_e = 101,
340 SDLK_f = 102,
341 SDLK_g = 103,
342 SDLK_h = 104,
343 SDLK_i = 105,
344 SDLK_j = 106,
345 SDLK_k = 107,
346 SDLK_l = 108,
347 SDLK_m = 109,
348 SDLK_n = 110,
349 SDLK_o = 111,
350 SDLK_p = 112,
351 SDLK_q = 113,
352 SDLK_r = 114,
353 SDLK_s = 115,
354 SDLK_t = 116,
355 SDLK_u = 117,
356 SDLK_v = 118,
357 SDLK_w = 119,
358 SDLK_x = 120,
359 SDLK_y = 121,
360 SDLK_z = 122,
361 */
362 MISC_keymap[15] = SDLK_KP0; /* Keypad 0-9 */
363 MISC_keymap[29] = SDLK_KP1;
364 MISC_keymap[30] = SDLK_KP2;
365 MISC_keymap[31] = SDLK_KP3;
366 MISC_keymap[45] = SDLK_KP4;
367 MISC_keymap[46] = SDLK_KP5;
368 MISC_keymap[47] = SDLK_KP6;
369 MISC_keymap[61] = SDLK_KP7;
370 MISC_keymap[62] = SDLK_KP8;
371 MISC_keymap[63] = SDLK_KP9;
372 MISC_keymap[60] = SDLK_KP_PERIOD;
373 MISC_keymap[92] = SDLK_KP_DIVIDE;
374 MISC_keymap[93] = SDLK_KP_MULTIPLY;
375 MISC_keymap[74] = SDLK_KP_MINUS;
376 MISC_keymap[94] = SDLK_KP_PLUS;
377 MISC_keymap[67] = SDLK_KP_ENTER;
378 // MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS;
379
380 MISC_keymap[76] = SDLK_UP;
381 MISC_keymap[77] = SDLK_DOWN;
382 MISC_keymap[78] = SDLK_RIGHT;
383 MISC_keymap[79] = SDLK_LEFT;
384 /*
385 MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT;
386 MISC_keymap[XK_Home&0xFF] = SDLK_HOME;
387 MISC_keymap[XK_End&0xFF] = SDLK_END;
388 */
389 // Mappati sulle parentesi del taastierino
390 MISC_keymap[90] = SDLK_PAGEUP;
391 MISC_keymap[91] = SDLK_PAGEDOWN;
392
393 MISC_keymap[80] = SDLK_F1;
394 MISC_keymap[81] = SDLK_F2;
395 MISC_keymap[82] = SDLK_F3;
396 MISC_keymap[83] = SDLK_F4;
397 MISC_keymap[84] = SDLK_F5;
398 MISC_keymap[85] = SDLK_F6;
399 MISC_keymap[86] = SDLK_F7;
400 MISC_keymap[87] = SDLK_F8;
401 MISC_keymap[88] = SDLK_F9;
402 MISC_keymap[89] = SDLK_F10;
403 // MISC_keymap[XK_F11&0xFF] = SDLK_F11;
404 // MISC_keymap[XK_F12&0xFF] = SDLK_F12;
405 // MISC_keymap[XK_F13&0xFF] = SDLK_F13;
406 // MISC_keymap[XK_F14&0xFF] = SDLK_F14;
407 // MISC_keymap[XK_F15&0xFF] = SDLK_F15;
408
409 // MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK;
410 MISC_keymap[98] = SDLK_CAPSLOCK;
411 // MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
412 MISC_keymap[97] = SDLK_RSHIFT;
413 MISC_keymap[96] = SDLK_LSHIFT;
414 MISC_keymap[99] = SDLK_LCTRL;
415 MISC_keymap[99] = SDLK_LCTRL;
416 MISC_keymap[101] = SDLK_RALT;
417 MISC_keymap[100] = SDLK_LALT;
418 // MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA;
419 // MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA;
420 MISC_keymap[103] = SDLK_LSUPER; /* Left "Windows" */
421 MISC_keymap[102] = SDLK_RSUPER; /* Right "Windows */
422
423 MISC_keymap[95] = SDLK_HELP;
424 }
425
amiga_TranslateKey(int code,SDL_keysym * keysym)426 SDL_keysym *amiga_TranslateKey(int code, SDL_keysym *keysym)
427 {
428 #ifdef STORMC4_WOS
429 static struct Library *KeymapBase=NULL; /* Linking failed in WOS version if ConsoleDevice was used */
430 #else
431 static struct Library *ConsoleDevice=NULL;
432 #endif
433
434 /* Get the raw keyboard scancode */
435 keysym->scancode = code;
436 keysym->sym = MISC_keymap[code];
437
438 #ifdef DEBUG_KEYS
439 fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, xkey->keycode);
440 #endif
441 /* Get the translated SDL virtual keysym */
442 if ( keysym->sym==SDLK_UNKNOWN )
443 {
444 #ifdef STORMC4_WOS
445 if(!KeymapBase)
446 #else
447 if(!ConsoleDevice)
448 #endif
449 {
450 #ifdef STORMC4_WOS
451 KeymapBase=OpenLibrary("keymap.library", 0L);
452 #else
453 if(ConPort=CreateMsgPort())
454 {
455 if(ConReq=CreateIORequest(ConPort,sizeof(struct IOStdReq)))
456 {
457 if(!OpenDevice("console.device",-1,(struct IORequest *)ConReq,0))
458 ConsoleDevice=(struct Library *)ConReq->io_Device;
459 else
460 {
461 DeleteIORequest(ConReq);
462 ConReq=NULL;
463 }
464 }
465 else
466 {
467 DeleteMsgPort(ConPort);
468 ConPort=NULL;
469 }
470 }
471 #endif
472 }
473
474 #ifdef STORMC4_WOS
475 if(KeymapBase)
476 #else
477 if(ConsoleDevice)
478 #endif
479 {
480 struct InputEvent event;
481 long actual;
482 char buffer[5];
483
484 event.ie_Qualifier=0;
485 event.ie_Class=IECLASS_RAWKEY;
486 event.ie_SubClass=0L;
487 event.ie_Code=code;
488 event.ie_X=event.ie_Y=0;
489 event.ie_EventAddress=NULL;
490 event.ie_NextEvent=NULL;
491 event.ie_Prev1DownCode=event.ie_Prev1DownQual=event.ie_Prev2DownCode=event.ie_Prev2DownQual=0;
492
493 #ifdef STORMC4_WOS
494 if( (actual=MapRawKey(&event,buffer,5,NULL))>=0)
495 #else
496 if( (actual=RawKeyConvert(&event,buffer,5,NULL))>=0)
497 #endif
498 {
499 if(actual>1)
500 {
501 D(bug("Warning (%ld) character conversion!\n",actual));
502 }
503 else if(actual==1)
504 {
505 keysym->sym=*buffer;
506 D(bug("Converted rawcode %ld to <%lc>\n",code,*buffer));
507 // Bufferizzo x le successive chiamate!
508 MISC_keymap[code]=*buffer;
509 }
510 }
511 }
512
513 }
514 keysym->mod = KMOD_NONE;
515
516 /* If UNICODE is on, get the UNICODE value for the key */
517 keysym->unicode = 0;
518 if ( SDL_TranslateUNICODE ) {
519 #if 0
520 static XComposeStatus state;
521 /* Until we handle the IM protocol, use XLookupString() */
522 unsigned char keybuf[32];
523 if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf),
524 NULL, &state) ) {
525 keysym->unicode = keybuf[0];
526 }
527 #endif
528 }
529 return(keysym);
530 }
531
amiga_InitOSKeymap(_THIS)532 void amiga_InitOSKeymap(_THIS)
533 {
534 amiga_InitKeymap();
535 }
536