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