src/video/photon/SDL_ph_events.c
author Sam Lantinga <slouken@lokigames.com>
Thu, 10 May 2001 18:42:17 +0000
changeset 19 8cc4dbfab9ab
parent 0 74212992fb08
child 220 7861d904fb77
permissions -rw-r--r--
Date: Thu, 19 Apr 2001 08:36:54 +0300
From: "Mike Gorchak" <mike@malva.com.ua>
Subject: Patches for QNX RtP

Here my patch for QNX RtP/Photon for SDL-1.2.

Detailed description of my changes:

SDL/configure.in:
If Photon detected declare define ENABLE_PHOTON.

SDL/src/video/SDL_sysvideo.h:
Added extern to ph_bootstrap.

SDL/src/video/SDL_video.c:
Added ph_bootstrap to bootstrap array.

SDL/src/video/photon/SDL_ph_events.c:
Declare DISABLE_X11 if compiled for Photon.

SDL/src/video/photon/SDL_ph_image.c:
Fixed segment violation on exit. Please update BUGS file.

SDL/src/video/photon/SDL_ph_video.c:
1. Enabling window manager.
2. Added to device capabilities Photon Window Manager functions:
SetCaption and IconifyWindow.
3. Renamed X11_bootstrap to ph_bootstrap.
4. Removed SEGFAULT termination of programs if Photon not available.

SDL/src/video/photon/SDL_ph_wm.c:
1. Declare DISABLE_X11 if compiled for Photon.
2. Added ph_SetCaption and ph_IconifyWindow code. (Thanks to
'phearbear' for iconify window source).
3. Some stubers for other wm functions.

Thanks !

