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
23 # define _STRUCT_TIMEVAL 1
31 /* Handle the event stream, converting Amiga events into SDL events */
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
60 static inline int amiga_WarpedMotion(_THIS
, struct IntuiMessage
*m
)
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
;
71 printf("Warped mouse motion: %d,%d\n", deltax
, deltay
);
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
;
86 printf("Extra mouse motion: %d,%d\n", deltax
, deltay
);
88 mouse_last
.x
= xevent
->xmotion
.x
;
89 mouse_last
.y
= xevent
->xmotion
.y
;
90 posted
+= SDL_PrivateMouseMotion(0, 1, deltax
, deltay
);
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
)) &&
101 (mouse_last
.x
+MOUSE_FUDGE_FACTOR
)) &&
103 (mouse_last
.y
-MOUSE_FUDGE_FACTOR
)) &&
105 (mouse_last
.y
+MOUSE_FUDGE_FACTOR
)) ) {
109 printf("Lost mouse motion: %d,%d\n", xevent
->xmotion
.x
, xevent
->xmotion
.y
);
114 printf("Warning: didn't detect mouse warp motion\n");
123 static int amiga_GetButton(int code
)
128 return SDL_BUTTON_MIDDLE
;
130 return SDL_BUTTON_RIGHT
;
132 return SDL_BUTTON_LEFT
;
136 static int amiga_DispatchEvent(_THIS
,struct IntuiMessage
*msg
)
138 int class=msg
->Class
,code
=msg
->Code
;
143 /* Gaining mouse coverage? */
144 case IDCMP_ACTIVEWINDOW
:
145 posted
= SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS
);
148 /* Losing mouse coverage? */
149 case IDCMP_INACTIVEWINDOW
:
150 posted
= SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS
);
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;
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;
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
);
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? */
191 code
&=~IECODE_UP_PREFIX
;
192 posted
= SDL_PrivateMouseButton(SDL_RELEASED
,
193 amiga_GetButton(code
), 0, 0);
201 if( !(code
&IECODE_UP_PREFIX
) )
204 posted
= SDL_PrivateKeyboard(SDL_PRESSED
,
205 amiga_TranslateKey(code
, msg
->Qualifier
, &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
));
221 /* Have we been iconified? */
225 printf("UnmapNotify!\n");
227 posted
=SDL_PrivateAppActive(0, SDL_APPACTIVE
|SDL_APPINPUTFOCUS
);
231 /* Have we been restored? */
235 printf("MapNotify!\n");
238 posted
= SDL_PrivateAppActive(1, SDL_APPACTIVE
);
240 if ( SDL_VideoSurface
&&
241 (SDL_VideoSurface
->flags
& SDL_FULLSCREEN
) )
243 CGX_EnterFullScreen(this);
245 X11_GrabInputNoLock(this, this->input_grab
);
247 if ( SDL_VideoSurface
) {
248 CGX_RefreshDisplay(this);
253 if ( SDL_VideoSurface
&& (xevent
.xexpose
.count
== 0) ) {
254 CGX_RefreshDisplay(this);
259 /* Have we been resized? */
261 SDL_PrivateResize(SDL_Window
->Width
-SDL_Window
->BorderLeft
-SDL_Window
->BorderRight
,
262 SDL_Window
->Height
-SDL_Window
->BorderTop
-SDL_Window
->BorderBottom
);
266 /* Have we been requested to quit? */
267 case IDCMP_CLOSEWINDOW
:
268 posted
= SDL_PrivateQuit();
271 /* Do we need to refresh ourselves? */
274 /* Only post the event if we're watching for it */
275 if ( SDL_ProcessEvents
[SDL_SYSWMEVENT
] == SDL_ENABLE
) {
278 SDL_VERSION(&wmmsg
.version
);
280 wmmsg
.subsystem
= SDL_SYSWM_CGX
;
281 wmmsg
.event
.xevent
= xevent
;
283 posted
= SDL_PrivateSysWMEvent(&wmmsg
);
288 ReplyMsg((struct Message
*)msg
);
294 void amiga_PumpEvents(_THIS
)
297 struct IntuiMessage
*m
;
299 /* Keep processing pending events */
301 while (( m
=(struct IntuiMessage
*)GetMsg(SDL_Window
->UserPort
) )) {
302 amiga_DispatchEvent(this,m
);
307 void amiga_InitKeymap(void)
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
;
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
;
440 static struct Library
*KeymapBase
=NULL
; /* Linking failed in WOS version if ConsoleDevice was used */
442 static struct Library
*ConsoleDevice
=NULL
;
445 /* Get the raw keyboard scancode */
446 keysym
->scancode
= code
;
447 keysym
->sym
= MISC_keymap
[code
];
450 fprintf(stderr
, "Translating key 0x%.4x (%d)\n", xsym
, xkey
->keycode
);
459 KeymapBase
=OpenLibrary("keymap.library", 0L);
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
;
469 DeleteIORequest(ConReq
);
475 DeleteMsgPort(ConPort
);
481 /* Get the translated SDL virtual keysym */
482 if ( keysym
->sym
==SDLK_UNKNOWN
)
490 event
.ie_Qualifier
=0;
491 event
.ie_Class
=IECLASS_RAWKEY
;
492 event
.ie_SubClass
=0L;
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;
500 if( (actual
=MapRawKey(&event
,buffer
,5,NULL
))>=0)
502 if( (actual
=RawKeyConvert(&event
,buffer
,5,NULL
))>=0)
507 D(bug("Warning (%ld) character conversion!\n",actual
));
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 */
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];
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
),
539 keysym
->unicode
= keybuf
[0];
546 void amiga_InitOSKeymap(_THIS
)