src/video/photon/SDL_ph_events.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 10 Dec 2003 12:35:56 +0000
changeset 753 b14fdadd8311
parent 663 8bedd6d61642
child 769 b8d311d90021
permissions -rw-r--r--
Date: Thu, 4 Dec 2003 07:48:40 +0200
From: "Mike Gorchak"
Subject: SDL/QNX6 new patch

Here in attachment my patch for the SDL/QNX6 again :) It contain non-crtitical/cosmetic fixes:

1. Fixed window centering at other than the first consoles.
2. Fixed window centering algorithm in case when window height or width are greater than the desktop resolution.
3. Fixed window positioning on other than the first consoles.
4. Fixed occasional input focus lost when switching to fullscreen.
5. Removed the Photon's default chroma color for the overlays, added RGB(12, 6, 12) color instead (very dark pink).
6. Added more checks to the YUV overlay code (fixed crashes during resolution mode switches).
7. Added support for Enter/Backspace keys in unicode mode (used by Maelstrom and by other games).
8. Fixed window restore/maximize function. It works, finally.
     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             /* quit request */
   221             else if (winEvent->event_f==Ph_WM_CLOSE)
   222             {
   223                 posted = SDL_PrivateQuit();
   224             }
   225             /* hide/unhide request */
   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+1, winEvent->size.h+1);
   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                    int error;
   254                    SDL_Rect target;
   255 
   256                    current_overlay->hwdata->locked=1;
   257                    target.x=current_overlay->hwdata->CurrentViewPort.pos.x;
   258                    target.y=current_overlay->hwdata->CurrentViewPort.pos.y;
   259                    target.w=current_overlay->hwdata->CurrentViewPort.size.w;
   260                    target.h=current_overlay->hwdata->CurrentViewPort.size.h;
   261                    current_overlay->hwdata->ischromakey=0;
   262                    error=ph_DisplayYUVOverlay(this, current_overlay, &target);
   263                    if (!error)
   264                    {
   265                        current_overlay->hwdata->ischromakey=chromastate;
   266                        current_overlay->hwdata->locked=lockedstate;
   267                    }
   268                 }
   269             }
   270             /* maximize request */
   271             else if (winEvent->event_f==Ph_WM_MAX)
   272             {
   273                 /* window already moved and resized here */
   274                 currently_maximized=1;
   275             }
   276             /* restore request */
   277             else if (winEvent->event_f==Ph_WM_RESTORE)
   278             {
   279                 /* window already moved and resized here */
   280                 currently_maximized=0;
   281             }
   282         }
   283         break;
   284 
   285         /* window has been resized, moved or removed */
   286         case Ph_EV_EXPOSE:
   287         {
   288             if (event->num_rects!=0)
   289             {
   290                 if (SDL_VideoSurface)
   291                 {
   292                     rect = PhGetRects(event);
   293 
   294                     for(i=0; i<event->num_rects; i++)
   295                     {
   296                         sdlrects[i].x = rect[i].ul.x;
   297                         sdlrects[i].y = rect[i].ul.y;
   298                         sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1;
   299                         sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1;
   300                     }
   301 
   302                     this->UpdateRects(this, event->num_rects, sdlrects);
   303 
   304                     if (current_overlay!=NULL)
   305                     {
   306                         int lockedstate=current_overlay->hwdata->locked;
   307                         int error;
   308                         SDL_Rect target;
   309 
   310                         current_overlay->hwdata->locked=1;
   311                         target.x=current_overlay->hwdata->CurrentViewPort.pos.x;
   312                         target.y=current_overlay->hwdata->CurrentViewPort.pos.y;
   313                         target.w=current_overlay->hwdata->CurrentViewPort.size.w;
   314                         target.h=current_overlay->hwdata->CurrentViewPort.size.h;
   315                         current_overlay->hwdata->forcedredraw=1;
   316                         error=ph_DisplayYUVOverlay(this, current_overlay, &target);
   317                         if (!error)
   318                         {
   319                             current_overlay->hwdata->forcedredraw=0;
   320                             current_overlay->hwdata->locked=lockedstate;
   321                         }
   322                     }
   323                 }
   324             }
   325         }
   326 	break;
   327 
   328         case Ph_EV_KEY:
   329         {
   330             SDL_keysym keysym;
   331 
   332             posted = 0;
   333 
   334             keyEvent = PhGetData( event );
   335 
   336             if (Pk_KF_Key_Down & keyEvent->key_flags)
   337             {
   338                 /* split the wheel events from real key events */
   339                 if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   340                 {
   341                    posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
   342                    break;
   343                 }
   344                 if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   345                 {
   346                    posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
   347                    break;
   348                 }
   349                 posted = SDL_PrivateKeyboard(SDL_PRESSED, ph_TranslateKey(keyEvent, &keysym));
   350             }
   351             else /* must be key release */
   352             {
   353                 /* split the wheel events from real key events */
   354                 if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   355                 {
   356                    posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
   357                    break;
   358                 }
   359                 if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
   360                 {
   361                    posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
   362                    break;
   363                 }
   364                 posted = SDL_PrivateKeyboard(SDL_RELEASED, ph_TranslateKey( keyEvent, &keysym));
   365             }
   366         }
   367         break;
   368         
   369         case Ph_EV_INFO:
   370         {
   371         }
   372         break;
   373     }
   374 
   375     return(posted);
   376 }
   377 
   378 /* perform a blocking read if no events available */
   379 int ph_Pending(_THIS)
   380 {
   381     /* Flush the display connection and look to see if events are queued */
   382     PgFlush();
   383 
   384     while (1)
   385     {
   386         switch(PhEventPeek(event, EVENT_SIZE))
   387         {
   388             case Ph_EVENT_MSG:
   389                  return 1;
   390                  break;
   391             case -1:
   392                  perror("ph_Pending(): PhEventNext failed");
   393                  break;
   394             default:
   395                  return 0;
   396         }
   397     }
   398 
   399     /* Oh well, nothing is ready .. */
   400     return(0);
   401 }
   402 
   403 void ph_PumpEvents(_THIS)
   404 {
   405     /* Flush the display connection and look to see if events are queued */
   406     PgFlush();
   407 
   408     while (ph_Pending(this))
   409     {
   410         PtEventHandler(event);
   411         ph_DispatchEvent(this);
   412     }
   413 }
   414 
   415 void ph_InitKeymap(void)
   416 {
   417     int i;
   418 
   419     /* Odd keys used in international keyboards */
   420     for (i=0; i<SDL_TABLESIZE(ODD_keymap); ++i)
   421     {
   422         ODD_keymap[i] = SDLK_UNKNOWN;
   423     }
   424 
   425     /* Map the miscellaneous keys */
   426     for (i=0; i<SDL_TABLESIZE(MISC_keymap); ++i)
   427     {
   428         MISC_keymap[i] = SDLK_UNKNOWN;
   429     }
   430 
   431     MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE;
   432     MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB;
   433     MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR;
   434     MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN;
   435     MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE;
   436     MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE;
   437     MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE;
   438 
   439     MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0;
   440     MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1;
   441     MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2;
   442     MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3;
   443     MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4;
   444     MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5;
   445     MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6;
   446     MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7;
   447     MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8;
   448     MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9;
   449 
   450     MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD;
   451     MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE;
   452     MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY;
   453     MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS;
   454     MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS;
   455     MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER;
   456     MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS;
   457 
   458     MISC_keymap[Pk_Up&0xFF] = SDLK_UP;
   459     MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN;
   460     MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT;
   461     MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT;
   462     MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT;
   463     MISC_keymap[Pk_Home&0xFF] = SDLK_HOME;
   464     MISC_keymap[Pk_End&0xFF] = SDLK_END;
   465     MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP;
   466     MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN;
   467 
   468     MISC_keymap[Pk_F1&0xFF] = SDLK_F1;
   469     MISC_keymap[Pk_F2&0xFF] = SDLK_F2;
   470     MISC_keymap[Pk_F3&0xFF] = SDLK_F3;
   471     MISC_keymap[Pk_F4&0xFF] = SDLK_F4;
   472     MISC_keymap[Pk_F5&0xFF] = SDLK_F5;
   473     MISC_keymap[Pk_F6&0xFF] = SDLK_F6;
   474     MISC_keymap[Pk_F7&0xFF] = SDLK_F7;
   475     MISC_keymap[Pk_F8&0xFF] = SDLK_F8;
   476     MISC_keymap[Pk_F9&0xFF] = SDLK_F9;
   477     MISC_keymap[Pk_F10&0xFF] = SDLK_F10;
   478     MISC_keymap[Pk_F11&0xFF] = SDLK_F11;
   479     MISC_keymap[Pk_F12&0xFF] = SDLK_F12;
   480     MISC_keymap[Pk_F13&0xFF] = SDLK_F13;
   481     MISC_keymap[Pk_F14&0xFF] = SDLK_F14;
   482     MISC_keymap[Pk_F15&0xFF] = SDLK_F15;
   483 
   484     MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK;
   485     MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK;
   486     MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
   487     MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT;
   488     MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT;
   489     MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL;
   490     MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL;
   491     MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT;
   492     MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT;
   493     MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA;
   494     MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA;
   495     MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER;
   496     MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER;
   497     MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key    */
   498 
   499     MISC_keymap[Pk_Help&0xFF] = SDLK_HELP;
   500     MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT;
   501     MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK;
   502     MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU;        /* Windows "Menu" key */
   503 
   504     MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_RSUPER;   /* Right "Windows" */
   505 
   506     /* Left "Windows" key, but it can't be catched by application */
   507     MISC_keymap[Pk_Hyper_L&0xFF] = SDLK_LSUPER;
   508 }
   509 
   510 static unsigned long cap;
   511 
   512 SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym)
   513 {
   514     /* 'sym' is set to the value of the key with modifiers applied to it.
   515        This member is valid only if Pk_KF_Sym_Valid is set in the key_flags.
   516        We will assume it is valid. */
   517 
   518     /* FIXME: This needs to check whether the cap & scancode is valid */
   519 
   520     cap = key->key_cap;
   521 
   522     switch (cap>>8)
   523     {
   524         case 0x00:  /* Latin 1 */
   525         case 0x01:  /* Latin 2 */
   526         case 0x02:  /* Latin 3 */
   527         case 0x03:  /* Latin 4 */
   528         case 0x04:  /* Katakana */
   529         case 0x05:  /* Arabic */
   530         case 0x06:  /* Cyrillic */
   531         case 0x07:  /* Greek */
   532         case 0x08:  /* Technical */
   533         case 0x0A:  /* Publishing */
   534         case 0x0C:  /* Hebrew */
   535         case 0x0D:  /* Thai */
   536                    keysym->sym = (SDLKey)(cap&0xFF);
   537                    /* Map capital letter syms to lowercase */
   538                    if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
   539                        keysym->sym += ('a'-'A');
   540                    break;
   541         case 0xF0:
   542                    keysym->sym = MISC_keymap[cap&0xFF];
   543                    break;
   544         default:
   545                    keysym->sym = SDLK_UNKNOWN;                
   546                    break;
   547     }
   548 
   549     keysym->scancode = key->key_scan;
   550     keysym->unicode = 0;
   551 
   552     if (SDL_TranslateUNICODE)
   553     {
   554         char utf8[MB_CUR_MAX];
   555         int utf8len;
   556         wchar_t unicode;
   557 
   558         switch (keysym->scancode)
   559         {
   560            /* Esc key */
   561            case 0x01: keysym->unicode = 27;
   562                       break;
   563            /* BackSpace key */
   564            case 0x0E: keysym->unicode = 127;
   565                       break;
   566            /* Enter key */
   567            case 0x1C: keysym->unicode = 10;
   568                       break;
   569            default:
   570                       utf8len = PhKeyToMb(utf8, key);
   571                       if (utf8len > 0)
   572                       {
   573                          utf8len = mbtowc(&unicode, utf8, utf8len);
   574                          if (utf8len > 0)
   575                          {
   576                              keysym->unicode = unicode;
   577                          }
   578                       }
   579                       break;
   580         }
   581 
   582     }
   583 
   584     return (keysym);
   585 }
   586 
   587 void ph_InitOSKeymap(_THIS)
   588 {
   589     ph_InitKeymap();
   590 }