diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/cybergfx/SDL_amigaevents.c	Thu Apr 26 16:45:43 2001 +0000
@@ -0,0 +1,518 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id$";
+#endif
+
+/* Handle the event stream, converting Amiga events into SDL events */
+#include "SDL.h"
+
+#include "SDL_syswm.h"
+#include "SDL_sysevents.h"
+#include "SDL_sysvideo.h"
+#include "SDL_events_c.h"
+#include "SDL_cgxvideo.h"
+#include "SDL_cgxmodes_c.h"
+#include "SDL_cgximage_c.h"
+#include "SDL_cgxwm_c.h"
+#include "SDL_amigaevents_c.h"
+
+
+/* The translation tables from an Amiga keysym to a SDL keysym */
+static SDLKey MISC_keymap[256];
+SDL_keysym *amiga_TranslateKey(int code, SDL_keysym *keysym);
+struct IOStdReq *ConReq=NULL;
+struct MsgPort *ConPort=NULL;
+
+/* Note:  The X server buffers and accumulates mouse motion events, so
+   the motion event generated by the warp may not appear exactly as we
+   expect it to.  We work around this (and improve performance) by only
+   warping the pointer when it reaches the edge, and then wait for it.
+*/
+#define MOUSE_FUDGE_FACTOR	8
+
+#if 0
+
+static inline int amiga_WarpedMotion(_THIS, struct IntuiMessage *m)
+{
+	int w, h, i;
+	int deltax, deltay;
+	int posted;
+
+	w = SDL_VideoSurface->w;
+	h = SDL_VideoSurface->h;
+	deltax = xevent->xmotion.x - mouse_last.x;
+	deltay = xevent->xmotion.y - mouse_last.y;
+#ifdef DEBUG_MOTION
+  printf("Warped mouse motion: %d,%d\n", deltax, deltay);
+#endif
+	mouse_last.x = xevent->xmotion.x;
+	mouse_last.y = xevent->xmotion.y;
+	posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay);
+
+	if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) ||
+	     (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) ||
+	     (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) ||
+	     (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) {
+		/* Get the events that have accumulated */
+		while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) {
+			deltax = xevent->xmotion.x - mouse_last.x;
+			deltay = xevent->xmotion.y - mouse_last.y;
+#ifdef DEBUG_MOTION
+  printf("Extra mouse motion: %d,%d\n", deltax, deltay);
+#endif
+			mouse_last.x = xevent->xmotion.x;
+			mouse_last.y = xevent->xmotion.y;
+			posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay);
+		}
+		mouse_last.x = w/2;
+		mouse_last.y = h/2;
+		XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0,
+					mouse_last.x, mouse_last.y);
+		for ( i=0; i<10; ++i ) {
+        		XMaskEvent(SDL_Display, PointerMotionMask, xevent);
+			if ( (xevent->xmotion.x >
+			          (mouse_last.x-MOUSE_FUDGE_FACTOR)) &&
+			     (xevent->xmotion.x <
+			          (mouse_last.x+MOUSE_FUDGE_FACTOR)) &&
+			     (xevent->xmotion.y >
+			          (mouse_last.y-MOUSE_FUDGE_FACTOR)) &&
+			     (xevent->xmotion.y <
+			          (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) {
+				break;
+			}
+#ifdef DEBUG_XEVENTS
+  printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y);
+#endif
+		}
+#ifdef DEBUG_XEVENTS
+		if ( i == 10 ) {
+			printf("Warning: didn't detect mouse warp motion\n");
+		}
+#endif
+	}
+	return(posted);
+}
+
+#endif
+
+static int amiga_GetButton(int code)
+{
+	switch(code)
+	{
+		case IECODE_MBUTTON:
+			return SDL_BUTTON_MIDDLE;
+		case IECODE_RBUTTON:
+			return SDL_BUTTON_RIGHT;
+		default:
+			return SDL_BUTTON_LEFT;
+	}
+}
+
+static int amiga_DispatchEvent(_THIS,struct IntuiMessage *msg)
+{
+	int class=msg->Class,code=msg->Code;
+	int posted;
+
+	posted = 0;
+	switch (class) {
+	    /* Gaining mouse coverage? */
+	    case IDCMP_ACTIVEWINDOW:
+			posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+			break;
+
+	    /* Losing mouse coverage? */
+	    case IDCMP_INACTIVEWINDOW:
+			posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
+			break;
+#if 0
+	    /* Gaining input focus? */
+	    case IDCMP_ACTIVEWINDOW: 
+			posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+
+			/* Queue entry into fullscreen mode */
+			switch_waiting = 0x01 | SDL_FULLSCREEN;
+			switch_time = SDL_GetTicks() + 1500;
+		    break;
+
+	    /* Losing input focus? */
+	    case IDCMP_INACTIVEWINDOW:
+			posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
+
+		/* Queue leaving fullscreen mode */
+			switch_waiting = 0x01;
+			switch_time = SDL_GetTicks() + 200;
+		    break;
+#endif
+	    /* Mouse motion? */
+	    case IDCMP_MOUSEMOVE: 
+			if ( SDL_VideoSurface ) {
+				posted = SDL_PrivateMouseMotion(0, 0,
+						msg->MouseX-SDL_Window->BorderLeft,
+						msg->MouseY-SDL_Window->BorderTop);
+			}
+	    	break;
+
+	    /* Mouse button press? */
+		case IDCMP_MOUSEBUTTONS:
+
+			if(!(code&IECODE_UP_PREFIX))
+			{
+				posted = SDL_PrivateMouseButton(SDL_PRESSED, 
+						amiga_GetButton(code), 0, 0);
+			    }
+	    /* Mouse button release? */
+			else
+			{
+				code&=~IECODE_UP_PREFIX;
+				posted = SDL_PrivateMouseButton(SDL_RELEASED, 
+						amiga_GetButton(code), 0, 0);
+			}
+			break;
+
+	    case IDCMP_RAWKEY:
+
+		    /* Key press? */
+
+		    if( !(code&IECODE_UP_PREFIX) )
+		    {
+				SDL_keysym keysym;
+				posted = SDL_PrivateKeyboard(SDL_PRESSED,
+					amiga_TranslateKey(code, &keysym));
+		    }
+		    else
+		    {
+	    /* Key release? */
+
+				SDL_keysym keysym;
+				code&=~IECODE_UP_PREFIX;
+
+			/* Check to see if this is a repeated key */
+/*			if ( ! X11_KeyRepeat(SDL_Display, &xevent) )  */
+
+				posted = SDL_PrivateKeyboard(SDL_RELEASED, 
+					amiga_TranslateKey(code, &keysym));
+		    }
+		    break;
+	    /* Have we been iconified? */
+#if 0
+	    case UnmapNotify: {
+#ifdef DEBUG_XEVENTS
+printf("UnmapNotify!\n");
+#endif
+		posted=SDL_PrivateAppActive(0, SDL_APPACTIVE|SDL_APPINPUTFOCUS);
+	    }
+	    break;
+
+	    /* Have we been restored? */
+
+	    case MapNotify: {
+#ifdef DEBUG_XEVENTS
+printf("MapNotify!\n");
+#endif
+
+		posted = SDL_PrivateAppActive(1, SDL_APPACTIVE);
+
+		if ( SDL_VideoSurface &&
+		     (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) 
+		{
+			CGX_EnterFullScreen(this);
+		} else {
+			X11_GrabInputNoLock(this, this->input_grab);
+		}
+		if ( SDL_VideoSurface ) {
+			CGX_RefreshDisplay(this);
+		}
+	    }
+	    break;
+	    case Expose:
+		if ( SDL_VideoSurface && (xevent.xexpose.count == 0) ) {
+			CGX_RefreshDisplay(this);
+		}
+		break;
+#endif
+
+	    /* Have we been resized? */
+	    case IDCMP_NEWSIZE: 
+			SDL_PrivateResize(SDL_Window->Width,
+		                  SDL_Window->Height);
+			break;
+
+	    /* Have we been requested to quit? */
+	    case IDCMP_CLOSEWINDOW:
+		posted = SDL_PrivateQuit();
+		break;
+
+	    /* Do we need to refresh ourselves? */
+
+	    default: {
+		/* Only post the event if we're watching for it */
+		if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) {
+			SDL_SysWMmsg wmmsg;
+
+			SDL_VERSION(&wmmsg.version);
+#if 0
+			wmmsg.subsystem = SDL_SYSWM_CGX;
+			wmmsg.event.xevent = xevent;
+#endif
+			posted = SDL_PrivateSysWMEvent(&wmmsg);
+		}
+	    }
+	    break;
+	}
+	ReplyMsg((struct Message *)msg);
+
+
+	return(posted);
+}
+
+void amiga_PumpEvents(_THIS)
+{
+	int pending;
+	struct IntuiMessage *m;
+
+	/* Keep processing pending events */
+	pending = 0;
+	while ( m=(struct IntuiMessage *)GetMsg(SDL_Window->UserPort) ) {
+		amiga_DispatchEvent(this,m);
+		++pending;
+	}
+}
+
+void amiga_InitKeymap(void)
+{
+	int i;
+
+	/* Map the miscellaneous keys */
+	for ( i=0; i<SDL_TABLESIZE(MISC_keymap); ++i )
+		MISC_keymap[i] = SDLK_UNKNOWN;
+
+	/* These X keysyms have 0xFF as the high byte */
+	MISC_keymap[65] = SDLK_BACKSPACE;
+	MISC_keymap[66] = SDLK_TAB;
+	MISC_keymap[70] = SDLK_CLEAR;
+	MISC_keymap[70] = SDLK_DELETE;
+	MISC_keymap[68] = SDLK_RETURN;
+//	MISC_keymap[XK_Pause&0xFF] = SDLK_PAUSE;
+	MISC_keymap[69] = SDLK_ESCAPE;
+	MISC_keymap[70] = SDLK_DELETE;
+/*
+	SDLK_SPACE		= 32,
+	SDLK_MINUS		= 45,
+	SDLK_LESS		= 60,
+	SDLK_COMMA		= 44,
+	SDLK_PERIOD		= 46,
+	SDLK_0			= 48,
+	SDLK_1			= 49,
+	SDLK_2			= 50,
+	SDLK_3			= 51,
+	SDLK_4			= 52,
+	SDLK_5			= 53,
+	SDLK_6			= 54,
+	SDLK_7			= 55,
+	SDLK_8			= 56,
+	SDLK_9			= 57,
+	SDLK_BACKQUOTE		= 96,
+	SDLK_BACKSLASH		= 92,
+	SDLK_a			= 97,
+	SDLK_b			= 98,
+	SDLK_c			= 99,
+	SDLK_d			= 100,
+	SDLK_e			= 101,
+	SDLK_f			= 102,
+	SDLK_g			= 103,
+	SDLK_h			= 104,
+	SDLK_i			= 105,
+	SDLK_j			= 106,
+	SDLK_k			= 107,
+	SDLK_l			= 108,
+	SDLK_m			= 109,
+	SDLK_n			= 110,
+	SDLK_o			= 111,
+	SDLK_p			= 112,
+	SDLK_q			= 113,
+	SDLK_r			= 114,
+	SDLK_s			= 115,
+	SDLK_t			= 116,
+	SDLK_u			= 117,
+	SDLK_v			= 118,
+	SDLK_w			= 119,
+	SDLK_x			= 120,
+	SDLK_y			= 121,
+	SDLK_z			= 122,
+*/
+	MISC_keymap[15] = SDLK_KP0;		/* Keypad 0-9 */
+	MISC_keymap[29] = SDLK_KP1;
+	MISC_keymap[30] = SDLK_KP2;
+	MISC_keymap[31] = SDLK_KP3;
+	MISC_keymap[45] = SDLK_KP4;
+	MISC_keymap[46] = SDLK_KP5;
+	MISC_keymap[47] = SDLK_KP6;
+	MISC_keymap[61] = SDLK_KP7;
+	MISC_keymap[62] = SDLK_KP8;
+	MISC_keymap[63] = SDLK_KP9;
+	MISC_keymap[60] = SDLK_KP_PERIOD;
+	MISC_keymap[92] = SDLK_KP_DIVIDE;
+	MISC_keymap[93] = SDLK_KP_MULTIPLY;
+	MISC_keymap[74] = SDLK_KP_MINUS;
+	MISC_keymap[94] = SDLK_KP_PLUS;
+	MISC_keymap[67] = SDLK_KP_ENTER;
+//	MISC_keymap[XK_KP_Equal&0xFF] = SDLK_KP_EQUALS;
+
+	MISC_keymap[76] = SDLK_UP;
+	MISC_keymap[77] = SDLK_DOWN;
+	MISC_keymap[78] = SDLK_RIGHT;
+	MISC_keymap[79] = SDLK_LEFT;
+/*
+	MISC_keymap[XK_Insert&0xFF] = SDLK_INSERT;
+	MISC_keymap[XK_Home&0xFF] = SDLK_HOME;
+	MISC_keymap[XK_End&0xFF] = SDLK_END;
+*/
+// Mappati sulle parentesi del taastierino
+	MISC_keymap[90] = SDLK_PAGEUP;
+	MISC_keymap[91] = SDLK_PAGEDOWN;
+
+	MISC_keymap[80] = SDLK_F1;
+	MISC_keymap[81] = SDLK_F2;
+	MISC_keymap[82] = SDLK_F3;
+	MISC_keymap[83] = SDLK_F4;
+	MISC_keymap[84] = SDLK_F5;
+	MISC_keymap[85] = SDLK_F6;
+	MISC_keymap[86] = SDLK_F7;
+	MISC_keymap[87] = SDLK_F8;
+	MISC_keymap[88] = SDLK_F9;
+	MISC_keymap[89] = SDLK_F10;
+//	MISC_keymap[XK_F11&0xFF] = SDLK_F11;
+//	MISC_keymap[XK_F12&0xFF] = SDLK_F12;
+//	MISC_keymap[XK_F13&0xFF] = SDLK_F13;
+//	MISC_keymap[XK_F14&0xFF] = SDLK_F14;
+//	MISC_keymap[XK_F15&0xFF] = SDLK_F15;
+
+//	MISC_keymap[XK_Num_Lock&0xFF] = SDLK_NUMLOCK;
+	MISC_keymap[98] = SDLK_CAPSLOCK;
+//	MISC_keymap[XK_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
+	MISC_keymap[97] = SDLK_RSHIFT;
+	MISC_keymap[96] = SDLK_LSHIFT;
+	MISC_keymap[99] = SDLK_LCTRL;
+	MISC_keymap[99] = SDLK_LCTRL;
+	MISC_keymap[101] = SDLK_RALT;
+	MISC_keymap[100] = SDLK_LALT;
+//	MISC_keymap[XK_Meta_R&0xFF] = SDLK_RMETA;
+//	MISC_keymap[XK_Meta_L&0xFF] = SDLK_LMETA;
+	MISC_keymap[103] = SDLK_LSUPER; /* Left "Windows" */
+	MISC_keymap[102] = SDLK_RSUPER; /* Right "Windows */
+
+	MISC_keymap[95] = SDLK_HELP;
+}
+
+SDL_keysym *amiga_TranslateKey(int code, SDL_keysym *keysym)
+{
+	static struct Library *ConsoleDevice=NULL;
+
+	/* Get the raw keyboard scancode */
+	keysym->scancode = code;
+	keysym->sym = MISC_keymap[code];
+
+#ifdef DEBUG_KEYS
+	fprintf(stderr, "Translating key 0x%.4x (%d)\n", xsym, xkey->keycode);
+#endif
+	/* Get the translated SDL virtual keysym */
+	if ( keysym->sym==SDLK_UNKNOWN ) 
+	{
+		if(!ConsoleDevice)
+		{
+			if(ConPort=CreateMsgPort())
+			{
+				if(ConReq=CreateIORequest(ConPort,sizeof(struct IOStdReq)))
+				{
+					if(!OpenDevice("console.device",-1,(struct IORequest *)ConReq,0))
+						ConsoleDevice=(struct Library *)ConReq->io_Device;
+					else
+					{
+						DeleteIORequest(ConReq);
+						ConReq=NULL;
+					}
+				}
+				else
+				{
+					DeleteMsgPort(ConPort);
+					ConPort=NULL;
+				}
+			}
+		}
+
+		if(ConsoleDevice)
+		{
+			struct InputEvent event;
+			long actual;
+			char buffer[5];
+
+			event.ie_Qualifier=0;
+			event.ie_Class=IECLASS_RAWKEY;
+			event.ie_SubClass=0L;
+			event.ie_Code=code;
+			event.ie_X=event.ie_Y=0;
+			event.ie_EventAddress=NULL;
+			event.ie_NextEvent=NULL;
+			event.ie_Prev1DownCode=event.ie_Prev1DownQual=event.ie_Prev2DownCode=event.ie_Prev2DownQual=0;
+
+			if( (actual=RawKeyConvert(&event,buffer,5,NULL))>=0)
+			{
+				if(actual>1)
+				{
+					D(bug("Warning (%ld) character conversion!\n",actual));
+				}
+				else if(actual==1)
+				{
+					keysym->sym=*buffer;
+					D(bug("Converted rawcode %ld to <%lc>\n",code,*buffer));
+// Bufferizzo x le successive chiamate!
+					MISC_keymap[code]=*buffer;
+				}
+			}
+		}
+
+	}
+	keysym->mod = KMOD_NONE;
+
+	/* If UNICODE is on, get the UNICODE value for the key */
+	keysym->unicode = 0;
+	if ( SDL_TranslateUNICODE ) {
+#if 0
+		static XComposeStatus state;
+		/* Until we handle the IM protocol, use XLookupString() */
+		unsigned char keybuf[32];
+		if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf),
+							NULL, &state) ) {
+			keysym->unicode = keybuf[0];
+		}
+#endif
+	}
+	return(keysym);
+}
+
+void amiga_InitOSKeymap(_THIS)
+{
+	amiga_InitKeymap();
+}