src/video/cybergfx/SDL_amigaevents.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. amiga_WarpedMotion
  2. amiga_GetButton
  3. amiga_DispatchEvent
  4. amiga_PumpEvents
  5. amiga_InitKeymap
  6. amiga_TranslateKey
  7. amiga_InitOSKeymap

   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: SDL_amigaevents.c,v 1.1.2.2 2001/02/10 07:20:06 hercules Exp $";
  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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 516 {
 517         amiga_InitKeymap();
 518 }

/* [<][>][^][v][top][bottom][index][help] */