src/video/photon/SDL_ph_events.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. ph_KeyRepeat
  2. ph_DispatchEvent
  3. ph_Pending
  4. ph_PumpEvents
  5. ph_InitKeymap
  6. ph_TranslateKey
  7. ph_InitOSKeymap

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

/* [<][>][^][v][top][bottom][index][help] */