symbian-qemu-0.9.1-12/libsdl-trunk/src/video/photon/SDL_ph_events.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/libsdl-trunk/src/video/photon/SDL_ph_events.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,624 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/* Handle the event stream, converting photon events into SDL events */
+
+#include <stdio.h>
+#include <setjmp.h>
+#include <sys/time.h>
+
+#include <Ph.h>
+#include <photon/PkKeyDef.h>
+
+#include "SDL.h"
+#include "SDL_syswm.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+#include "SDL_ph_video.h"
+#include "SDL_ph_modes_c.h"
+#include "SDL_ph_image_c.h"
+#include "SDL_ph_events_c.h"
+#include "SDL_phyuv_c.h"
+
+/* The translation tables from a photon keysym to a SDL keysym */
+static SDLKey ODD_keymap[256];
+static SDLKey MISC_keymap[0xFF + 1];
+SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym);
+
+/* Check to see if this is a repeated key.
+   (idea shamelessly lifted from GII -- thanks guys! :) */
+static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent)
+{
+    PhRect_t *rect = PhGetRects( winEvent );
+
+    int centre_x, centre_y;
+    int dx, dy;
+    short abs_x, abs_y;
+    int posted;
+
+    centre_x = SDL_VideoSurface->w / 2;
+    centre_y = SDL_VideoSurface->h / 2;
+
+    dx = rect->ul.x - centre_x;
+    dy = rect->ul.y - centre_y;
+
+    posted = SDL_PrivateMouseMotion( 0, 1, dx, dy );
+
+    /* Move mouse cursor to middle of the window */
+    PtGetAbsPosition( window, &abs_x, &abs_y );
+    PhMoveCursorAbs(PhInputGroup(NULL), abs_x + centre_x, abs_y + centre_y);
+
+    return (posted);
+}
+
+/* Control which motion flags the window has set, a flags value of -1 sets
+ * MOTION_BUTTON and MOTION_NOBUTTON */
+
+static void set_motion_sensitivity(_THIS, unsigned int flags)
+{
+    int rid;
+    int fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON;
+    PhRegion_t region;
+
+    if( window )
+    {
+        rid = PtWidgetRid(window);
+        if( rid != 0 && PhRegionQuery(rid, &region, NULL, NULL, 0) == 0 )
+        {
+            region.events_sense=(region.events_sense & ~fields)|(flags & fields);
+            PhRegionChange(Ph_REGION_EV_SENSE, 0, &region, NULL, NULL);
+        }
+    }
+}
+
+/* Convert the photon button state value to an SDL value */
+static Uint8 ph2sdl_mousebutton(unsigned short button_state)
+{
+    Uint8 mouse_button = 0;
+
+    if (button_state & Ph_BUTTON_SELECT)
+        mouse_button |= SDL_BUTTON_LEFT;
+    if (button_state & Ph_BUTTON_MENU)
+        mouse_button |= SDL_BUTTON_RIGHT;
+    if (button_state & Ph_BUTTON_ADJUST)
+        mouse_button |= SDL_BUTTON_MIDDLE;
+
+    return (mouse_button);
+}
+
+static int ph_DispatchEvent(_THIS)
+{
+    int posted;
+    PhRect_t* rect;
+    PhPointerEvent_t* pointerEvent;
+    PhKeyEvent_t* keyEvent;
+    PhWindowEvent_t* winEvent;
+    int i, buttons;
+    SDL_Rect sdlrects[PH_SDL_MAX_RECTS];
+	
+    posted = 0;
+	
+    switch (phevent->type)
+    {
+        case Ph_EV_BOUNDARY:
+        {
+            if (phevent->subtype == Ph_EV_PTR_ENTER)
+            {
+                posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
+            }
+            else if (phevent->subtype ==Ph_EV_PTR_LEAVE)
+            {
+                posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);	
+            }
+        }
+        break;
+
+        case Ph_EV_PTR_MOTION_BUTTON:
+        case Ph_EV_PTR_MOTION_NOBUTTON:
+        {
+            if (SDL_VideoSurface)
+            {
+                pointerEvent = PhGetData(phevent);
+                rect = PhGetRects(phevent);
+
+                if (mouse_relative)
+                {
+                    posted = ph_WarpedMotion(this, phevent);
+                }
+                else
+                {
+                    posted = SDL_PrivateMouseMotion(0, 0, rect->ul.x, rect->ul.y);
+                }
+            }
+        }
+        break;
+
+        case Ph_EV_BUT_PRESS:
+        {
+            pointerEvent = PhGetData(phevent);
+            buttons = ph2sdl_mousebutton(pointerEvent->buttons);
+            if (buttons != 0)
+            {
+                posted = SDL_PrivateMouseButton(SDL_PRESSED, buttons, 0, 0);
+            }
+        }
+        break;
+
+        case Ph_EV_BUT_RELEASE:
+        {
+            pointerEvent = PhGetData(phevent);
+            buttons = ph2sdl_mousebutton(pointerEvent->buttons);
+            if (phevent->subtype == Ph_EV_RELEASE_REAL && buttons != 0)
+            {
+                posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0);
+            }
+            else if(phevent->subtype == Ph_EV_RELEASE_PHANTOM)
+            {
+                /* If the mouse is outside the window,
+                 * only a phantom release event is sent, so
+                 * check if the window doesn't have mouse focus.
+                 * Not perfect, maybe checking the mouse button
+                 * state for Ph_EV_BOUNDARY events would be
+                 * better. */
+                if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) == 0)
+		{
+                    posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0);
+                }
+            }
+        }
+        break;
+
+        case Ph_EV_WM:
+        {
+            winEvent = PhGetData(phevent);
+
+            /* losing focus */
+            if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUSLOST))
+            {
+                set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON);
+                posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);	
+            }
+            /* gaining focus */
+            else if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUS))
+            {
+                set_motion_sensitivity(this, -1);
+                posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
+            }
+            /* request quit */
+            else if (winEvent->event_f==Ph_WM_CLOSE)
+            {
+                posted = SDL_PrivateQuit();
+            }
+            /* request hide/unhide */
+            else if (winEvent->event_f==Ph_WM_HIDE)
+            {
+                if (currently_hided)
+                {
+                   /* got unhide window event                                */
+                   /* TODO: restore application's palette if in palette mode */
+                   currently_hided=0;
+                }
+                else
+                {
+                   /* got hide window event                                  */
+                   /* TODO: restore original palette if in palette mode      */
+                   currently_hided=1;
+                }
+            }
+            /* request to resize */
+            else if (winEvent->event_f==Ph_WM_RESIZE)
+            {
+                currently_maximized=0;
+                #if (_NTO_VERSION < 630)
+                   SDL_PrivateResize(winEvent->size.w+1, winEvent->size.h+1);
+                #else
+                   /* QNX 6.3.0 have this bug fixed */
+                   SDL_PrivateResize(winEvent->size.w, winEvent->size.h);
+                #endif /* _NTO_VERSION */
+            }
+            /* request to move */
+            else if (winEvent->event_f==Ph_WM_MOVE)
+            {
+                if (current_overlay!=NULL)
+                {
+                   int lockedstate=current_overlay->hwdata->locked;
+                   int chromastate=current_overlay->hwdata->ischromakey;
+                   int error;
+                   SDL_Rect src, dst;
+
+                   current_overlay->hwdata->locked=1;
+                   src.x = 0;
+                   src.y = 0;
+                   src.w = current_overlay->w;
+                   src.y = current_overlay->h;
+                   dst.x=current_overlay->hwdata->CurrentViewPort.pos.x;
+                   dst.y=current_overlay->hwdata->CurrentViewPort.pos.y;
+                   dst.w=current_overlay->hwdata->CurrentViewPort.size.w;
+                   dst.h=current_overlay->hwdata->CurrentViewPort.size.h;
+                   current_overlay->hwdata->ischromakey=0;
+                   error=ph_DisplayYUVOverlay(this, current_overlay, &src, &dst);
+                   if (!error)
+                   {
+                       current_overlay->hwdata->ischromakey=chromastate;
+                       current_overlay->hwdata->locked=lockedstate;
+                   }
+                }
+            }
+            /* maximize request */
+            else if (winEvent->event_f==Ph_WM_MAX)
+            {
+                /* window already moved and resized here */
+                currently_maximized=1;
+            }
+            /* restore request */
+            else if (winEvent->event_f==Ph_WM_RESTORE)
+            {
+                /* window already moved and resized here */
+                currently_maximized=0;
+            }
+        }
+        break;
+
+        /* window has been resized, moved or removed */
+        case Ph_EV_EXPOSE:
+        {
+            if (phevent->num_rects!=0)
+            {
+                int numrects;
+
+                if (SDL_VideoSurface)
+                {
+                    rect = PhGetRects(phevent);
+                    if (phevent->num_rects>PH_SDL_MAX_RECTS)
+                    {
+                       /* sorry, buffers underrun, we'll update only first PH_SDL_MAX_RECTS rects */
+                       numrects=PH_SDL_MAX_RECTS;
+                    }
+
+                    for(i=0; i<phevent->num_rects; i++)
+                    {
+                        sdlrects[i].x = rect[i].ul.x;
+                        sdlrects[i].y = rect[i].ul.y;
+                        sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1;
+                        sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1;
+                    }
+
+                    this->UpdateRects(this, phevent->num_rects, sdlrects);
+
+                    if (current_overlay!=NULL)
+                    {
+                        int lockedstate=current_overlay->hwdata->locked;
+                        int error;
+                        SDL_Rect src, dst;
+
+                        current_overlay->hwdata->locked=1;
+                        src.x = 0;
+                        src.y = 0;
+                        src.w = current_overlay->w;
+                        src.y = current_overlay->h;
+                        dst.x=current_overlay->hwdata->CurrentViewPort.pos.x;
+                        dst.y=current_overlay->hwdata->CurrentViewPort.pos.y;
+                        dst.w=current_overlay->hwdata->CurrentViewPort.size.w;
+                        dst.h=current_overlay->hwdata->CurrentViewPort.size.h;
+                        current_overlay->hwdata->forcedredraw=1;
+                        error=ph_DisplayYUVOverlay(this, current_overlay, &src, &dst);
+                        if (!error)
+                        {
+                            current_overlay->hwdata->forcedredraw=0;
+                            current_overlay->hwdata->locked=lockedstate;
+                        }
+                    }
+                }
+            }
+        }
+	break;
+
+        case Ph_EV_KEY:
+        {
+            SDL_keysym keysym;
+
+            posted = 0;
+
+            keyEvent = PhGetData(phevent);
+
+            if (Pk_KF_Key_Down & keyEvent->key_flags)
+            {
+                /* split the wheel events from real key events */
+                if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+                {
+                   posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0);
+                   break;
+                }
+                if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+                {
+                   posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0);
+                   break;
+                }
+                posted = SDL_PrivateKeyboard(SDL_PRESSED, ph_TranslateKey(keyEvent, &keysym));
+            }
+            else /* must be key release */
+            {
+                /* split the wheel events from real key events */
+                if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+                {
+                   posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0);
+                   break;
+                }
+                if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid))
+                {
+                   posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0);
+                   break;
+                }
+                posted = SDL_PrivateKeyboard(SDL_RELEASED, ph_TranslateKey( keyEvent, &keysym));
+            }
+        }
+        break;
+        
+        case Ph_EV_INFO:
+        {
+           if (phevent->subtype==Ph_OFFSCREEN_INVALID)
+           {
+              unsigned long* EvInfoData;
+
+              EvInfoData=(unsigned long*)PhGetData(phevent);
+
+              switch (*EvInfoData)
+              {
+                 case Pg_VIDEO_MODE_SWITCHED:
+                      {
+                      }
+                      break;
+                 case Pg_ENTERED_DIRECT:
+                      {
+                      }
+                      break;
+                 case Pg_EXITED_DIRECT:
+                      {
+                      }
+                      break;
+                 case Pg_DRIVER_STARTED:
+                      {
+                      }
+                      break;
+              }
+           }
+        }
+        break;
+    }
+
+    return(posted);
+}
+
+/* perform a blocking read if no events available */
+int ph_Pending(_THIS)
+{
+    /* Flush the display connection and look to see if events are queued */
+    PgFlush();
+
+    while (1)
+    {
+        switch(PhEventPeek(phevent, EVENT_SIZE))
+        {
+            case Ph_EVENT_MSG:
+                 return 1;
+            case -1:
+                 SDL_SetError("ph_Pending(): PhEventNext failed.\n");
+                 return 0;
+            default:
+                 return 0;
+        }
+    }
+
+    /* Oh well, nothing is ready .. */
+    return(0);
+}
+
+void ph_PumpEvents(_THIS)
+{
+    /* Flush the display connection and look to see if events are queued */
+    PgFlush();
+
+    while (ph_Pending(this))
+    {
+        PtEventHandler(phevent);
+        ph_DispatchEvent(this);
+    }
+}
+
+void ph_InitKeymap(void)
+{
+    int i;
+
+    /* Odd keys used in international keyboards */
+    for (i=0; i<SDL_arraysize(ODD_keymap); ++i)
+    {
+        ODD_keymap[i] = SDLK_UNKNOWN;
+    }
+
+    /* Map the miscellaneous keys */
+    for (i=0; i<SDL_arraysize(MISC_keymap); ++i)
+    {
+        MISC_keymap[i] = SDLK_UNKNOWN;
+    }
+
+    MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE;
+    MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB;
+    MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR;
+    MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN;
+    MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE;
+    MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE;
+    MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE;
+
+    MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0;
+    MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1;
+    MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2;
+    MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3;
+    MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4;
+    MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5;
+    MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6;
+    MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7;
+    MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8;
+    MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9;
+
+    MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD;
+    MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE;
+    MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY;
+    MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS;
+    MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS;
+    MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER;
+    MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS;
+
+    MISC_keymap[Pk_Up&0xFF] = SDLK_UP;
+    MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN;
+    MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT;
+    MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT;
+    MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT;
+    MISC_keymap[Pk_Home&0xFF] = SDLK_HOME;
+    MISC_keymap[Pk_End&0xFF] = SDLK_END;
+    MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP;
+    MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN;
+
+    MISC_keymap[Pk_F1&0xFF] = SDLK_F1;
+    MISC_keymap[Pk_F2&0xFF] = SDLK_F2;
+    MISC_keymap[Pk_F3&0xFF] = SDLK_F3;
+    MISC_keymap[Pk_F4&0xFF] = SDLK_F4;
+    MISC_keymap[Pk_F5&0xFF] = SDLK_F5;
+    MISC_keymap[Pk_F6&0xFF] = SDLK_F6;
+    MISC_keymap[Pk_F7&0xFF] = SDLK_F7;
+    MISC_keymap[Pk_F8&0xFF] = SDLK_F8;
+    MISC_keymap[Pk_F9&0xFF] = SDLK_F9;
+    MISC_keymap[Pk_F10&0xFF] = SDLK_F10;
+    MISC_keymap[Pk_F11&0xFF] = SDLK_F11;
+    MISC_keymap[Pk_F12&0xFF] = SDLK_F12;
+    MISC_keymap[Pk_F13&0xFF] = SDLK_F13;
+    MISC_keymap[Pk_F14&0xFF] = SDLK_F14;
+    MISC_keymap[Pk_F15&0xFF] = SDLK_F15;
+
+    MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK;
+    MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK;
+    MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
+    MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT;
+    MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT;
+    MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL;
+    MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL;
+    MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT;
+    MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT;
+    MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA;
+    MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA;
+    MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER;
+    MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER;
+    MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key    */
+
+    MISC_keymap[Pk_Help&0xFF] = SDLK_HELP;
+    MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT;
+    MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK;
+    MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU;        /* Windows "Menu" key */
+
+    MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_RSUPER;   /* Right "Windows" */
+
+    /* Left "Windows" key, but it can't be catched by application */
+    MISC_keymap[Pk_Hyper_L&0xFF] = SDLK_LSUPER;
+}
+
+static unsigned long cap;
+
+SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym)
+{
+    /* 'sym' is set to the value of the key with modifiers applied to it.
+       This member is valid only if Pk_KF_Sym_Valid is set in the key_flags.
+       We will assume it is valid. */
+
+    /* FIXME: This needs to check whether the cap & scancode is valid */
+
+    cap = key->key_cap;
+
+    switch (cap>>8)
+    {
+        case 0x00:  /* Latin 1 */
+        case 0x01:  /* Latin 2 */
+        case 0x02:  /* Latin 3 */
+        case 0x03:  /* Latin 4 */
+        case 0x04:  /* Katakana */
+        case 0x05:  /* Arabic */
+        case 0x06:  /* Cyrillic */
+        case 0x07:  /* Greek */
+        case 0x08:  /* Technical */
+        case 0x0A:  /* Publishing */
+        case 0x0C:  /* Hebrew */
+        case 0x0D:  /* Thai */
+                   keysym->sym = (SDLKey)(cap&0xFF);
+                   /* Map capital letter syms to lowercase */
+                   if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
+                       keysym->sym += ('a'-'A');
+                   break;
+        case 0xF0:
+                   keysym->sym = MISC_keymap[cap&0xFF];
+                   break;
+        default:
+                   keysym->sym = SDLK_UNKNOWN;                
+                   break;
+    }
+
+    keysym->scancode = key->key_scan;
+    keysym->unicode = 0;
+
+    if (SDL_TranslateUNICODE)
+    {
+        char utf8[MB_CUR_MAX];
+        int utf8len;
+        wchar_t unicode;
+
+        switch (keysym->scancode)
+        {
+           /* Esc key */
+           case 0x01: keysym->unicode = 27;
+                      break;
+           /* BackSpace key */
+           case 0x0E: keysym->unicode = 127;
+                      break;
+           /* Enter key */
+           case 0x1C: keysym->unicode = 10;
+                      break;
+           default:
+                      utf8len = PhKeyToMb(utf8, key);
+                      if (utf8len > 0)
+                      {
+                         utf8len = mbtowc(&unicode, utf8, utf8len);
+                         if (utf8len > 0)
+                         {
+                             keysym->unicode = unicode;
+                         }
+                      }
+                      break;
+        }
+
+    }
+
+    return (keysym);
+}
+
+void ph_InitOSKeymap(_THIS)
+{
+    ph_InitKeymap();
+}