Mercurial > sdl-ios-xcode
annotate src/video/cybergfx/SDL_amigaevents.c @ 202:401f0134f4f9
Fixed crash when using double-buffering with DGA
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 30 Sep 2001 20:19:20 +0000 |
parents | 75a95f82bc1f |
children | e8157fcb3114 |
rev | line source |
---|---|
0 | 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: | |
21
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
258 SDL_PrivateResize(SDL_Window->Width-SDL_Window->BorderLeft-SDL_Window->BorderRight, |
75a95f82bc1f
Updated the Amiga OS port of SDL (thanks Gabriele)
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
259 SDL_Window->Height-SDL_Window->BorderTop-SDL_Window->BorderBottom); |
0 | 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 } |