comparison src/video/cybergfx/SDL_amigaevents.c @ 0:74212992fb08

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