cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_DirectFB_events.c (28797B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21#include "../../SDL_internal.h"
     22
     23#if SDL_VIDEO_DRIVER_DIRECTFB
     24
     25/* Handle the event stream, converting DirectFB input events into SDL events */
     26
     27#include "SDL_DirectFB_video.h"
     28#include "SDL_DirectFB_window.h"
     29#include "SDL_DirectFB_modes.h"
     30
     31#include "SDL_syswm.h"
     32
     33#include "../../events/SDL_mouse_c.h"
     34#include "../../events/SDL_keyboard_c.h"
     35#include "../../events/SDL_windowevents_c.h"
     36#include "../../events/SDL_events_c.h"
     37#include "../../events/scancodes_linux.h"
     38#include "../../events/scancodes_xfree86.h"
     39
     40#include "SDL_DirectFB_events.h"
     41
     42#if USE_MULTI_API
     43#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y, p)
     44#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
     45#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(id, state, scancode)
     46#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(id, text)
     47#else
     48#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y)
     49#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
     50#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(state, scancode)
     51#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(text)
     52#endif
     53
     54typedef struct _cb_data cb_data;
     55struct _cb_data
     56{
     57    DFB_DeviceData *devdata;
     58    int sys_ids;
     59    int sys_kbd;
     60};
     61
     62/* The translation tables from a DirectFB keycode to a SDL keysym */
     63static SDL_Scancode oskeymap[256];
     64
     65
     66static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
     67                                         SDL_Keysym * keysym, Uint32 *unicode);
     68static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
     69                                                   SDL_Keysym * keysym, Uint32 *unicode);
     70
     71static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys);
     72static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
     73
     74static void UnicodeToUtf8( Uint16 w , char *utf8buf)
     75{
     76        unsigned char *utf8s = (unsigned char *) utf8buf;
     77
     78    if ( w < 0x0080 ) {
     79        utf8s[0] = ( unsigned char ) w;
     80        utf8s[1] = 0;
     81    }
     82    else if ( w < 0x0800 ) {
     83        utf8s[0] = 0xc0 | (( w ) >> 6 );
     84        utf8s[1] = 0x80 | (( w ) & 0x3f );
     85        utf8s[2] = 0;
     86    }
     87    else {
     88        utf8s[0] = 0xe0 | (( w ) >> 12 );
     89        utf8s[1] = 0x80 | (( ( w ) >> 6 ) & 0x3f );
     90        utf8s[2] = 0x80 | (( w ) & 0x3f );
     91        utf8s[3] = 0;
     92    }
     93}
     94
     95static void
     96FocusAllMice(_THIS, SDL_Window *window)
     97{
     98#if USE_MULTI_API
     99    SDL_DFB_DEVICEDATA(_this);
    100    int index;
    101
    102    for (index = 0; index < devdata->num_mice; index++)
    103        SDL_SetMouseFocus(devdata->mouse_id[index], id);
    104#else
    105    SDL_SetMouseFocus(window);
    106#endif
    107}
    108
    109
    110static void
    111FocusAllKeyboards(_THIS, SDL_Window *window)
    112{
    113#if USE_MULTI_API
    114    SDL_DFB_DEVICEDATA(_this);
    115    int index;
    116
    117    for (index = 0; index < devdata->num_keyboard; index++)
    118        SDL_SetKeyboardFocus(index, id);
    119#else
    120    SDL_SetKeyboardFocus(window);
    121#endif
    122}
    123
    124static void
    125MotionAllMice(_THIS, int x, int y)
    126{
    127#if USE_MULTI_API
    128    SDL_DFB_DEVICEDATA(_this);
    129    int index;
    130
    131    for (index = 0; index < devdata->num_mice; index++) {
    132        SDL_Mouse *mouse = SDL_GetMouse(index);
    133        mouse->x = mouse->last_x = x;
    134        mouse->y = mouse->last_y = y;
    135        /* SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0); */
    136    }
    137#endif
    138}
    139
    140static int
    141KbdIndex(_THIS, int id)
    142{
    143    SDL_DFB_DEVICEDATA(_this);
    144    int index;
    145
    146    for (index = 0; index < devdata->num_keyboard; index++) {
    147        if (devdata->keyboard[index].id == id)
    148            return index;
    149    }
    150    return -1;
    151}
    152
    153static int
    154ClientXY(DFB_WindowData * p, int *x, int *y)
    155{
    156    int cx, cy;
    157
    158    cx = *x;
    159    cy = *y;
    160
    161    cx -= p->client.x;
    162    cy -= p->client.y;
    163
    164    if (cx < 0 || cy < 0)
    165        return 0;
    166    if (cx >= p->client.w || cy >= p->client.h)
    167        return 0;
    168    *x = cx;
    169    *y = cy;
    170    return 1;
    171}
    172
    173static void
    174ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt)
    175{
    176    SDL_DFB_DEVICEDATA(_this);
    177    SDL_DFB_WINDOWDATA(sdlwin);
    178    SDL_Keysym keysym;
    179    Uint32 unicode;
    180    char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
    181
    182    if (evt->clazz == DFEC_WINDOW) {
    183        switch (evt->type) {
    184        case DWET_BUTTONDOWN:
    185            if (ClientXY(windata, &evt->x, &evt->y)) {
    186                if (!devdata->use_linux_input) {
    187                    SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
    188                                        evt->y, 0);
    189                    SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
    190                                        SDL_PRESSED,
    191                                        DirectFB_TranslateButton
    192                                        (evt->button));
    193                } else {
    194                    MotionAllMice(_this, evt->x, evt->y);
    195                }
    196            }
    197            break;
    198        case DWET_BUTTONUP:
    199            if (ClientXY(windata, &evt->x, &evt->y)) {
    200                if (!devdata->use_linux_input) {
    201                    SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
    202                                        evt->y, 0);
    203                    SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
    204                                        SDL_RELEASED,
    205                                        DirectFB_TranslateButton
    206                                        (evt->button));
    207                } else {
    208                    MotionAllMice(_this, evt->x, evt->y);
    209                }
    210            }
    211            break;
    212        case DWET_MOTION:
    213            if (ClientXY(windata, &evt->x, &evt->y)) {
    214                if (!devdata->use_linux_input) {
    215                    if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED))
    216                        SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0,
    217                                            evt->x, evt->y, 0);
    218                } else {
    219                    /* relative movements are not exact!
    220                     * This code should limit the number of events sent.
    221                     * However it kills MAME axis recognition ... */
    222                    static int cnt = 0;
    223                    if (1 && ++cnt > 20) {
    224                        MotionAllMice(_this, evt->x, evt->y);
    225                        cnt = 0;
    226                    }
    227                }
    228                if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS))
    229                    SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0,
    230                                        0);
    231            }
    232            break;
    233        case DWET_KEYDOWN:
    234            if (!devdata->use_linux_input) {
    235                DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
    236                /* printf("Scancode %d  %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
    237                SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode);
    238                if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
    239                    SDL_zero(text);
    240                    UnicodeToUtf8(unicode, text);
    241                    if (*text) {
    242                        SDL_SendKeyboardText_ex(0, text);
    243                    }
    244                }
    245            }
    246            break;
    247        case DWET_KEYUP:
    248            if (!devdata->use_linux_input) {
    249                DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
    250                SDL_SendKeyboardKey_ex(0, SDL_RELEASED, keysym.scancode);
    251            }
    252            break;
    253        case DWET_POSITION:
    254            if (ClientXY(windata, &evt->x, &evt->y)) {
    255                SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
    256                                    evt->x, evt->y);
    257            }
    258            break;
    259        case DWET_POSITION_SIZE:
    260            if (ClientXY(windata, &evt->x, &evt->y)) {
    261                SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
    262                                    evt->x, evt->y);
    263            }
    264            /* fall throught */
    265        case DWET_SIZE:
    266            /* FIXME: what about < 0 */
    267            evt->w -= (windata->theme.right_size + windata->theme.left_size);
    268            evt->h -=
    269                (windata->theme.top_size + windata->theme.bottom_size +
    270                 windata->theme.caption_size);
    271            SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED,
    272                                evt->w, evt->h);
    273            break;
    274        case DWET_CLOSE:
    275            SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0);
    276            break;
    277        case DWET_GOTFOCUS:
    278            DirectFB_SetContext(_this, sdlwin);
    279            FocusAllKeyboards(_this, sdlwin);
    280            SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED,
    281                                0, 0);
    282            break;
    283        case DWET_LOSTFOCUS:
    284            SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
    285            FocusAllKeyboards(_this, 0);
    286            break;
    287        case DWET_ENTER:
    288            /* SDL_DirectFB_ReshowCursor(_this, 0); */
    289            FocusAllMice(_this, sdlwin);
    290            /* FIXME: when do we really enter ? */
    291            if (ClientXY(windata, &evt->x, &evt->y))
    292                MotionAllMice(_this, evt->x, evt->y);
    293            SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0);
    294            break;
    295        case DWET_LEAVE:
    296            SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0);
    297            FocusAllMice(_this, 0);
    298            /* SDL_DirectFB_ReshowCursor(_this, 1); */
    299            break;
    300        default:
    301            ;
    302        }
    303    } else
    304        printf("Event Clazz %d\n", evt->clazz);
    305}
    306
    307static void
    308ProcessInputEvent(_THIS, DFBInputEvent * ievt)
    309{
    310    SDL_DFB_DEVICEDATA(_this);
    311    SDL_Keysym keysym;
    312    int kbd_idx;
    313    Uint32 unicode;
    314    char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
    315
    316    if (!devdata->use_linux_input) {
    317        if (ievt->type == DIET_AXISMOTION) {
    318            if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
    319                if (ievt->axis == DIAI_X)
    320                    SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
    321                                        ievt->axisrel, 0, 0);
    322                else if (ievt->axis == DIAI_Y)
    323                    SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
    324                                        ievt->axisrel, 0);
    325            }
    326        }
    327    } else {
    328        static int last_x, last_y;
    329
    330        switch (ievt->type) {
    331        case DIET_AXISMOTION:
    332            if (ievt->flags & DIEF_AXISABS) {
    333                if (ievt->axis == DIAI_X)
    334                    last_x = ievt->axisabs;
    335                else if (ievt->axis == DIAI_Y)
    336                    last_y = ievt->axisabs;
    337                if (!(ievt->flags & DIEF_FOLLOW)) {
    338#if USE_MULTI_API
    339                    SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id);
    340                    SDL_Window *window = SDL_GetWindowFromID(mouse->focus);
    341#else
    342                    SDL_Window *window = devdata->grabbed_window;
    343#endif
    344                    if (window) {
    345                        DFB_WindowData *windata =
    346                            (DFB_WindowData *) window->driverdata;
    347                        int x, y;
    348
    349                        windata->dfbwin->GetPosition(windata->dfbwin, &x, &y);
    350                        SDL_SendMouseMotion_ex(window, ievt->device_id, 0,
    351                                            last_x - (x +
    352                                                      windata->client.x),
    353                                            last_y - (y +
    354                                                      windata->client.y), 0);
    355                    } else {
    356                        SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x,
    357                                            last_y, 0);
    358                    }
    359                }
    360            } else if (ievt->flags & DIEF_AXISREL) {
    361                if (ievt->axis == DIAI_X)
    362                    SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
    363                                        ievt->axisrel, 0, 0);
    364                else if (ievt->axis == DIAI_Y)
    365                    SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
    366                                        ievt->axisrel, 0);
    367            }
    368            break;
    369        case DIET_KEYPRESS:
    370            kbd_idx = KbdIndex(_this, ievt->device_id);
    371            DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
    372            /* printf("Scancode %d  %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
    373            SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode);
    374            if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
    375                SDL_zero(text);
    376                UnicodeToUtf8(unicode, text);
    377                if (*text) {
    378                    SDL_SendKeyboardText_ex(kbd_idx, text);
    379                }
    380            }
    381            break;
    382        case DIET_KEYRELEASE:
    383            kbd_idx = KbdIndex(_this, ievt->device_id);
    384            DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
    385            SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode);
    386            break;
    387        case DIET_BUTTONPRESS:
    388            if (ievt->buttons & DIBM_LEFT)
    389                SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1);
    390            if (ievt->buttons & DIBM_MIDDLE)
    391                SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2);
    392            if (ievt->buttons & DIBM_RIGHT)
    393                SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3);
    394            break;
    395        case DIET_BUTTONRELEASE:
    396            if (!(ievt->buttons & DIBM_LEFT))
    397                SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1);
    398            if (!(ievt->buttons & DIBM_MIDDLE))
    399                SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2);
    400            if (!(ievt->buttons & DIBM_RIGHT))
    401                SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3);
    402            break;
    403        default:
    404            break;              /* please gcc */
    405        }
    406    }
    407}
    408
    409void
    410DirectFB_PumpEventsWindow(_THIS)
    411{
    412    SDL_DFB_DEVICEDATA(_this);
    413    DFBInputEvent ievt;
    414    SDL_Window *w;
    415
    416    for (w = devdata->firstwin; w != NULL; w = w->next) {
    417        SDL_DFB_WINDOWDATA(w);
    418        DFBWindowEvent evt;
    419
    420        while (windata->eventbuffer->GetEvent(windata->eventbuffer,
    421                                        DFB_EVENT(&evt)) == DFB_OK) {
    422            if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) {
    423                /* Send a SDL_SYSWMEVENT if the application wants them */
    424                if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
    425                    SDL_SysWMmsg wmmsg;
    426                    SDL_VERSION(&wmmsg.version);
    427                    wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
    428                    wmmsg.msg.dfb.event.window = evt;
    429                    SDL_SendSysWMEvent(&wmmsg);
    430                }
    431                ProcessWindowEvent(_this, w, &evt);
    432            }
    433        }
    434    }
    435
    436    /* Now get relative events in case we need them */
    437    while (devdata->events->GetEvent(devdata->events,
    438                                     DFB_EVENT(&ievt)) == DFB_OK) {
    439
    440        if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
    441            SDL_SysWMmsg wmmsg;
    442            SDL_VERSION(&wmmsg.version);
    443            wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
    444            wmmsg.msg.dfb.event.input = ievt;
    445            SDL_SendSysWMEvent(&wmmsg);
    446        }
    447        ProcessInputEvent(_this, &ievt);
    448    }
    449}
    450
    451void
    452DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys)
    453{
    454    int i;
    455
    456    /* Initialize the DirectFB key translation table */
    457    for (i = 0; i < numkeys; ++i)
    458        keymap[i] = SDL_SCANCODE_UNKNOWN;
    459
    460    keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
    461    keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B;
    462    keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C;
    463    keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D;
    464    keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E;
    465    keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F;
    466    keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G;
    467    keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H;
    468    keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I;
    469    keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J;
    470    keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K;
    471    keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L;
    472    keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M;
    473    keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N;
    474    keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O;
    475    keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P;
    476    keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q;
    477    keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R;
    478    keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S;
    479    keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T;
    480    keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U;
    481    keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V;
    482    keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W;
    483    keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X;
    484    keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y;
    485    keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z;
    486
    487    keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0;
    488    keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1;
    489    keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2;
    490    keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3;
    491    keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4;
    492    keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5;
    493    keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6;
    494    keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7;
    495    keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8;
    496    keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9;
    497
    498    keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1;
    499    keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2;
    500    keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3;
    501    keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4;
    502    keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5;
    503    keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6;
    504    keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7;
    505    keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8;
    506    keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9;
    507    keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10;
    508    keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11;
    509    keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12;
    510
    511    keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE;
    512    keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT;
    513    keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT;
    514    keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP;
    515    keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN;
    516    keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL;
    517    keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL;
    518    keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT;
    519    keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT;
    520    keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT;
    521    keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT;
    522    keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI;
    523    keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI;
    524    keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
    525    keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
    526    /* FIXME:Do we read hyper keys ?
    527     * keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
    528     * keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
    529     */
    530    keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB;
    531    keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN;
    532    keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE;
    533    keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE;
    534    keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT;
    535    keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE;
    536    keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME;
    537    keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END;
    538    keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP;
    539    keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN;
    540    keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK;
    541    keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR;
    542    keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK;
    543    keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN;
    544    keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE;
    545
    546    keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS;
    547    keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD;
    548    keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0;
    549    keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1;
    550    keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2;
    551    keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3;
    552    keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4;
    553    keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5;
    554    keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6;
    555    keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7;
    556    keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8;
    557    keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9;
    558    keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE;
    559    keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY;
    560    keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS;
    561    keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS;
    562    keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER;
    563
    564    keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE;        /*  TLDE  */
    565    keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS;        /*  AE11  */
    566    keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS;      /*  AE12  */
    567    keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET;       /*  AD11  */
    568    keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET;       /*  AD12  */
    569    keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH;     /*  BKSL  */
    570    keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON;     /*  AC10  */
    571    keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE;  /*  AC11  */
    572    keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA;     /*  AB08  */
    573    keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD;   /*  AB09  */
    574    keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH;     /*  AB10  */
    575    keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH;        /*  103rd  */
    576
    577}
    578
    579static SDL_Keysym *
    580DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode)
    581{
    582    SDL_DFB_DEVICEDATA(_this);
    583    int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */
    584    DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
    585
    586    keysym->scancode = SDL_SCANCODE_UNKNOWN;
    587
    588    if (kbd->map && evt->key_code >= kbd->map_adjust &&
    589        evt->key_code < kbd->map_size + kbd->map_adjust)
    590        keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
    591
    592    if (keysym->scancode == SDL_SCANCODE_UNKNOWN ||
    593        devdata->keyboard[kbd_idx].is_generic) {
    594        if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
    595            keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
    596        else
    597            keysym->scancode = SDL_SCANCODE_UNKNOWN;
    598    }
    599
    600    *unicode =
    601        (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
    602    if (*unicode == 0 &&
    603        (evt->key_symbol > 0 && evt->key_symbol < 255))
    604        *unicode = evt->key_symbol;
    605
    606    return keysym;
    607}
    608
    609static SDL_Keysym *
    610DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
    611                                SDL_Keysym * keysym, Uint32 *unicode)
    612{
    613    SDL_DFB_DEVICEDATA(_this);
    614    int kbd_idx = KbdIndex(_this, evt->device_id);
    615    DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
    616
    617    keysym->scancode = SDL_SCANCODE_UNKNOWN;
    618
    619    if (kbd->map && evt->key_code >= kbd->map_adjust &&
    620        evt->key_code < kbd->map_size + kbd->map_adjust)
    621        keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
    622
    623    if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) {
    624        if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
    625            keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
    626        else
    627            keysym->scancode = SDL_SCANCODE_UNKNOWN;
    628    }
    629
    630    *unicode =
    631        (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
    632    if (*unicode == 0 &&
    633        (evt->key_symbol > 0 && evt->key_symbol < 255))
    634        *unicode = evt->key_symbol;
    635
    636    return keysym;
    637}
    638
    639static int
    640DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
    641{
    642    switch (button) {
    643    case DIBI_LEFT:
    644        return 1;
    645    case DIBI_MIDDLE:
    646        return 2;
    647    case DIBI_RIGHT:
    648        return 3;
    649    default:
    650        return 0;
    651    }
    652}
    653
    654static DFBEnumerationResult
    655EnumKeyboards(DFBInputDeviceID device_id,
    656                DFBInputDeviceDescription desc, void *callbackdata)
    657{
    658    cb_data *cb = callbackdata;
    659    DFB_DeviceData *devdata = cb->devdata;
    660#if USE_MULTI_API
    661    SDL_Keyboard keyboard;
    662#endif
    663    SDL_Keycode keymap[SDL_NUM_SCANCODES];
    664
    665    if (!cb->sys_kbd) {
    666        if (cb->sys_ids) {
    667            if (device_id >= 0x10)
    668                return DFENUM_OK;
    669        } else {
    670            if (device_id < 0x10)
    671                return DFENUM_OK;
    672        }
    673    } else {
    674        if (device_id != DIDID_KEYBOARD)
    675            return DFENUM_OK;
    676    }
    677
    678    if ((desc.caps & DIDTF_KEYBOARD)) {
    679#if USE_MULTI_API
    680        SDL_zero(keyboard);
    681        SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
    682#endif
    683        devdata->keyboard[devdata->num_keyboard].id = device_id;
    684        devdata->keyboard[devdata->num_keyboard].is_generic = 0;
    685        if (!strncmp("X11", desc.name, 3))
    686        {
    687            devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2;
    688            devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2);
    689            devdata->keyboard[devdata->num_keyboard].map_adjust = 8;
    690        } else {
    691            devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table;
    692            devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table);
    693            devdata->keyboard[devdata->num_keyboard].map_adjust = 0;
    694        }
    695
    696        SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name);
    697
    698        SDL_GetDefaultKeymap(keymap);
    699#if USE_MULTI_API
    700        SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES);
    701#else
    702        SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
    703#endif
    704        devdata->num_keyboard++;
    705
    706        if (cb->sys_kbd)
    707            return DFENUM_CANCEL;
    708    }
    709    return DFENUM_OK;
    710}
    711
    712void
    713DirectFB_InitKeyboard(_THIS)
    714{
    715    SDL_DFB_DEVICEDATA(_this);
    716    cb_data cb;
    717
    718    DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
    719
    720    devdata->num_keyboard = 0;
    721    cb.devdata = devdata;
    722
    723    if (devdata->use_linux_input) {
    724        cb.sys_kbd = 0;
    725        cb.sys_ids = 0;
    726        SDL_DFB_CHECK(devdata->dfb->
    727                      EnumInputDevices(devdata->dfb, EnumKeyboards, &cb));
    728        if (devdata->num_keyboard == 0) {
    729            cb.sys_ids = 1;
    730            SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
    731                                                         EnumKeyboards,
    732                                                         &cb));
    733        }
    734    } else {
    735        cb.sys_kbd = 1;
    736        SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
    737                                                     EnumKeyboards,
    738                                                     &cb));
    739    }
    740}
    741
    742void
    743DirectFB_QuitKeyboard(_THIS)
    744{
    745    /* SDL_DFB_DEVICEDATA(_this); */
    746
    747    SDL_KeyboardQuit();
    748
    749}
    750
    751#endif /* SDL_VIDEO_DRIVER_DIRECTFB */