slouken@281: /* slouken@281: SDL - Simple DirectMedia Layer slouken@769: Copyright (C) 1997-2004 Sam Lantinga slouken@281: slouken@281: This library is free software; you can redistribute it and/or slouken@281: modify it under the terms of the GNU Library General Public slouken@281: License as published by the Free Software Foundation; either slouken@281: version 2 of the License, or (at your option) any later version. slouken@281: slouken@281: This library is distributed in the hope that it will be useful, slouken@281: but WITHOUT ANY WARRANTY; without even the implied warranty of slouken@281: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU slouken@281: Library General Public License for more details. slouken@281: slouken@281: You should have received a copy of the GNU Library General Public slouken@281: License along with this library; if not, write to the Free slouken@281: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA slouken@281: slouken@281: Sam Lantinga slouken@281: slouken@libsdl.org slouken@281: */ slouken@281: slouken@281: #ifdef SAVE_RCSID slouken@281: static char rcsid = slouken@281: "@(#) $Id$"; slouken@281: #endif slouken@281: slouken@281: /* slouken@281: * GEM SDL video driver implementation slouken@281: * inspired from the Dummy SDL driver slouken@281: * slouken@281: * Patrice Mandin slouken@281: * and work from slouken@281: * Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard slouken@281: */ slouken@281: slouken@281: #include slouken@281: slouken@281: #include slouken@281: slouken@281: #include "SDL.h" slouken@281: #include "SDL_sysevents.h" slouken@281: #include "SDL_events_c.h" slouken@281: #include "SDL_gemvideo.h" slouken@281: #include "SDL_gemevents_c.h" slouken@319: #include "SDL_atarikeys.h" /* for keyboard scancodes */ slouken@319: #include "SDL_xbiosinterrupt_s.h" slouken@281: slouken@281: /* Defines */ slouken@281: slouken@281: #define ATARIBIOS_MAXKEYS 128 slouken@281: slouken@281: /* Variables */ slouken@281: slouken@281: static unsigned char gem_currentkeyboard[ATARIBIOS_MAXKEYS]; slouken@281: static unsigned char gem_previouskeyboard[ATARIBIOS_MAXKEYS]; slouken@281: static unsigned char gem_currentascii[ATARIBIOS_MAXKEYS]; slouken@281: slouken@281: /* The translation tables from a console scancode to a SDL keysym */ slouken@281: static SDLKey keymap[ATARIBIOS_MAXKEYS]; slouken@281: slouken@281: /* Functions prototypes */ slouken@281: slouken@281: static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym); slouken@281: static int do_messages(_THIS, short *message); slouken@281: static void do_keyboard(short kc, short ks); slouken@319: static void do_mouse(_THIS, short mx, short my, short mb, short ks); slouken@281: slouken@281: /* Functions */ slouken@281: slouken@281: static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym) slouken@281: { slouken@281: /* Set the keysym information */ slouken@281: keysym->scancode = scancode; slouken@281: slouken@281: if (asciicode) slouken@281: keysym->sym = asciicode; slouken@281: else slouken@281: keysym->sym = keymap[scancode]; slouken@281: slouken@281: keysym->mod = KMOD_NONE; slouken@281: keysym->unicode = 0; slouken@281: slouken@281: return(keysym); slouken@281: } slouken@281: slouken@281: void GEM_InitOSKeymap(_THIS) slouken@281: { slouken@281: int i; slouken@281: slouken@281: memset(gem_currentkeyboard, 0, sizeof(gem_currentkeyboard)); slouken@281: memset(gem_previouskeyboard, 0, sizeof(gem_previouskeyboard)); slouken@281: memset(gem_currentascii, 0, sizeof(gem_currentascii)); slouken@281: slouken@281: /* Initialize keymap */ slouken@281: for ( i=0; i=0)) { patmandin@1067: wind_get (GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2); patmandin@1067: event_mask |= MU_M1|MU_M2; patmandin@1067: } else { patmandin@1067: x2=y2=w2=h2=0; patmandin@1067: } patmandin@1067: slouken@281: resultat = evnt_multi( patmandin@1067: event_mask, slouken@281: 0,0,0, patmandin@1067: MO_ENTER,x2,y2,w2,h2, patmandin@1067: MO_LEAVE,x2,y2,w2,h2, slouken@281: buffer, slouken@281: 10, slouken@319: &dummy,&dummy,&dummy,&kstate,&kc,&dummy slouken@281: ); slouken@281: slouken@281: /* Message event ? */ slouken@281: if (resultat & MU_MESAG) slouken@281: quit = do_messages(this, buffer); slouken@281: slouken@281: /* Keyboard event ? */ slouken@319: if (resultat & MU_KEYBD) { slouken@319: if ((prevkc != kc) || (prevks != kstate)) { slouken@319: do_keyboard(kc,kstate); slouken@319: } else { slouken@319: /* Avoid looping, if repeating same key */ slouken@319: break; slouken@319: } slouken@319: } slouken@281: patmandin@1067: /* Mouse entering/leaving window */ patmandin@1067: if (resultat & MU_M1) { patmandin@1067: if (this->input_grab == SDL_GRAB_OFF) { patmandin@1088: if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { patmandin@1088: SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); patmandin@1088: } patmandin@1067: } patmandin@1067: } patmandin@1067: if (resultat & MU_M2) { patmandin@1067: if (this->input_grab == SDL_GRAB_OFF) { patmandin@1088: if ( (SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { patmandin@1088: SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); patmandin@1088: ] patmandin@1067: } patmandin@1067: } patmandin@1067: slouken@281: /* Timer event ? */ slouken@281: if ((resultat & MU_TIMER) || quit) slouken@281: break; slouken@281: } slouken@281: slouken@281: /* Update mouse */ slouken@319: graf_mkstate(&mousex, &mousey, &mouseb, &kstate); slouken@319: do_mouse(this, mousex, mousey, mouseb, kstate); slouken@281: slouken@319: /* Now generate keyboard events */ slouken@281: for (i=0; i>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0); patmandin@996: } patmandin@996: } else { patmandin@996: /* Iconified */ patmandin@996: if (GEM_icon_name) { patmandin@996: wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_icon_name)>>16),(short)(((unsigned long)GEM_icon_name) & 0xffff),0,0); patmandin@996: } patmandin@996: } patmandin@996: GEM_refresh_name = SDL_FALSE; patmandin@996: } slouken@281: } slouken@281: slouken@281: static int do_messages(_THIS, short *message) slouken@281: { slouken@281: int quit, posted; patmandin@922: short x2,y2,w2,h2; slouken@281: slouken@281: quit=0; slouken@281: switch (message[0]) { slouken@281: case WM_CLOSED: slouken@281: case AP_TERM: slouken@281: posted = SDL_PrivateQuit(); slouken@281: quit=1; slouken@281: break; slouken@281: case WM_MOVED: slouken@281: wind_set(message[3],WF_CURRXYWH,message[4],message[5],message[6],message[7]); slouken@281: break; slouken@281: case WM_TOPPED: slouken@281: wind_set(message[3],WF_TOP,message[4],0,0,0); slouken@281: SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); patmandin@1074: if (VDI_setpalette) { patmandin@1074: VDI_setpalette(this, VDI_curpalette); patmandin@1074: } slouken@281: break; slouken@281: case WM_REDRAW: patmandin@964: if (!GEM_lock_redraw) { patmandin@964: GEM_wind_redraw(this, message[3],&message[4]); patmandin@964: } slouken@281: break; slouken@281: case WM_ICONIFY: slouken@281: case WM_ALLICONIFY: slouken@281: wind_set(message[3],WF_ICONIFY,message[4],message[5],message[6],message[7]); slouken@281: /* If we're active, make ourselves inactive */ slouken@281: if ( SDL_GetAppState() & SDL_APPACTIVE ) { slouken@281: /* Send an internal deactivate event */ patmandin@1088: SDL_PrivateAppActive(0, SDL_APPACTIVE); slouken@281: } patmandin@736: /* Update window title */ patmandin@736: if (GEM_refresh_name && GEM_icon_name) { patmandin@736: wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_icon_name)>>16),(short)(((unsigned long)GEM_icon_name) & 0xffff),0,0); patmandin@736: GEM_refresh_name = SDL_FALSE; patmandin@736: } slouken@281: break; slouken@281: case WM_UNICONIFY: slouken@281: wind_set(message[3],WF_UNICONIFY,message[4],message[5],message[6],message[7]); slouken@281: /* If we're not active, make ourselves active */ slouken@281: if ( !(SDL_GetAppState() & SDL_APPACTIVE) ) { slouken@281: /* Send an internal activate event */ slouken@281: SDL_PrivateAppActive(1, SDL_APPACTIVE); slouken@281: } patmandin@736: if (GEM_refresh_name && GEM_title_name) { patmandin@736: wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0); patmandin@736: GEM_refresh_name = SDL_FALSE; patmandin@736: } slouken@281: break; slouken@281: case WM_SIZED: slouken@281: wind_set (message[3], WF_CURRXYWH, message[4], message[5], message[6], message[7]); patmandin@964: wind_get (message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2); slouken@281: GEM_win_fulled = SDL_FALSE; /* Cancel maximized flag */ patmandin@964: GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers resized */ patmandin@922: SDL_PrivateResize(w2, h2); slouken@281: break; slouken@281: case WM_FULLED: slouken@281: { slouken@281: short x,y,w,h; slouken@281: slouken@281: if (GEM_win_fulled) { slouken@281: wind_get (message[3], WF_PREVXYWH, &x, &y, &w, &h); slouken@281: GEM_win_fulled = SDL_FALSE; slouken@281: } else { slouken@281: x = GEM_desk_x; slouken@281: y = GEM_desk_y; slouken@281: w = GEM_desk_w; slouken@281: h = GEM_desk_h; slouken@281: GEM_win_fulled = SDL_TRUE; slouken@281: } slouken@281: wind_set (message[3], WF_CURRXYWH, x, y, w, h); patmandin@922: wind_get (message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2); patmandin@964: GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers resized */ patmandin@922: SDL_PrivateResize(w2, h2); slouken@281: } slouken@281: break; slouken@281: case WM_BOTTOMED: slouken@281: case WM_UNTOPPED: slouken@281: SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); patmandin@1074: if (VDI_setpalette) { patmandin@1074: VDI_setpalette(this, VDI_oldpalette); patmandin@1074: } slouken@281: break; slouken@281: } slouken@281: slouken@281: return quit; slouken@281: } slouken@281: slouken@281: static void do_keyboard(short kc, short ks) slouken@281: { slouken@281: int scancode, asciicode; slouken@281: slouken@281: if (kc) { slouken@281: scancode=(kc>>8) & 127; slouken@281: asciicode=kc & 255; slouken@281: slouken@281: gem_currentkeyboard[scancode]=0xFF; slouken@281: gem_currentascii[scancode]=asciicode; slouken@281: } slouken@281: slouken@281: /* Read special keys */ slouken@281: if (ks & K_RSHIFT) slouken@281: gem_currentkeyboard[SCANCODE_RIGHTSHIFT]=0xFF; slouken@281: if (ks & K_LSHIFT) slouken@281: gem_currentkeyboard[SCANCODE_LEFTSHIFT]=0xFF; slouken@281: if (ks & K_CTRL) slouken@281: gem_currentkeyboard[SCANCODE_LEFTCONTROL]=0xFF; slouken@281: if (ks & K_ALT) slouken@281: gem_currentkeyboard[SCANCODE_LEFTALT]=0xFF; slouken@281: } slouken@281: slouken@319: static void do_mouse(_THIS, short mx, short my, short mb, short ks) slouken@281: { slouken@319: static short prevmousex=0, prevmousey=0, prevmouseb=0; patmandin@926: short x2, y2, w2, h2; patmandin@926: patmandin@1067: /* Don't return mouse events if out of window */ patmandin@1067: if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS)==0) { patmandin@1067: return; patmandin@1067: } patmandin@1067: patmandin@926: /* Retrieve window coords, and generate mouse events accordingly */ patmandin@926: x2 = y2 = 0; patmandin@928: w2 = VDI_w; patmandin@928: h2 = VDI_h; patmandin@926: if ((!GEM_fullscreen) && (GEM_handle>=0)) { patmandin@926: wind_get (GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2); patmandin@926: patmandin@926: /* Do not generate mouse button event if out of window working area */ patmandin@926: if ((mx=x2+w2) || (my=y2+h2)) { patmandin@926: mb=prevmouseb; patmandin@926: } patmandin@926: } slouken@319: slouken@281: /* Mouse motion ? */ slouken@281: if ((prevmousex!=mx) || (prevmousey!=my)) { slouken@281: if (GEM_mouse_relative) { slouken@319: SDL_PrivateMouseMotion(0, 1, SDL_AtariXbios_mousex, SDL_AtariXbios_mousey); slouken@319: SDL_AtariXbios_mousex = SDL_AtariXbios_mousey = 0; slouken@281: } else { patmandin@926: int posx, posy; patmandin@926: patmandin@926: /* Give mouse position relative to window position */ patmandin@926: posx = mx - x2; patmandin@927: if (posx<0) posx = 0; patmandin@926: if (posx>w2) posx = w2-1; patmandin@926: posy = my - y2; patmandin@927: if (posy<0) posy = 0; patmandin@926: if (posy>h2) posy = h2-1; patmandin@926: patmandin@926: SDL_PrivateMouseMotion(0, 0, posx, posy); slouken@281: } slouken@281: prevmousex = mx; slouken@281: prevmousey = my; slouken@281: } slouken@281: slouken@281: /* Mouse button ? */ slouken@281: if (prevmouseb!=mb) { slouken@281: int i; slouken@281: slouken@319: for (i=0;i<2;i++) { slouken@281: int curbutton, prevbutton; slouken@281: slouken@281: curbutton = mb & (1<