src/video/photon/SDL_ph_events.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 04 Aug 2003 00:52:42 +0000
changeset 663 8bedd6d61642
parent 571 8e3ce997621c
child 753 b14fdadd8311
permissions -rw-r--r--
Date: Sat, 2 Aug 2003 16:22:51 +0300
From: "Mike Gorchak"
Subject: New patches for QNX6

Here my patches for the SDL/QNX:

QNXSDL.diff - diff to non-QNX related sources:

- updated BUGS file, I think QNX6 is now will be officially supported
- configure.in - added shared library support for QNX, and removed dependency between the ALSA and QNX6.
- SDL_audio.c - added QNX NTO sound bootstrap insted of ALSA's.
- SDL_sysaudio.h - the same.
- SDL_nto_audio.c - the same.
- SDL_video.c - right now, QNX doesn't offer any method to obtain pointers to the OpenGL functions by function name, so they must be hardcoded in library, otherwise OpenGL will not be supported.
- testsprite.c - fixed: do not draw vertical red line if we are in non-double-buffered mode.

sdlqnxph.tar.gz - archive of the ./src/video/photon/* . Too many changes in code to make diffs :) :

+ Added stub for support hide/unhide window event
+ Added full YUV overlays support.
+ Added window maximize support.
+ Added mouse wheel events.
+ Added support for some specific key codes in Unicode mode (like ESC).
+ Added more checks to the all memory allocation code.
+ Added SDL_DOUBLEBUF support in all fullscreen modes.
+ Added fallback to window mode, if desired fullscreen mode is not supported.
+ Added stub support for the GL_LoadLibrary and GL_GetProcAddress functions.
+ Added resizable window support without caption.
! Fixed bug in the Ph_EV_EXPOSE event handler, when rectangles to update is 0 and when width or height of the rectangle is 0.
! Fixed bug in the event handler code. Events has not been passed to the window widget handler.
! Fixed codes for Win keys (Super/Hyper/Menu).
! Fixed memory leak, when deallocation palette.
! Fixed palette emulation code bugs.
! Fixed fullscreen and hwsurface handling.
! Fixed CLOSE button bug. First event was passed to the handler, but second terminated the application. Now all events passed to the application correctly.
- Removed all printfs in code, now SDL_SetError used instead of them.
- Disabled ToggleFullScreen function.

README.QNX - updated README.QNX file. Added much more issues.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  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@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 /* Handle the event stream, converting photon events into SDL events */
    29 
    30 #define DISABLE_X11
    31 
    32 #include <stdio.h>
    33 #include <setjmp.h>
    34 #include <sys/time.h>
    35 
    36 #include <Ph.h>
    37 #include <photon/PkKeyDef.h>
    38 
    39 #include "SDL.h"
    40 #include "SDL_syswm.h"
    41 #include "SDL_sysevents.h"
    42 #include "SDL_sysvideo.h"
    43 #include "SDL_events_c.h"
    44 #include "SDL_ph_video.h"
    45 #include "SDL_ph_modes_c.h"
    46 #include "SDL_ph_image_c.h"
    47 #include "SDL_ph_events_c.h"
    48 #include "SDL_phyuv_c.h"
    49 
    50 
    51 
    52 /* The translation tables from a photon keysym to a SDL keysym */
    53 static SDLKey ODD_keymap[256];
    54 static SDLKey MISC_keymap[0xFF + 1];
    55 SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym);
    56 
    57 /* Check to see if this is a repeated key.
    58    (idea shamelessly lifted from GII -- thanks guys! :)
    59  */
    60 
    61 static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent)
    62 {
    63     PhRect_t *rect = PhGetRects( winEvent );
    64 
    65     int centre_x, centre_y;
    66     int dx, dy;
    67     short abs_x, abs_y;
    68     int posted;
    69 
    70     centre_x = SDL_VideoSurface->w / 2;
    71     centre_y = SDL_VideoSurface->h / 2;
    72 
    73     dx = rect->ul.x - centre_x;
    74     dy = rect->ul.y - centre_y;
    75 
    76     posted = SDL_PrivateMouseMotion( 0, 1, dx, dy );
    77 
    78     /* Move mouse cursor to middle of the window */
    79     PtGetAbsPosition( window, &abs_x, &abs_y );
    80     PhMoveCursorAbs(PhInputGroup(NULL), abs_x + centre_x, abs_y + centre_y);
    81 
    82     return (posted);
    83 }
    84 
    85 /* Control which motion flags the window has set, a flags value of -1 sets
    86  * MOTION_BUTTON and MOTION_NOBUTTON */
    87 
    88 static void set_motion_sensitivity(_THIS, unsigned int flags)
    89 {
    90     int rid;
    91     int fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON;
    92     PhRegion_t region;
    93 
    94     if( window )
    95     {
    96         rid = PtWidgetRid(window);
    97         if( rid != 0 && PhRegionQuery(rid, &region, NULL, NULL, 0) == 0 )
    98         {
    99             region.events_sense=(region.events_sense & ~fields)|(flags & fields);
   100             PhRegionChange(Ph_REGION_EV_SENSE, 0, &region, NULL, NULL);
   101         }
   102     }
   103 }
   104 
   105 /* Convert the photon button state value to an SDL value */
   106 static Uint8 ph2sdl_mousebutton(unsigned short button_state)
   107 {
   108     Uint8 mouse_button = 0;
   109 
   110     if (button_state & Ph_BUTTON_SELECT)
   111         mouse_button |= SDL_BUTTON_LEFT;
   112     if (button_state & Ph_BUTTON_MENU)
   113         mouse_button |= SDL_BUTTON_RIGHT;
   114     if (button_state & Ph_BUTTON_ADJUST)
   115         mouse_button |= SDL_BUTTON_MIDDLE;
   116 
   117     return (mouse_button);
   118 }
   119 
   120 //                   void* PtAppCreateContext();
   121 
   122 static int ph_DispatchEvent(_THIS)
   123 {
   124     int posted;
   125     PhRect_t* rect;
   126     PhPointerEvent_t* pointerEvent;
   127     PhKeyEvent_t* keyEvent;
   128     PhWindowEvent_t* winEvent;
   129     int i, buttons;
   130     SDL_Rect sdlrects[50]; 
   131 	
   132     posted = 0;
   133 	
   134     switch (event->type)
   135     {
   136         case Ph_EV_BOUNDARY:
   137         {
   138             if (event->subtype == Ph_EV_PTR_ENTER)
   139             {
   140                 posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
   141             }
   142             else if (event->subtype ==Ph_EV_PTR_LEAVE)
   143             {
   144                 posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);	
   145             }
   146         }
   147         break;
   148 
   149         case Ph_EV_PTR_MOTION_BUTTON:
   150         case Ph_EV_PTR_MOTION_NOBUTTON:
   151         {
   152             if (SDL_VideoSurface)
   153             {
   154                 pointerEvent = PhGetData(event);
   155                 rect = PhGetRects(event);
   156 
   157                 if (mouse_relative)
   158                 {
   159                     posted = ph_WarpedMotion(this, event);
   160                 }
   161                 else
   162                 {
   163                     posted = SDL_PrivateMouseMotion(0, 0, rect->ul.x, rect->ul.y);
   164                 }
   165             }
   166         }
   167         break;
   168 
   169         case Ph_EV_BUT_PRESS:
   170         {
   171             pointerEvent = PhGetData( event );
   172             buttons = ph2sdl_mousebutton( pointerEvent->buttons );
   173             if (buttons != 0)
   174             {
   175                 posted = SDL_PrivateMouseButton(SDL_PRESSED, buttons, 0, 0);
   176             }
   177         }
   178         break;
   179 
   180         case Ph_EV_BUT_RELEASE:
   181         {
   182             pointerEvent = PhGetData(event);
   183             buttons = ph2sdl_mousebutton(pointerEvent->buttons);
   184             if (event->subtype == Ph_EV_RELEASE_REAL && buttons != 0)
   185             {
   186                 posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0);
   187             }
   188             else if(event->subtype == Ph_EV_RELEASE_PHANTOM)
   189             {
   190                 /* If the mouse is outside the window,
   191                  * only a phantom release event is sent, so
   192                  * check if the window doesn't have mouse focus.
   193                  * Not perfect, maybe checking the mouse button
   194                  * state for Ph_EV_BOUNDARY events would be
   195                  * better. */
   196                 if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) == 0)
   197 		{
   198                     posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0);
   199                 }
   200             }
   201         }
   202         break;
   203 
   204         case Ph_EV_WM:
   205         {
   206             winEvent = PhGetData(event);
   207 
   208             /* losing focus */
   209             if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUSLOST))
   210             {
   211                 set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON);
   212                 posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);	
   213             }
   214             /* gaining focus */
   215             else if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUS))
   216             {
   217                 set_motion_sensitivity(this, -1);
   218                 posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
   219             }
   220             /* request to quit */
   221             else if (winEvent->event_f==Ph_WM_CLOSE)
   222             {
   223                 posted = SDL_PrivateQuit();
   224             }
   225             /* request to hide/unhide */
   226             else if (winEvent->event_f==Ph_WM_HIDE)
   227             {
   228                 if (currently_hided)
   229                 {
   230                    /* got unhide window event                                */
   231                    /* TODO: restore application's palette if in palette mode */
   232                    currently_hided=0;
   233                 }
   234                 else
   235                 {
   236                    /* got hide window event                                  */
   237                    /* TODO: restore original palette if in palette mode      */
   238                    currently_hided=1;
   239                 }
   240             }
   241             /* request to resize */
   242             else if (winEvent->event_f==Ph_WM_RESIZE)
   243             {
   244                 SDL_PrivateResize(winEvent->size.w, winEvent->size.h);
   245             }
   246             /* request to move */
   247             else if (winEvent->event_f==Ph_WM_MOVE)
   248             {
   249                 if (current_overlay!=NULL)
   250                 {
   251                    int lockedstate=current_overlay->hwdata->locked;
   252                    int chromastate=current_overlay->hwdata->ischromakey;
   253                    SDL_Rect target;
   254 
   255                    current_overlay->hwdata->locked=1;
   256                    target.x=current_overlay->hwdata->CurrentViewPort.pos.x;
   257                    target.y=current_overlay->hwdata->CurrentViewPort.pos.y;
   258                    target.w=current_overlay->hwdata->CurrentViewPort.size.w;
   259                    target.h=current_overlay->hwdata->CurrentViewPort.size.h;
   260                    current_overlay->hwdata->ischromakey=0;
   261                    ph_DisplayYUVOverlay(this, current_overlay, &target);
   262                    current_overlay->hwdata->ischromakey=chromastate;
   263                    current_overlay->hwdata->locked=lockedstate;
   264                 }
   265             }
   266             /* request to maximize */
   267             else if (winEvent->event_f==Ph_WM_MAX)
   268             {
   269                 /* window already moved and resized here */
   270                 SDL_PrivateResize(winEvent->size.w-winEvent->pos.x, winEvent->size.h-winEvent->pos.y);
   271             }
   272             /* request to restore */
   273             else if (winEvent->event_f==Ph_WM_RESTORE)
   274             {
   275             }
   276         }
   277         break;
   278 
   279         /* window has been resized, moved or removed */
   280         case Ph_EV_EXPOSE:
   281         {
   282             if (event->num_rects!=0)
   283             {
   284                 if (SDL_VideoSurface)
   285                 {
   286                     rect = PhGetRects(event);
   287 
   288                     for(i=0;i<event->num_rects;i++)
   289                     {
   290                         sdlrects[i].x = rect[i].ul.x;
   291                         sdlrects[i].y = rect[i].ul.y;
   292                         sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1;
   293                         sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1;
   294                     }
   295 
   296                     this->UpdateRects(this, event->num_rects, sdlrects);
   297 
   298                     if (current_overlay!=NULL)
   299                     {
   300                         int lockedstate=current_overlay->hwdata->locked;
   301                         SDL_Rect target;
   302 
   303                         current_overlay->hwdata->locked=1;
   304                         target.x=current_overlay->hwdata->CurrentViewPort.pos.x;
   305                         target.y=current_overlay->hwdata->CurrentViewPort.pos.y;
   306                         target.w=current_overlay->hwdata->CurrentViewPort.size.w;
   307                         target.h=current_overlay->hwdata->CurrentViewPort.size.h;
   308                         current_overlay->hwdata->forcedredraw=1;
   309                         ph_DisplayYUVOverlay(this, current_overlay, &target);
   310                         current_overlay->hwdata->forcedredraw=0;
   311                         current_overlay->hwdata->locked=lockedstate;
   312                     }
   313                 }
   314             }
   315         }
   316 	break;
   317 
   318         case Ph_EV_KEY:
   319         {
   320             SDL_keysym keysym;
   321 
   322             posted = 0;
   323 
   324             keyEvent = PhGetData( event );
   325 
   326             if (Pk_KF_Key_Down & keyEvent->key_flags)
   327             {
   328                 /* split the wheel events from real key events */
   329                 if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   330                 {
   331                    posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
   332                    break;
   333                 }
   334                 if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   335                 {
   336                    posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
   337                    break;
   338                 }
   339                 posted = SDL_PrivateKeyboard(SDL_PRESSED, ph_TranslateKey(keyEvent, &keysym));
   340             }
   341             else /* must be key release */
   342             {
   343                 /* split the wheel events from real key events */
   344                 if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   345                 {
   346                    posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
   347                    break;
   348                 }
   349                 if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   350                 {
   351                    posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
   352                    break;
   353                 }
   354                 posted = SDL_PrivateKeyboard(SDL_RELEASED, ph_TranslateKey( keyEvent, &keysym));
   355             }
   356         }
   357         break;
   358     }
   359 
   360     return(posted);
   361 }
   362 
   363 /* perform a blocking read if no events available */
   364 int ph_Pending(_THIS)
   365 {
   366     /* Flush the display connection and look to see if events are queued */
   367     PgFlush();
   368 
   369     while (1)
   370     {
   371         switch(PhEventPeek(event, EVENT_SIZE))
   372         {
   373             case Ph_EVENT_MSG:
   374                  return 1;
   375                  break;
   376             case -1:
   377                  perror("ph_Pending(): PhEventNext failed");
   378                  break;
   379             default:
   380                  return 0;
   381         }
   382     }
   383 
   384     /* Oh well, nothing is ready .. */
   385     return(0);
   386 }
   387 
   388 void ph_PumpEvents(_THIS)
   389 {
   390     /* Flush the display connection and look to see if events are queued */
   391     PgFlush();
   392 
   393     while (ph_Pending(this))
   394     {
   395         PtEventHandler(event);
   396         ph_DispatchEvent(this);
   397     }
   398 }
   399 
   400 void ph_InitKeymap(void)
   401 {
   402     int i;
   403 
   404     /* Odd keys used in international keyboards */
   405     for (i=0; i<SDL_TABLESIZE(ODD_keymap); ++i)
   406     {
   407         ODD_keymap[i] = SDLK_UNKNOWN;
   408     }
   409 
   410     /* Map the miscellaneous keys */
   411     for (i=0; i<SDL_TABLESIZE(MISC_keymap); ++i)
   412     {
   413         MISC_keymap[i] = SDLK_UNKNOWN;
   414     }
   415 
   416     MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE;
   417     MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB;
   418     MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR;
   419     MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN;
   420     MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE;
   421     MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE;
   422     MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE;
   423 
   424     MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0;
   425     MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1;
   426     MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2;
   427     MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3;
   428     MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4;
   429     MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5;
   430     MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6;
   431     MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7;
   432     MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8;
   433     MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9;
   434 
   435     MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD;
   436     MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE;
   437     MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY;
   438     MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS;
   439     MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS;
   440     MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER;
   441     MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS;
   442 
   443     MISC_keymap[Pk_Up&0xFF] = SDLK_UP;
   444     MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN;
   445     MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT;
   446     MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT;
   447     MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT;
   448     MISC_keymap[Pk_Home&0xFF] = SDLK_HOME;
   449     MISC_keymap[Pk_End&0xFF] = SDLK_END;
   450     MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP;
   451     MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN;
   452 
   453     MISC_keymap[Pk_F1&0xFF] = SDLK_F1;
   454     MISC_keymap[Pk_F2&0xFF] = SDLK_F2;
   455     MISC_keymap[Pk_F3&0xFF] = SDLK_F3;
   456     MISC_keymap[Pk_F4&0xFF] = SDLK_F4;
   457     MISC_keymap[Pk_F5&0xFF] = SDLK_F5;
   458     MISC_keymap[Pk_F6&0xFF] = SDLK_F6;
   459     MISC_keymap[Pk_F7&0xFF] = SDLK_F7;
   460     MISC_keymap[Pk_F8&0xFF] = SDLK_F8;
   461     MISC_keymap[Pk_F9&0xFF] = SDLK_F9;
   462     MISC_keymap[Pk_F10&0xFF] = SDLK_F10;
   463     MISC_keymap[Pk_F11&0xFF] = SDLK_F11;
   464     MISC_keymap[Pk_F12&0xFF] = SDLK_F12;
   465     MISC_keymap[Pk_F13&0xFF] = SDLK_F13;
   466     MISC_keymap[Pk_F14&0xFF] = SDLK_F14;
   467     MISC_keymap[Pk_F15&0xFF] = SDLK_F15;
   468 
   469     MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK;
   470     MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK;
   471     MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
   472     MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT;
   473     MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT;
   474     MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL;
   475     MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL;
   476     MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT;
   477     MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT;
   478     MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA;
   479     MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA;
   480     MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER;
   481     MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER;
   482     MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key    */
   483 
   484     MISC_keymap[Pk_Help&0xFF] = SDLK_HELP;
   485     MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT;
   486     MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK;
   487     MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU;        /* Windows "Menu" key */
   488 
   489     MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_RSUPER;   /* Right "Windows" */
   490 
   491     /* Left "Windows" key, but it can't be catched by application */
   492     MISC_keymap[Pk_Hyper_L&0xFF] = SDLK_LSUPER;
   493 }
   494 
   495 static unsigned long cap;
   496 
   497 SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym)
   498 {
   499     /* 'sym' is set to the value of the key with modifiers applied to it.
   500        This member is valid only if Pk_KF_Sym_Valid is set in the key_flags.
   501        We will assume it is valid. */
   502 
   503     /* FIXME: This needs to check whether the cap & scancode is valid */
   504 
   505     cap = key->key_cap;
   506 
   507     switch (cap>>8)
   508     {
   509         case 0x00:  /* Latin 1 */
   510         case 0x01:  /* Latin 2 */
   511         case 0x02:  /* Latin 3 */
   512         case 0x03:  /* Latin 4 */
   513         case 0x04:  /* Katakana */
   514         case 0x05:  /* Arabic */
   515         case 0x06:  /* Cyrillic */
   516         case 0x07:  /* Greek */
   517         case 0x08:  /* Technical */
   518         case 0x0A:  /* Publishing */
   519         case 0x0C:  /* Hebrew */
   520         case 0x0D:  /* Thai */
   521                    keysym->sym = (SDLKey)(cap&0xFF);
   522                    /* Map capital letter syms to lowercase */
   523                    if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
   524                        keysym->sym += ('a'-'A');
   525                    break;
   526         case 0xF0:
   527                    keysym->sym = MISC_keymap[cap&0xFF];
   528                    break;
   529         default:
   530                    keysym->sym = SDLK_UNKNOWN;                
   531                    break;
   532     }
   533 
   534     keysym->scancode = key->key_scan;
   535     keysym->unicode = 0;
   536 
   537     if (SDL_TranslateUNICODE)
   538     {
   539         char utf8[MB_CUR_MAX];
   540         int utf8len;
   541         wchar_t unicode;
   542 
   543         switch (keysym->scancode)
   544         {
   545            case 0x01: keysym->unicode = 27;
   546                       break;
   547            default:
   548                       utf8len = PhKeyToMb(utf8, key);
   549                       if (utf8len > 0)
   550                       {
   551                           utf8len = mbtowc(&unicode, utf8, utf8len);
   552                          if (utf8len > 0)
   553                          {
   554                              keysym->unicode = unicode;
   555                          }
   556                       }
   557                       break;
   558         }
   559 
   560     }
   561 
   562     return (keysym);
   563 }
   564 
   565 void ph_InitOSKeymap(_THIS)
   566 {
   567     ph_InitKeymap();
   568 }