• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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