----------------------------
Mike Gorchak
CJSC Malva
System Programmer
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@devolution.com
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 /* Handle the event stream, converting photon events into SDL events */
    29 
    30 #define DISABLE_X11
    31 
    32 #include <Ph.h>
    33 #include <stdio.h>
    34 #include <setjmp.h>
    35 #include <photon/PkKeyDef.h>
    36 #include <sys/time.h>
    37 
    38 #include "SDL.h"
    39 #include "SDL_syswm.h"
    40 #include "SDL_sysevents.h"
    41 #include "SDL_sysvideo.h"
    42 #include "SDL_events_c.h"
    43 #include "SDL_ph_video.h"
    44 #include "SDL_ph_modes_c.h"
    45 #include "SDL_ph_image_c.h"
    46 #include "SDL_ph_events_c.h"
    47 
    48 
    49 /* The translation tables from a photon keysym to a SDL keysym */
    50 static SDLKey ODD_keymap[256];
    51 static SDLKey MISC_keymap[0xFF + 1];
    52 SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym);
    53 
    54 /* Check to see if this is a repeated key.
    55    (idea shamelessly lifted from GII -- thanks guys! :)
    56  */
    57 
    58 static int ph_KeyRepeat(_THIS, PhKeyEvent_t* keyevent)
    59 {
    60 	PhEvent_t* peekevent;
    61 	PhKeyEvent_t* keyEvent;
    62 	int repeated;
    63 
    64 	repeated = 0;
    65 	switch (PhEventPeek( peekevent, EVENT_SIZE ))
    66 	{
    67 		case Ph_EVENT_MSG: {
    68 			if(peekevent->type == Ph_EV_KEY)
    69 			{
    70 				keyEvent = PhGetData( peekevent );
    71 				if ( !(Pk_KF_Key_Down & keyEvent->key_flags) &&
    72 					(keyEvent->key_cap == keyevent->key_cap) &&
    73 					(peekevent->timestamp == event->timestamp)	
    74 				) {
    75 					repeated = 1;
    76 					 //PhEventNext( peekevent, EVENT_SIZE );  
    77 				}				
    78 			}
    79 		}
    80 		break;
    81 
    82 		case -1: {
    83 			perror( "PhEventPeek failed" );
    84 		}
    85 		break;
    86 
    87 		default: /* no events pending */
    88 	}
    89 	return(repeated);
    90 }
    91 
    92 /* Note:  The X server buffers and accumulates mouse motion events, so
    93    the motion event generated by the warp may not appear exactly as we
    94    expect it to.  We work around this (and improve performance) by only
    95    warping the pointer when it reaches the edge, and then wait for it.
    96 */
    97 /*
    98 #define MOUSE_FUDGE_FACTOR	8
    99 
   100 static inline int X11_WarpedMotion(_THIS, XEvent *xevent)
   101 {
   102 	int w, h, i;
   103 	int deltax, deltay;
   104 	int posted;
   105 
   106 	w = SDL_VideoSurface->w;
   107 	h = SDL_VideoSurface->h;
   108 	deltax = xevent->xmotion.x - mouse_last.x;
   109 	deltay = xevent->xmotion.y - mouse_last.y;
   110 #ifdef DEBUG_MOTION
   111   printf("Warped mouse motion: %d,%d\n", deltax, deltay);
   112 #endif
   113 	mouse_last.x = xevent->xmotion.x;
   114 	mouse_last.y = xevent->xmotion.y;
   115 	posted = SDL_PrivateMouseMotion(0, 1, deltax, deltay);
   116 
   117 	if ( (xevent->xmotion.x < MOUSE_FUDGE_FACTOR) ||
   118 	     (xevent->xmotion.x > (w-MOUSE_FUDGE_FACTOR)) ||
   119 	     (xevent->xmotion.y < MOUSE_FUDGE_FACTOR) ||
   120 	     (xevent->xmotion.y > (h-MOUSE_FUDGE_FACTOR)) ) {
   121 		/* Get the events that have accumulated */
   122 /*		while ( XCheckTypedEvent(SDL_Display, MotionNotify, xevent) ) {
   123 			deltax = xevent->xmotion.x - mouse_last.x;
   124 			deltay = xevent->xmotion.y - mouse_last.y;
   125 #ifdef DEBUG_MOTION
   126   printf("Extra mouse motion: %d,%d\n", deltax, deltay);
   127 #endif
   128 			mouse_last.x = xevent->xmotion.x;
   129 			mouse_last.y = xevent->xmotion.y;
   130 			posted += SDL_PrivateMouseMotion(0, 1, deltax, deltay);
   131 		}
   132 		mouse_last.x = w/2;
   133 		mouse_last.y = h/2;
   134 		XWarpPointer(SDL_Display, None, SDL_Window, 0, 0, 0, 0,
   135 					mouse_last.x, mouse_last.y);
   136 		for ( i=0; i<10; ++i ) {
   137         		XMaskEvent(SDL_Display, PointerMotionMask, xevent);
   138 			if ( (xevent->xmotion.x >
   139 			          (mouse_last.x-MOUSE_FUDGE_FACTOR)) &&
   140 			     (xevent->xmotion.x <
   141 			          (mouse_last.x+MOUSE_FUDGE_FACTOR)) &&
   142 			     (xevent->xmotion.y >
   143 			          (mouse_last.y-MOUSE_FUDGE_FACTOR)) &&
   144 			     (xevent->xmotion.y <
   145 			          (mouse_last.y+MOUSE_FUDGE_FACTOR)) ) {
   146 				break;
   147 			}
   148 #ifdef DEBUG_XEVENTS
   149   printf("Lost mouse motion: %d,%d\n", xevent->xmotion.x, xevent->xmotion.y);
   150 #endif
   151 		}
   152 #ifdef DEBUG_XEVENTS
   153 		if ( i == 10 ) {
   154 			printf("Warning: didn't detect mouse warp motion\n");
   155 		}
   156 #endif
   157 	}
   158 	return(posted);
   159 }
   160 */
   161 
   162 static int ph_DispatchEvent(_THIS)
   163 {
   164 	int posted;
   165 	PhRect_t* rect;
   166 	PhPointerEvent_t* pointerEvent;
   167 	PhKeyEvent_t* keyEvent;
   168 	PhWindowEvent_t* winEvent;
   169 	int i;
   170 	SDL_Rect sdlrects[50]; 
   171 	
   172 	posted = 0;
   173 	
   174 	switch (event->type) {
   175 		case Ph_EV_BOUNDARY:
   176 		{
   177 		
   178 			if (event->subtype == Ph_EV_PTR_ENTER)
   179 				posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
   180 			else if (event->subtype ==Ph_EV_PTR_LEAVE)
   181 				posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);	
   182 		}
   183 		break;
   184 
   185 		case Ph_EV_PTR_MOTION_BUTTON:
   186 		case Ph_EV_PTR_MOTION_NOBUTTON:
   187 		{
   188 		
   189 			if ( SDL_VideoSurface ) {
   190 				pointerEvent = PhGetData( event );
   191 				rect = PhGetRects( event );
   192 				posted = SDL_PrivateMouseMotion(0, 1,
   193                 		pointerEvent->pos.x - rect[0].ul.x,
   194                 		pointerEvent->pos.y - rect[0].ul.y);		
   195 			}
   196 		}
   197 		break;
   198 
   199 		case Ph_EV_BUT_PRESS:
   200 		{
   201 
   202 			pointerEvent = PhGetData( event );
   203 			/* TODO: is 'buttons' the right mapping? */
   204 			posted = SDL_PrivateMouseButton(SDL_PRESSED,
   205                         	pointerEvent->buttons, 0, 0);
   206 		}
   207 		break;
   208 
   209 		case Ph_EV_BUT_RELEASE:
   210 		{
   211 			
   212 			pointerEvent = PhGetData( event );
   213 			 posted = SDL_PrivateMouseButton(SDL_RELEASED,
   214          			pointerEvent->buttons, 0, 0);
   215 		}
   216 		break;
   217 
   218 		case Ph_EV_WM:
   219 		{
   220 
   221 		
   222 			winEvent = PhGetData( event );
   223 			
   224 			/* losing focus */
   225 			if ((winEvent->event_f==Ph_WM_FOCUS)&&
   226 				(winEvent->event_state==Ph_WM_EVSTATE_FOCUSLOST))
   227 			{
   228 				posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);	
   229 
   230 				/* Queue leaving fullscreen mode */
   231 				switch_waiting = 0x01;
   232 				switch_time = SDL_GetTicks() + 200;
   233 			}
   234 
   235 			/* gaining focus */
   236 			else if ((winEvent->event_f==Ph_WM_FOCUS)&&
   237 					(winEvent->event_state==Ph_WM_EVSTATE_FOCUS))
   238 			{
   239 				posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
   240 
   241 				/* Queue entry into fullscreen mode */
   242 				switch_waiting = 0x01 | SDL_FULLSCREEN;
   243 				switch_time = SDL_GetTicks() + 1500;
   244 			}
   245 
   246 			/* request to quit */
   247 			else if (winEvent->event_f==Ph_WM_CLOSE)
   248 			{
   249 				posted = SDL_PrivateQuit();
   250 			}
   251 		}
   252 		break;
   253 		
   254 		/* window has been resized, moved or removed */
   255 		case Ph_EV_EXPOSE:
   256 		{
   257 
   258 			if (SDL_VideoSurface)
   259 			{
   260 			  
   261 			  
   262 					rect = PhGetRects( event );
   263 
   264 				//PgSetClipping(1, rect );
   265 				 for(i=0;i<event->num_rects;i++)
   266 			   {
   267 			      sdlrects[i].x = rect[i].ul.x;
   268 			      sdlrects[i].y = rect[i].ul.y;
   269 			      sdlrects[i].w = rect[i].lr.x - rect[i].ul.x;
   270 			      sdlrects[i].h = rect[i].lr.y - rect[i].ul.y;
   271 			      	
   272 				}
   273 			
   274 					this->UpdateRects(this, event->num_rects, sdlrects);
   275 
   276 			}
   277 		}
   278 		break;
   279 
   280 		case Ph_EV_KEY:
   281 		{
   282 	
   283 			SDL_keysym keysym;
   284 			
   285 			posted = 0;
   286 			
   287 			keyEvent = PhGetData( event );
   288 
   289 			if (Pk_KF_Key_Down & keyEvent->key_flags)
   290 			{
   291 				
   292 				posted = SDL_PrivateKeyboard(SDL_PRESSED,
   293                 			ph_TranslateKey( keyEvent, &keysym));
   294 			}
   295 			else /* must be key release */
   296  			{
   297  				/* Ignore repeated key release events */
   298 				/*if (! Pk_KF_Key_Repeat & keyEvent->key_flags )*/
   299 				
   300 					posted = SDL_PrivateKeyboard(SDL_RELEASED,
   301         					ph_TranslateKey( keyEvent, &keysym));
   302 				/*}*/
   303 			}
   304 		}
   305 		break;
   306 	}
   307 	
   308 		
   309 	
   310 	return(posted);
   311 }
   312 
   313 /* perform a blocking read if no events available */
   314 int ph_Pending(_THIS)
   315 {
   316 	
   317 	/* Flush the display connection and look to see if events are queued */
   318 
   319 	PgFlush();
   320 
   321      while( 1 )
   322       {   //note this is a non-blocking call
   323           switch( PhEventPeek( event, EVENT_SIZE ) )
   324            {
   325               case Ph_EVENT_MSG:
   326                  
   327                  return 1;
   328                  break;
   329               case -1:
   330                  perror( "PhEventNext failed" );
   331                  break;
   332               default:
   333              	  
   334                 return 0;
   335        }
   336    }
   337 
   338 	/* Oh well, nothing is ready .. */
   339 	return(0);
   340 }
   341 
   342 /*
   343 SAMPLE EVENT PUMP
   344 =================
   345 static void update( int block ){
   346 
   347     int ch,fl;
   348     PhKeyEvent_t *key;
   349 
   350     for( ;; ){
   351 
   352         if( block ){
   353             do{
   354                 fl=PhEventNext( event,EVENT_SIZE );
   355             }while( fl!=Ph_EVENT_MSG );
   356             block=0;
   357         }else{
   358             do{
   359                 fl=PhEventPeek( event,EVENT_SIZE );
   360                 if( !fl ) return;
   361             }while( fl!=Ph_EVENT_MSG );
   362         }
   363 
   364         switch( event->type ){
   365         case Ph_EV_KEY:
   366             key=PhGetData( event );
   367             ch=key->key_cap;    // & 127;
   368             fl=key->key_flags;
   369             if( ch<32 || ch>127 ) break;
   370             if( fl & Pk_KF_Key_Down ){
   371                 if( !(fl & Pk_KF_Key_Repeat) ){
   372                     if( queput-queget<QUE_SIZE ) keyque[ queput++ & QUE_MASK ]=ch;
   373                     keyMatrix[ch]=1;
   374                 }
   375             }else{
   376                 keyMatrix[ch]=0;
   377             }
   378             break;
   379         default:
   380             PtEventHandler( event );
   381         }
   382     }
   383 }
   384 */
   385 
   386 void ph_PumpEvents(_THIS)
   387 {
   388 	int pending;
   389 
   390 	/* Keep processing pending events */
   391 	pending = 0;
   392 	while ( ph_Pending(this) ) {
   393 		ph_DispatchEvent(this);
   394 		++pending;
   395 	}
   396 	if ( switch_waiting ) {
   397 		Uint32 now;
   398 
   399 		now  = SDL_GetTicks();
   400 		if ( pending || !SDL_VideoSurface ) {
   401 			/* Try again later... */
   402 			if ( switch_waiting & SDL_FULLSCREEN ) {
   403 				switch_time = now + 1500;
   404 			} else {
   405 				switch_time = now + 200;
   406 			}
   407 		} else if ( now >= switch_time ) {
   408 			Uint32 go_fullscreen;
   409 
   410 			go_fullscreen = switch_waiting & SDL_FULLSCREEN;
   411 			switch_waiting = 0;
   412 			if ( SDL_VideoSurface->flags & SDL_FULLSCREEN ) {
   413 				if ( go_fullscreen ) {
   414 					ph_EnterFullScreen(this);
   415 				} else {
   416 					ph_LeaveFullScreen(this);
   417 				}
   418 			}
   419 			/* Handle focus in/out when grabbed */
   420 /*
   421 			if ( go_fullscreen ) {
   422 				ph_GrabInputNoLock(this, this->input_grab);
   423 			} else {
   424 				ph_GrabInputNoLock(this, SDL_GRAB_OFF);
   425 			}
   426 */
   427 		}
   428 	}
   429 }
   430 
   431 void ph_InitKeymap(void)
   432 {
   433 	int i;
   434 
   435 	/* Odd keys used in international keyboards */
   436 	for ( i=0; i<SDL_TABLESIZE(ODD_keymap); ++i )
   437 		ODD_keymap[i] = SDLK_UNKNOWN;
   438 
   439 	/* Map the miscellaneous keys */
   440 	for ( i=0; i<SDL_TABLESIZE(MISC_keymap); ++i )
   441 		MISC_keymap[i] = SDLK_UNKNOWN;
   442 
   443 	MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE;
   444 	MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB;
   445 	MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR;
   446 	MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN;
   447 	MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE;
   448 	MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE;
   449 	MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE;
   450 
   451 	MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0;
   452 	MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1;
   453 	MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2;
   454 	MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3;
   455 	MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4;
   456 	MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5;
   457 	MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6;
   458 	MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7;
   459 	MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8;
   460 	MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9;
   461 
   462 	MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD;
   463 	MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE;
   464 	MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY;
   465 	MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS;
   466 	MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS;
   467 	MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER;
   468 	MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS;
   469 
   470 	MISC_keymap[Pk_Up&0xFF] = SDLK_UP;
   471 	MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN;
   472 	MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT;
   473 	MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT;
   474 	MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT;
   475 	MISC_keymap[Pk_Home&0xFF] = SDLK_HOME;
   476 	MISC_keymap[Pk_End&0xFF] = SDLK_END;
   477 	MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP;
   478 	MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN;
   479 
   480 	MISC_keymap[Pk_F1&0xFF] = SDLK_F1;
   481 	MISC_keymap[Pk_F2&0xFF] = SDLK_F2;
   482 	MISC_keymap[Pk_F3&0xFF] = SDLK_F3;
   483 	MISC_keymap[Pk_F4&0xFF] = SDLK_F4;
   484 	MISC_keymap[Pk_F5&0xFF] = SDLK_F5;
   485 	MISC_keymap[Pk_F6&0xFF] = SDLK_F6;
   486 	MISC_keymap[Pk_F7&0xFF] = SDLK_F7;
   487 	MISC_keymap[Pk_F8&0xFF] = SDLK_F8;
   488 	MISC_keymap[Pk_F9&0xFF] = SDLK_F9;
   489 	MISC_keymap[Pk_F10&0xFF] = SDLK_F10;
   490 	MISC_keymap[Pk_F11&0xFF] = SDLK_F11;
   491 	MISC_keymap[Pk_F12&0xFF] = SDLK_F12;
   492 	MISC_keymap[Pk_F13&0xFF] = SDLK_F13;
   493 	MISC_keymap[Pk_F14&0xFF] = SDLK_F14;
   494 	MISC_keymap[Pk_F15&0xFF] = SDLK_F15;
   495 
   496 	MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK;
   497 	MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK;
   498 	MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK;
   499 	MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT;
   500 	MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT;
   501 	MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL;
   502 	MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL;
   503 	MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT;
   504 	MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT;
   505 	MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA;
   506 	MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA;
   507 	MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER; /* Left "Windows" */
   508 	MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER; /* Right "Windows */
   509 	MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */
   510 
   511 	MISC_keymap[Pk_Help&0xFF] = SDLK_HELP;
   512 	MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT;
   513 //	MISC_keymap[Pk_Sys_Req] = SDLK_SYSREQ;
   514 	MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK;
   515 	MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU;
   516 	MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_MENU;   /* Windows "Menu" key */
   517 }
   518 
   519 static unsigned long cap;
   520 
   521 SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym)
   522 {
   523 /*	
   524 	'sym' is set to the value of the key with modifiers applied to it. 
   525 	This member is valid only if Pk_KF_Sym_Valid is set in the key_flags.
   526 	We will assume it is valid.
   527 */
   528 	cap = key->key_cap;
   529     switch (cap>>8) {
   530             case 0x00:  /* Latin 1 */
   531             case 0x01:  /* Latin 2 */
   532             case 0x02:  /* Latin 3 */
   533             case 0x03:  /* Latin 4 */
   534             case 0x04:  /* Katakana */
   535             case 0x05:  /* Arabic */
   536             case 0x06:  /* Cyrillic */
   537             case 0x07:  /* Greek */
   538             case 0x08:  /* Technical */
   539             case 0x0A:  /* Publishing */
   540             case 0x0C:  /* Hebrew */
   541             case 0x0D:  /* Thai */
   542                 keysym->sym = (SDLKey)(cap&0xFF);
   543                 /* Map capital letter syms to lowercase */
   544                 if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z'))
   545                     keysym->sym += ('a'-'A');
   546                 break;
   547 //            case 0xFE:
   548 //                keysym->sym = ODD_keymap[sym&0xFF];
   549 //                break;
   550             case 0xF0:
   551                 keysym->sym = MISC_keymap[cap&0xFF];
   552                 break;
   553             default:
   554                 fprintf(stderr,"Photon: Unknown key_cap, cap = 0x%.4x\n", (unsigned int)cap);
   555                 break;
   556     }	
   557 	return (keysym);
   558 }
   559 
   560 void ph_InitOSKeymap(_THIS)
   561 {
   562 
   563 	ph_InitKeymap();
   564 }
   565