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