sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_DirectFB_events.c (28773B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 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 
     54 typedef struct _cb_data cb_data;
     55 struct _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 */
     63 static SDL_Scancode oskeymap[256];
     64 
     65 
     66 static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
     67                                          SDL_Keysym * keysym, Uint32 *unicode);
     68 static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
     69                                                    SDL_Keysym * keysym, Uint32 *unicode);
     70 
     71 static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys);
     72 static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
     73 
     74 static 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 
     95 static void
     96 FocusAllMice(_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 
    110 static void
    111 FocusAllKeyboards(_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 
    124 static void
    125 MotionAllMice(_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 
    140 static int
    141 KbdIndex(_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 
    153 static int
    154 ClientXY(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 
    173 static void
    174 ProcessWindowEvent(_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_zeroa(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 
    307 static void
    308 ProcessInputEvent(_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_zeroa(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 
    409 void
    410 DirectFB_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 
    451 void
    452 DirectFB_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 
    579 static SDL_Keysym *
    580 DirectFB_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 
    609 static SDL_Keysym *
    610 DirectFB_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 
    639 static int
    640 DirectFB_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 
    654 static DFBEnumerationResult
    655 EnumKeyboards(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 
    712 void
    713 DirectFB_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 
    742 void
    743 DirectFB_QuitKeyboard(_THIS)
    744 {
    745     /* SDL_DFB_DEVICEDATA(_this); */
    746 }
    747 
    748 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */