src/video/photon/SDL_ph_events.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 14 Feb 2004 20:22:21 +0000
changeset 821 30168104389f
parent 769 b8d311d90021
child 886 05c551e5bc64
permissions -rw-r--r--
Date: Sat, 14 Feb 2004 14:52:40 +0200
From: "Mike Gorchak"
Subject: Batch of the QNX6 fixes for the SDL

1. Updated readme.QNX
2. Fixed crashes during intensive window updating under fast machines (got over 200 rectangles for update).
3. Fixed double-buffered fullscreen modes, now it works as needed.
4. Fixed Photon detection algorithm.
5. Fixed HWSURFACE update function.
6. Added SDL_PHOTON_FULLSCREEN_REFRESH environment variable support for control refresh rates under Photon.
7. Added 640x400 fullscreen mode emulation via 640x480 (if videodriver not supports original 640x400 mode of course) shifted by 40 vertical pixels from begin, to center it. It's needed for some old DOS games which ran in doubled 320x200 mode.
8. Added available video ram amount support.
8. Added hardware surface allocation/deallocation support if current videomode and videodriver supports it.
9. Added hardware filling support.
10. Added hardware blits support (simple and colorkeyed).

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