src/video/directfb/SDL_DirectFB_events.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 02 Mar 2013 20:44:16 -0800
changeset 6950 1ddb72193079
parent 6885 700f1b25f77f
child 7191 75360622e65f
permissions -rw-r--r--
Added a mouse ID to the mouse events, which set to the special value SDL_TOUCH_MOUSEID for mouse events simulated by touch input.
     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);
    68 static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
    69                                                    SDL_Keysym * keysym);
    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     char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
   180 
   181     if (evt->clazz == DFEC_WINDOW) {
   182         switch (evt->type) {
   183         case DWET_BUTTONDOWN:
   184             if (ClientXY(windata, &evt->x, &evt->y)) {
   185                 if (!devdata->use_linux_input) {
   186                     SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
   187                                         evt->y, 0);
   188                     SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
   189                                         SDL_PRESSED,
   190                                         DirectFB_TranslateButton
   191                                         (evt->button));
   192                 } else {
   193                     MotionAllMice(_this, evt->x, evt->y);
   194                 }
   195             }
   196             break;
   197         case DWET_BUTTONUP:
   198             if (ClientXY(windata, &evt->x, &evt->y)) {
   199                 if (!devdata->use_linux_input) {
   200                     SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
   201                                         evt->y, 0);
   202                     SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
   203                                         SDL_RELEASED,
   204                                         DirectFB_TranslateButton
   205                                         (evt->button));
   206                 } else {
   207                     MotionAllMice(_this, evt->x, evt->y);
   208                 }
   209             }
   210             break;
   211         case DWET_MOTION:
   212             if (ClientXY(windata, &evt->x, &evt->y)) {
   213                 if (!devdata->use_linux_input) {
   214                     if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED))
   215                         SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0,
   216                                             evt->x, evt->y, 0);
   217                 } else {
   218                     /* relative movements are not exact! 
   219                      * This code should limit the number of events sent.
   220                      * However it kills MAME axis recognition ... */
   221                     static int cnt = 0;
   222                     if (1 && ++cnt > 20) {
   223                         MotionAllMice(_this, evt->x, evt->y);
   224                         cnt = 0;
   225                     }
   226                 }
   227                 if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS))
   228                     SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0,
   229                                         0);
   230             }
   231             break;
   232         case DWET_KEYDOWN:
   233             if (!devdata->use_linux_input) {
   234                 DirectFB_TranslateKey(_this, evt, &keysym);
   235                 //printf("Scancode %d  %d %d\n", keysym.scancode, evt->key_code, evt->key_id);
   236                 SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode);
   237                 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   238 	                SDL_zero(text);
   239                     UnicodeToUtf8(keysym.unicode, text);
   240                     if (*text) {
   241                         SDL_SendKeyboardText_ex(0, text);
   242                     }
   243                 }
   244             }
   245             break;
   246         case DWET_KEYUP:
   247             if (!devdata->use_linux_input) {
   248                 DirectFB_TranslateKey(_this, evt, &keysym);
   249                 SDL_SendKeyboardKey_ex(0, SDL_RELEASED, keysym.scancode);
   250             }
   251             break;
   252         case DWET_POSITION:
   253             if (ClientXY(windata, &evt->x, &evt->y)) {
   254                 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
   255                                     evt->x, evt->y);
   256             }
   257             break;
   258         case DWET_POSITION_SIZE:
   259             if (ClientXY(windata, &evt->x, &evt->y)) {
   260                 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
   261                                     evt->x, evt->y);
   262             }
   263             /* fall throught */
   264         case DWET_SIZE:
   265             // FIXME: what about < 0
   266             evt->w -= (windata->theme.right_size + windata->theme.left_size);
   267             evt->h -=
   268                 (windata->theme.top_size + windata->theme.bottom_size +
   269                  windata->theme.caption_size);
   270             SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED,
   271                                 evt->w, evt->h);
   272             break;
   273         case DWET_CLOSE:
   274             SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0);
   275             break;
   276         case DWET_GOTFOCUS:
   277             DirectFB_SetContext(_this, sdlwin);
   278             FocusAllKeyboards(_this, sdlwin);
   279             SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED,
   280                                 0, 0);
   281             break;
   282         case DWET_LOSTFOCUS:
   283             SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
   284             FocusAllKeyboards(_this, 0);
   285             break;
   286         case DWET_ENTER:
   287             /* SDL_DirectFB_ReshowCursor(_this, 0); */
   288             FocusAllMice(_this, sdlwin);
   289             // FIXME: when do we really enter ?
   290             if (ClientXY(windata, &evt->x, &evt->y))
   291                 MotionAllMice(_this, evt->x, evt->y);
   292             SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0);
   293             break;
   294         case DWET_LEAVE:
   295             SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0);
   296             FocusAllMice(_this, 0);
   297             /* SDL_DirectFB_ReshowCursor(_this, 1); */
   298             break;
   299         default:
   300             ;
   301         }
   302     } else
   303         printf("Event Clazz %d\n", evt->clazz);
   304 }
   305 
   306 static void
   307 ProcessInputEvent(_THIS, DFBInputEvent * ievt)
   308 {
   309     SDL_DFB_DEVICEDATA(_this);
   310     SDL_Keysym keysym;
   311     int kbd_idx;
   312     char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
   313 
   314     if (!devdata->use_linux_input) {
   315         if (ievt->type == DIET_AXISMOTION) {
   316             if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
   317                 if (ievt->axis == DIAI_X)
   318                     SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
   319                                         ievt->axisrel, 0, 0);
   320                 else if (ievt->axis == DIAI_Y)
   321                     SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
   322                                         ievt->axisrel, 0);
   323             }
   324         }
   325     } else {
   326         static int last_x, last_y;
   327 
   328         switch (ievt->type) {
   329         case DIET_AXISMOTION:
   330             if (ievt->flags & DIEF_AXISABS) {
   331                 if (ievt->axis == DIAI_X)
   332                     last_x = ievt->axisabs;
   333                 else if (ievt->axis == DIAI_Y)
   334                     last_y = ievt->axisabs;
   335                 if (!(ievt->flags & DIEF_FOLLOW)) {
   336 #if USE_MULTI_API
   337                     SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id);
   338                     SDL_Window *window = SDL_GetWindowFromID(mouse->focus);
   339 #else
   340                     SDL_Window *window = devdata->grabbed_window;
   341 #endif
   342                     if (window) {
   343                         DFB_WindowData *windata =
   344                             (DFB_WindowData *) window->driverdata;
   345                         int x, y;
   346 
   347                         windata->dfbwin->GetPosition(windata->dfbwin, &x, &y);
   348                         SDL_SendMouseMotion_ex(window, ievt->device_id, 0,
   349                                             last_x - (x +
   350                                                       windata->client.x),
   351                                             last_y - (y +
   352                                                       windata->client.y), 0);
   353                     } else {
   354                         SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x,
   355                                             last_y, 0);
   356                     }
   357                 }
   358             } else if (ievt->flags & DIEF_AXISREL) {
   359                 if (ievt->axis == DIAI_X)
   360                     SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
   361                                         ievt->axisrel, 0, 0);
   362                 else if (ievt->axis == DIAI_Y)
   363                     SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
   364                                         ievt->axisrel, 0);
   365             }
   366             break;
   367         case DIET_KEYPRESS:
   368             kbd_idx = KbdIndex(_this, ievt->device_id);
   369             DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym);
   370             //printf("Scancode %d  %d %d\n", keysym.scancode, evt->key_code, evt->key_id);
   371             SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode);
   372             if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   373                 SDL_zero(text);
   374                 UnicodeToUtf8(keysym.unicode, text);
   375                 if (*text) {
   376                     SDL_SendKeyboardText_ex(kbd_idx, text);
   377                 }
   378             }
   379             break;
   380         case DIET_KEYRELEASE:
   381             kbd_idx = KbdIndex(_this, ievt->device_id);
   382             DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym);
   383             SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode);
   384             break;
   385         case DIET_BUTTONPRESS:
   386             if (ievt->buttons & DIBM_LEFT)
   387                 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1);
   388             if (ievt->buttons & DIBM_MIDDLE)
   389                 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2);
   390             if (ievt->buttons & DIBM_RIGHT)
   391                 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3);
   392             break;
   393         case DIET_BUTTONRELEASE:
   394             if (!(ievt->buttons & DIBM_LEFT))
   395                 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1);
   396             if (!(ievt->buttons & DIBM_MIDDLE))
   397                 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2);
   398             if (!(ievt->buttons & DIBM_RIGHT))
   399                 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3);
   400             break;
   401         default:
   402             break;              /* please gcc */
   403         }
   404     }
   405 }
   406 
   407 void
   408 DirectFB_PumpEventsWindow(_THIS)
   409 {
   410     SDL_DFB_DEVICEDATA(_this);
   411     DFBInputEvent ievt;
   412     SDL_Window *w;
   413 
   414     for (w = devdata->firstwin; w != NULL; w = w->next) {
   415         SDL_DFB_WINDOWDATA(w);
   416         DFBWindowEvent evt;
   417 
   418         while (windata->eventbuffer->GetEvent(windata->eventbuffer,
   419                                         DFB_EVENT(&evt)) == DFB_OK) {
   420             if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) {
   421                 /* Send a SDL_SYSWMEVENT if the application wants them */
   422                 if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
   423                     SDL_SysWMmsg wmmsg;
   424                     SDL_VERSION(&wmmsg.version);
   425                     wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
   426                     wmmsg.msg.dfb.event.window = evt;
   427                     SDL_SendSysWMEvent(&wmmsg);
   428                 }
   429                 ProcessWindowEvent(_this, w, &evt);
   430             }
   431         }
   432     }
   433 
   434     /* Now get relative events in case we need them */
   435     while (devdata->events->GetEvent(devdata->events,
   436                                      DFB_EVENT(&ievt)) == DFB_OK) {
   437 
   438     	if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
   439             SDL_SysWMmsg wmmsg;
   440             SDL_VERSION(&wmmsg.version);
   441             wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
   442             wmmsg.msg.dfb.event.input = ievt;
   443             SDL_SendSysWMEvent(&wmmsg);
   444         }
   445         ProcessInputEvent(_this, &ievt);
   446     }
   447 }
   448 
   449 void
   450 DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys)
   451 {
   452     int i;
   453 
   454     /* Initialize the DirectFB key translation table */
   455     for (i = 0; i < numkeys; ++i)
   456         keymap[i] = SDL_SCANCODE_UNKNOWN;
   457 
   458     keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
   459     keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B;
   460     keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C;
   461     keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D;
   462     keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E;
   463     keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F;
   464     keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G;
   465     keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H;
   466     keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I;
   467     keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J;
   468     keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K;
   469     keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L;
   470     keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M;
   471     keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N;
   472     keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O;
   473     keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P;
   474     keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q;
   475     keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R;
   476     keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S;
   477     keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T;
   478     keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U;
   479     keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V;
   480     keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W;
   481     keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X;
   482     keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y;
   483     keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z;
   484 
   485     keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0;
   486     keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1;
   487     keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2;
   488     keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3;
   489     keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4;
   490     keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5;
   491     keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6;
   492     keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7;
   493     keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8;
   494     keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9;
   495 
   496     keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1;
   497     keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2;
   498     keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3;
   499     keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4;
   500     keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5;
   501     keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6;
   502     keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7;
   503     keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8;
   504     keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9;
   505     keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10;
   506     keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11;
   507     keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12;
   508 
   509     keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE;
   510     keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT;
   511     keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT;
   512     keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP;
   513     keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN;
   514     keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL;
   515     keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL;
   516     keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT;
   517     keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT;
   518     keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT;
   519     keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT;
   520     keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI;
   521     keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI;
   522     keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   523     keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   524     /* FIXME:Do we read hyper keys ?
   525      * keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   526      * keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   527      */
   528     keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB;
   529     keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN;
   530     keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE;
   531     keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE;
   532     keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT;
   533     keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE;
   534     keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME;
   535     keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END;
   536     keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP;
   537     keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN;
   538     keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK;
   539     keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR;
   540     keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK;
   541     keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN;
   542     keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE;
   543 
   544     keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS;
   545     keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD;
   546     keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0;
   547     keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1;
   548     keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2;
   549     keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3;
   550     keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4;
   551     keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5;
   552     keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6;
   553     keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7;
   554     keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8;
   555     keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9;
   556     keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE;
   557     keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY;
   558     keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS;
   559     keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS;
   560     keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER;
   561 
   562     keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE;        /*  TLDE  */
   563     keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS;        /*  AE11  */
   564     keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS;      /*  AE12  */
   565     keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET;       /*  AD11  */
   566     keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET;       /*  AD12  */
   567     keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH;     /*  BKSL  */
   568     keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON;     /*  AC10  */
   569     keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE;  /*  AC11  */
   570     keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA;     /*  AB08  */
   571     keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD;   /*  AB09  */
   572     keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH;     /*  AB10  */
   573     keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH;        /*  103rd  */
   574 
   575 }
   576 
   577 static SDL_Keysym *
   578 DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym)
   579 {
   580     SDL_DFB_DEVICEDATA(_this);
   581     int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */
   582     DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
   583 
   584     keysym->scancode = SDL_SCANCODE_UNKNOWN;
   585 
   586     if (kbd->map && evt->key_code >= kbd->map_adjust &&
   587 	    evt->key_code < kbd->map_size + kbd->map_adjust)
   588 	    keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
   589 
   590     if (keysym->scancode == SDL_SCANCODE_UNKNOWN ||
   591         devdata->keyboard[kbd_idx].is_generic) {
   592         if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
   593             keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
   594         else
   595             keysym->scancode = SDL_SCANCODE_UNKNOWN;
   596     }
   597 
   598     keysym->unicode =
   599         (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
   600     if (keysym->unicode == 0 &&
   601         (evt->key_symbol > 0 && evt->key_symbol < 255))
   602         keysym->unicode = evt->key_symbol;
   603 
   604     return keysym;
   605 }
   606 
   607 static SDL_Keysym *
   608 DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
   609                                 SDL_Keysym * keysym)
   610 {
   611     SDL_DFB_DEVICEDATA(_this);
   612     int kbd_idx = KbdIndex(_this, evt->device_id);
   613     DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
   614 
   615     keysym->scancode = SDL_SCANCODE_UNKNOWN;
   616 
   617     if (kbd->map && evt->key_code >= kbd->map_adjust &&
   618 	    evt->key_code < kbd->map_size + kbd->map_adjust)
   619 	    keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
   620 
   621     if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) {
   622         if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
   623             keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
   624         else
   625             keysym->scancode = SDL_SCANCODE_UNKNOWN;
   626     }
   627 
   628     keysym->unicode =
   629         (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
   630     if (keysym->unicode == 0 &&
   631         (evt->key_symbol > 0 && evt->key_symbol < 255))
   632         keysym->unicode = evt->key_symbol;
   633 
   634     return keysym;
   635 }
   636 
   637 static int
   638 DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
   639 {
   640     switch (button) {
   641     case DIBI_LEFT:
   642         return 1;
   643     case DIBI_MIDDLE:
   644         return 2;
   645     case DIBI_RIGHT:
   646         return 3;
   647     default:
   648         return 0;
   649     }
   650 }
   651 
   652 static DFBEnumerationResult
   653 EnumKeyboards(DFBInputDeviceID device_id,
   654                 DFBInputDeviceDescription desc, void *callbackdata)
   655 {
   656 	cb_data *cb = callbackdata;
   657     DFB_DeviceData *devdata = cb->devdata;
   658 #if USE_MULTI_API
   659     SDL_Keyboard keyboard;
   660 #endif
   661     SDL_Keycode keymap[SDL_NUM_SCANCODES];
   662 
   663 	if (!cb->sys_kbd) {
   664 		if (cb->sys_ids) {
   665 		    if (device_id >= 0x10)
   666 		        return DFENUM_OK;
   667 		} else {
   668 		    if (device_id < 0x10)
   669 		        return DFENUM_OK;
   670 		}
   671 	} else {
   672 		if (device_id != DIDID_KEYBOARD)
   673 		    return DFENUM_OK;
   674 	}
   675 	
   676     if ((desc.caps & DIDTF_KEYBOARD)) {
   677 #if USE_MULTI_API
   678         SDL_zero(keyboard);
   679         SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
   680 #endif
   681         devdata->keyboard[devdata->num_keyboard].id = device_id;
   682         devdata->keyboard[devdata->num_keyboard].is_generic = 0;
   683         if (!strncmp("X11", desc.name, 3))
   684         {
   685         	devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2;
   686         	devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2);
   687 			devdata->keyboard[devdata->num_keyboard].map_adjust = 8;
   688         } else {
   689         	devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table;
   690         	devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table);
   691 			devdata->keyboard[devdata->num_keyboard].map_adjust = 0;
   692         }
   693 
   694 		SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name);
   695 		
   696         SDL_GetDefaultKeymap(keymap);
   697 #if USE_MULTI_API
   698         SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES);
   699 #else
   700         SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
   701 #endif
   702         devdata->num_keyboard++;
   703 
   704 		if (cb->sys_kbd)
   705 	        return DFENUM_CANCEL;
   706     }
   707     return DFENUM_OK;
   708 }
   709 
   710 void
   711 DirectFB_InitKeyboard(_THIS)
   712 {
   713     SDL_DFB_DEVICEDATA(_this);
   714 	cb_data cb;    
   715 	
   716     DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
   717 
   718     devdata->num_keyboard = 0;
   719     cb.devdata = devdata;
   720     
   721     if (devdata->use_linux_input) {
   722     	cb.sys_kbd = 0;
   723         cb.sys_ids = 0;
   724         SDL_DFB_CHECK(devdata->dfb->
   725                       EnumInputDevices(devdata->dfb, EnumKeyboards, &cb));
   726         if (devdata->num_keyboard == 0) {
   727             cb.sys_ids = 1;
   728             SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
   729                                                          EnumKeyboards,
   730                                                          &cb));
   731         }
   732     } else {
   733     	cb.sys_kbd = 1;
   734         SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
   735                                                      EnumKeyboards,
   736                                                      &cb));
   737     }
   738 }
   739 
   740 void
   741 DirectFB_QuitKeyboard(_THIS)
   742 {
   743     //SDL_DFB_DEVICEDATA(_this);
   744 
   745     SDL_KeyboardQuit();
   746 
   747 }
   748 
   749 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */