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