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