src/video/directfb/SDL_DirectFB_events.c
author Gabriel Jacobo <gabomdq@gmail.com>
Wed, 21 Aug 2013 09:47:10 -0300
changeset 7678 286c42d7c5ed
parent 7677 871d43c6968a
child 8093 b43765095a6f
permissions -rw-r--r--
OCD fixes: Adds a space after /* (glory to regular expressions!)
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 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_config.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_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 
   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_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 
   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     SDL_KeyboardQuit();
   748 
   749 }
   750 
   751 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */