src/video/directfb/SDL_DirectFB_events.c
author Bob Pendleton <bob@pendleton.com>
Fri, 09 Jan 2009 20:43:30 +0000
changeset 3011 8f4ed5ec2b06
parent 2998 d364ee9b9c15
child 3013 8cc00819c8d6
permissions -rw-r--r--
I ran a global "make indent" it modified the following files.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* Handle the event stream, converting DirectFB input events into SDL events */
    25 
    26 #include <directfb.h>
    27 
    28 #include "../SDL_sysvideo.h"
    29 #include "../../events/SDL_sysevents.h"
    30 #include "../../events/SDL_events_c.h"
    31 #include "../../events/SDL_keyboard_c.h"
    32 #include "../../events/scancodes_linux.h"
    33 #include "SDL_DirectFB_events.h"
    34 
    35 /* The translation tables from a DirectFB keycode to a SDL keysym */
    36 static SDLKey oskeymap[256];
    37 static int sys_ids;
    38 
    39 static SDL_keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
    40                                          SDL_keysym * keysym);
    41 static SDL_keysym *DirectFB_TranslateKeyInputEvent(_THIS, int index,
    42                                                    DFBInputEvent * evt,
    43                                                    SDL_keysym * keysym);
    44 
    45 static void DirectFB_InitOSKeymap(_THIS, SDLKey * keypmap, int numkeys);
    46 static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
    47 
    48 static void
    49 DirectFB_SetContext(_THIS, SDL_WindowID id)
    50 {
    51 #if (DIRECTFB_MAJOR_VERSION >= 1)
    52     /* FIXME: does not work on 1.0/1.2 with radeon driver
    53      *        the approach did work with the matrox driver
    54      *        This has simply no effect.
    55      */
    56 
    57     SDL_Window *window = SDL_GetWindowFromID(id);
    58     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
    59     DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
    60     int ret;
    61 
    62     if (dispdata->vidIDinuse)
    63         SDL_DFB_CHECKERR(dispdata->
    64                          vidlayer->SwitchContext(dispdata->vidlayer,
    65                                                  DFB_TRUE));
    66 
    67   error:
    68     return;
    69 #endif
    70 
    71 }
    72 
    73 static void
    74 FocusAllMice(_THIS, SDL_WindowID id)
    75 {
    76     SDL_DFB_DEVICEDATA(_this);
    77     int index;
    78 
    79     for (index = 0; index < devdata->num_mice; index++)
    80         SDL_SetMouseFocus(devdata->mouse_id[index], id);
    81 }
    82 
    83 
    84 static void
    85 FocusAllKeyboards(_THIS, SDL_WindowID id)
    86 {
    87     SDL_DFB_DEVICEDATA(_this);
    88     int index;
    89 
    90     for (index = 0; index < devdata->num_keyboard; index++)
    91         SDL_SetKeyboardFocus(index, id);
    92 }
    93 
    94 static void
    95 MotionAllMice(_THIS, int x, int y)
    96 {
    97     SDL_DFB_DEVICEDATA(_this);
    98     int index;
    99 
   100     for (index = 0; index < devdata->num_mice; index++) {
   101         SDL_Mouse *mouse = SDL_GetMouse(index);
   102         mouse->x = mouse->last_x = x;
   103         mouse->y = mouse->last_y = y;
   104         //SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0);
   105     }
   106 }
   107 
   108 static int
   109 KbdIndex(_THIS, int id)
   110 {
   111     SDL_DFB_DEVICEDATA(_this);
   112     int index;
   113 
   114     for (index = 0; index < devdata->num_keyboard; index++) {
   115         if (devdata->keyboard[index].id == id)
   116             return index;
   117     }
   118     return -1;
   119 }
   120 
   121 void
   122 DirectFB_PumpEventsWindow(_THIS)
   123 {
   124     SDL_DFB_DEVICEDATA(_this);
   125     DFB_WindowData *p;
   126     DFBInputEvent ievt;
   127     Sint32 /* SDL_WindowID */ grabbed_window;
   128     char text[5];
   129     int kbd_idx;
   130 
   131     grabbed_window = -1;
   132 
   133     for (p = devdata->firstwin; p != NULL; p = p->next) {
   134         DFBWindowEvent evt;
   135         SDL_Window *w = SDL_GetWindowFromID(p->id);
   136 
   137         if (w->flags & SDL_WINDOW_INPUT_GRABBED) {
   138             grabbed_window = p->id;
   139         }
   140 
   141         while (p->eventbuffer->GetEvent(p->eventbuffer,
   142                                         DFB_EVENT(&evt)) == DFB_OK) {
   143             SDL_keysym keysym;
   144 
   145             if (evt.clazz == DFEC_WINDOW) {
   146                 switch (evt.type) {
   147                 case DWET_BUTTONDOWN:
   148                     if (!devdata->use_linux_input) {
   149                         SDL_SendMouseMotion(devdata->mouse_id[0], 0, evt.cx,
   150                                             evt.cy, 0);
   151                         SDL_SendMouseButton(devdata->mouse_id[0], SDL_PRESSED,
   152                                             DirectFB_TranslateButton
   153                                             (evt.button));
   154                     } else {
   155                         MotionAllMice(_this, evt.x, evt.y);
   156                     }
   157                     break;
   158                 case DWET_BUTTONUP:
   159                     if (!devdata->use_linux_input) {
   160                         SDL_SendMouseMotion(devdata->mouse_id[0], 0, evt.cx,
   161                                             evt.cy, 0);
   162                         SDL_SendMouseButton(devdata->mouse_id[0],
   163                                             SDL_RELEASED,
   164                                             DirectFB_TranslateButton
   165                                             (evt.button));
   166                     } else {
   167                         MotionAllMice(_this, evt.x, evt.y);
   168                     }
   169                     break;
   170                 case DWET_MOTION:
   171                     if (!devdata->use_linux_input) {
   172                         if (!(w->flags & SDL_WINDOW_INPUT_GRABBED))
   173                             SDL_SendMouseMotion(devdata->mouse_id[0], 0,
   174                                                 evt.cx, evt.cy, 0);
   175                     } else {
   176                         /* relative movements are not exact! 
   177                          * This code should limit the number of events sent.
   178                          * However it kills MAME axis recognition ... */
   179                         static int cnt = 0;
   180                         if (1 && ++cnt > 20) {
   181                             MotionAllMice(_this, evt.x, evt.y);
   182                             cnt = 0;
   183                         }
   184                     }
   185                     break;
   186                 case DWET_KEYDOWN:
   187                     if (!devdata->use_linux_input) {
   188                         DirectFB_TranslateKey(_this, &evt, &keysym);
   189                         SDL_SendKeyboardKey(0, SDL_PRESSED, keysym.scancode);
   190                         if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   191                             SDL_memcpy(text, &keysym.unicode, 4);
   192                             text[4] = 0;
   193                             if (*text) {
   194                                 SDL_SendKeyboardText(0, text);
   195                             }
   196                         }
   197                     }
   198                     break;
   199                 case DWET_KEYUP:
   200                     if (!devdata->use_linux_input) {
   201                         DirectFB_TranslateKey(_this, &evt, &keysym);
   202                         SDL_SendKeyboardKey(0, SDL_RELEASED, keysym.scancode);
   203                     }
   204                     break;
   205                 case DWET_POSITION_SIZE:
   206                     if (evt.x != w->x || evt.y != w->y)
   207                         SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED,
   208                                             evt.x, evt.y);
   209                     if (evt.w != w->w || evt.h != w->h)
   210                         SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED,
   211                                             evt.w, evt.h);
   212                     break;
   213                 case DWET_POSITION:
   214                     if (evt.x != w->x || evt.y != w->y)
   215                         SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED,
   216                                             evt.x, evt.y);
   217                     break;
   218                 case DWET_SIZE:
   219                     if (evt.w != w->w || evt.h != w->h)
   220                         SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED,
   221                                             evt.w, evt.h);
   222                     break;
   223                 case DWET_CLOSE:
   224                     SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_CLOSE, 0, 0);
   225                     break;
   226                 case DWET_GOTFOCUS:
   227                     DirectFB_SetContext(_this, p->id);
   228                     FocusAllKeyboards(_this, p->id);
   229                     SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_FOCUS_GAINED,
   230                                         0, 0);
   231                     break;
   232                 case DWET_LOSTFOCUS:
   233                     SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_FOCUS_LOST, 0,
   234                                         0);
   235                     FocusAllKeyboards(_this, 0);
   236                     break;
   237                 case DWET_ENTER:
   238                     /* SDL_DirectFB_ReshowCursor(_this, 0); */
   239                     FocusAllMice(_this, p->id);
   240                     MotionAllMice(_this, evt.x, evt.y);
   241                     SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_ENTER, 0, 0);
   242                     break;
   243                 case DWET_LEAVE:
   244                     SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_LEAVE, 0, 0);
   245                     FocusAllMice(_this, 0);
   246                     /* SDL_DirectFB_ReshowCursor(_this, 1); */
   247                     break;
   248                 default:
   249                     ;
   250                 }
   251             } else
   252                 printf("Event Clazz %d\n", evt.clazz);
   253 
   254         }
   255     }
   256 
   257     /* Now get relative events in case we need them */
   258     while (devdata->events->GetEvent(devdata->events,
   259                                      DFB_EVENT(&ievt)) == DFB_OK) {
   260         SDL_keysym keysym;
   261 
   262         switch (ievt.type) {
   263         case DIET_AXISMOTION:
   264             if (!devdata->use_linux_input) {
   265                 if ((grabbed_window >= 0) && (ievt.flags & DIEF_AXISREL)) {
   266                     printf("rel devid %d\n", ievt.device_id);
   267                     if (ievt.axis == DIAI_X)
   268                         SDL_SendMouseMotion(ievt.device_id, 1, ievt.axisrel,
   269                                             0, 0);
   270                     else if (ievt.axis == DIAI_Y)
   271                         SDL_SendMouseMotion(ievt.device_id, 1, 0,
   272                                             ievt.axisrel, 0);
   273                 }
   274             }
   275             break;
   276         }
   277         if (devdata->use_linux_input) {
   278             IDirectFBInputDevice *idev;
   279             static int last_x, last_y;
   280 
   281             switch (ievt.type) {
   282             case DIET_AXISMOTION:
   283                 if (ievt.flags & DIEF_AXISABS) {
   284                     if (ievt.axis == DIAI_X)
   285                         last_x = ievt.axisabs;
   286                     else if (ievt.axis == DIAI_Y)
   287                         last_y = ievt.axisabs;
   288                     if (!(ievt.flags & DIEF_FOLLOW))
   289                         SDL_SendMouseMotion(ievt.device_id, 0, last_x, last_y,
   290                                             0);
   291                 } else if (ievt.flags & DIEF_AXISREL) {
   292                     //printf("rel %d %d\n", ievt.device_id, ievt.axisrel);
   293                     if (ievt.axis == DIAI_X)
   294                         SDL_SendMouseMotion(ievt.device_id, 1, ievt.axisrel,
   295                                             0, 0);
   296                     else if (ievt.axis == DIAI_Y)
   297                         SDL_SendMouseMotion(ievt.device_id, 1, 0,
   298                                             ievt.axisrel, 0);
   299                 }
   300                 break;
   301             case DIET_KEYPRESS:
   302                 kbd_idx = KbdIndex(_this, ievt.device_id);
   303                 DirectFB_TranslateKeyInputEvent(_this, kbd_idx, &ievt,
   304                                                 &keysym);
   305                 SDL_SendKeyboardKey(kbd_idx, SDL_PRESSED, keysym.scancode);
   306                 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   307                     SDL_memcpy(text, &keysym.unicode, 4);
   308                     text[4] = 0;
   309                     if (*text) {
   310                         SDL_SendKeyboardText(kbd_idx, text);
   311                     }
   312                 }
   313                 break;
   314             case DIET_KEYRELEASE:
   315                 kbd_idx = KbdIndex(_this, ievt.device_id);
   316                 DirectFB_TranslateKeyInputEvent(_this, kbd_idx, &ievt,
   317                                                 &keysym);
   318                 SDL_SendKeyboardKey(kbd_idx, SDL_RELEASED, keysym.scancode);
   319                 break;
   320             case DIET_BUTTONPRESS:
   321                 if (ievt.buttons & DIBM_LEFT)
   322                     SDL_SendMouseButton(ievt.device_id, SDL_PRESSED, 1);
   323                 if (ievt.buttons & DIBM_MIDDLE)
   324                     SDL_SendMouseButton(ievt.device_id, SDL_PRESSED, 2);
   325                 if (ievt.buttons & DIBM_RIGHT)
   326                     SDL_SendMouseButton(ievt.device_id, SDL_PRESSED, 3);
   327                 break;
   328             case DIET_BUTTONRELEASE:
   329                 if (!(ievt.buttons & DIBM_LEFT))
   330                     SDL_SendMouseButton(ievt.device_id, SDL_RELEASED, 1);
   331                 if (!(ievt.buttons & DIBM_MIDDLE))
   332                     SDL_SendMouseButton(ievt.device_id, SDL_RELEASED, 2);
   333                 if (!(ievt.buttons & DIBM_RIGHT))
   334                     SDL_SendMouseButton(ievt.device_id, SDL_RELEASED, 3);
   335                 break;
   336             }
   337         }
   338     }
   339 }
   340 
   341 void
   342 DirectFB_InitOSKeymap(_THIS, SDLKey * keymap, int numkeys)
   343 {
   344     int i;
   345 
   346     /* Initialize the DirectFB key translation table */
   347     for (i = 0; i < numkeys; ++i)
   348         keymap[i] = SDL_SCANCODE_UNKNOWN;
   349 
   350     keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
   351     keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B;
   352     keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C;
   353     keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D;
   354     keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E;
   355     keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F;
   356     keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G;
   357     keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H;
   358     keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I;
   359     keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J;
   360     keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K;
   361     keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L;
   362     keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M;
   363     keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N;
   364     keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O;
   365     keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P;
   366     keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q;
   367     keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R;
   368     keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S;
   369     keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T;
   370     keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U;
   371     keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V;
   372     keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W;
   373     keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X;
   374     keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y;
   375     keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z;
   376 
   377     keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0;
   378     keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1;
   379     keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2;
   380     keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3;
   381     keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4;
   382     keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5;
   383     keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6;
   384     keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7;
   385     keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8;
   386     keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9;
   387 
   388     keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1;
   389     keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2;
   390     keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3;
   391     keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4;
   392     keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5;
   393     keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6;
   394     keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7;
   395     keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8;
   396     keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9;
   397     keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10;
   398     keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11;
   399     keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12;
   400 
   401     keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE;
   402     keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT;
   403     keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT;
   404     keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP;
   405     keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN;
   406     keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL;
   407     keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL;
   408     keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT;
   409     keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT;
   410     keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT;
   411     keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT;
   412     keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI;
   413     keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI;
   414     keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   415     keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   416     /* FIXME:Do we read hyper keys ?
   417      * keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   418      * keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
   419      */
   420     keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB;
   421     keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN;
   422     keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE;
   423     keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE;
   424     keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT;
   425     keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE;
   426     keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME;
   427     keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END;
   428     keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP;
   429     keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN;
   430     keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK;
   431     keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR;
   432     keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK;
   433     keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN;
   434     keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE;
   435 
   436     keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS;
   437     keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD;
   438     keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0;
   439     keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1;
   440     keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2;
   441     keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3;
   442     keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4;
   443     keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5;
   444     keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6;
   445     keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7;
   446     keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8;
   447     keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9;
   448     keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE;
   449     keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY;
   450     keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS;
   451     keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS;
   452     keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER;
   453 
   454     keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE;        /*  TLDE  */
   455     keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS;        /*  AE11  */
   456     keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS;      /*  AE12  */
   457     keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET;       /*  AD11  */
   458     keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET;       /*  AD12  */
   459     keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH;     /*  BKSL  */
   460     keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON;     /*  AC10  */
   461     keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE;  /*  AC11  */
   462     keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA;     /*  AB08  */
   463     keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD;   /*  AB09  */
   464     keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH;     /*  AB10  */
   465     keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH;        /*  103rd  */
   466 
   467 }
   468 
   469 static SDL_keysym *
   470 DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_keysym * keysym)
   471 {
   472     SDL_DFB_DEVICEDATA(_this);
   473 
   474     if (evt->key_code >= 0
   475         && evt->key_code < SDL_arraysize(linux_scancode_table))
   476         keysym->scancode = linux_scancode_table[evt->key_code];
   477     else
   478         keysym->scancode = SDL_SCANCODE_UNKNOWN;
   479 
   480     if (keysym->scancode == SDL_SCANCODE_UNKNOWN
   481         || devdata->keyboard[0].is_generic) {
   482         if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
   483             keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
   484         else
   485             keysym->scancode = SDL_SCANCODE_UNKNOWN;
   486     }
   487 
   488     keysym->unicode =
   489         (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
   490     if (keysym->unicode == 0
   491         && (evt->key_symbol > 0 && evt->key_symbol < 255))
   492         keysym->unicode = evt->key_symbol;
   493 
   494     return keysym;
   495 }
   496 
   497 static SDL_keysym *
   498 DirectFB_TranslateKeyInputEvent(_THIS, int index, DFBInputEvent * evt,
   499                                 SDL_keysym * keysym)
   500 {
   501     SDL_DFB_DEVICEDATA(_this);
   502 
   503     if (evt->key_code >= 0
   504         && evt->key_code < SDL_arraysize(linux_scancode_table))
   505         keysym->scancode = linux_scancode_table[evt->key_code];
   506     else
   507         keysym->scancode = SDL_SCANCODE_UNKNOWN;
   508 
   509     if (keysym->scancode == SDL_SCANCODE_UNKNOWN
   510         || devdata->keyboard[index].is_generic) {
   511         if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
   512             keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
   513         else
   514             keysym->scancode = SDL_SCANCODE_UNKNOWN;
   515     }
   516 
   517     keysym->unicode =
   518         (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
   519     if (keysym->unicode == 0
   520         && (evt->key_symbol > 0 && evt->key_symbol < 255))
   521         keysym->unicode = evt->key_symbol;
   522 
   523     return keysym;
   524 }
   525 
   526 static int
   527 DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
   528 {
   529     switch (button) {
   530     case DIBI_LEFT:
   531         return 1;
   532     case DIBI_MIDDLE:
   533         return 2;
   534     case DIBI_RIGHT:
   535         return 3;
   536     default:
   537         return 0;
   538     }
   539 }
   540 
   541 static DFBEnumerationResult
   542 input_device_cb(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
   543                 void *callbackdata)
   544 {
   545     DFB_DeviceData *devdata = callbackdata;
   546     SDL_Keyboard keyboard;
   547     SDLKey keymap[SDL_NUM_SCANCODES];
   548 
   549     if ((desc.caps & DIDTF_KEYBOARD) && device_id == DIDID_KEYBOARD) {
   550         SDL_zero(keyboard);
   551         SDL_AddKeyboard(&keyboard, 0);
   552         devdata->keyboard[0].id = device_id;
   553         devdata->keyboard[0].is_generic = 0;
   554         if (!strncmp("X11", desc.name, 3))
   555             devdata->keyboard[0].is_generic = 1;
   556 
   557         SDL_GetDefaultKeymap(keymap);
   558         SDL_SetKeymap(0, 0, keymap, SDL_NUM_SCANCODES);
   559         devdata->num_keyboard++;
   560 
   561         return DFENUM_CANCEL;
   562     }
   563     return DFENUM_OK;
   564 }
   565 
   566 static DFBEnumerationResult
   567 EnumKeyboards(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
   568               void *callbackdata)
   569 {
   570     DFB_DeviceData *devdata = callbackdata;
   571     SDL_Keyboard keyboard;
   572     SDLKey keymap[SDL_NUM_SCANCODES];
   573 
   574     if (sys_ids) {
   575         if (device_id >= 0x10)
   576             return DFENUM_OK;
   577     } else {
   578         if (device_id < 0x10)
   579             return DFENUM_OK;
   580     }
   581     if ((desc.caps & DIDTF_KEYBOARD)) {
   582         SDL_zero(keyboard);
   583         SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
   584         devdata->keyboard[devdata->num_keyboard].id = device_id;
   585         devdata->keyboard[devdata->num_keyboard].is_generic = 0;
   586         if (!strncmp("X11", desc.name, 3))
   587             devdata->keyboard[devdata->num_keyboard].is_generic = 1;
   588 
   589         SDL_GetDefaultKeymap(keymap);
   590         SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES);
   591         devdata->num_keyboard++;
   592     }
   593     return DFENUM_OK;
   594 }
   595 
   596 void
   597 DirectFB_InitKeyboard(_THIS)
   598 {
   599     SDL_DFB_DEVICEDATA(_this);
   600     int ret;
   601 
   602     DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
   603 
   604     devdata->num_keyboard = 0;
   605     if (devdata->use_linux_input) {
   606         sys_ids = 0;
   607         SDL_DFB_CHECK(devdata->
   608                       dfb->EnumInputDevices(devdata->dfb, EnumKeyboards,
   609                                             devdata));
   610         if (devdata->num_keyboard == 0) {
   611             sys_ids = 1;
   612             SDL_DFB_CHECK(devdata->
   613                           dfb->EnumInputDevices(devdata->dfb, EnumKeyboards,
   614                                                 devdata));
   615         }
   616     } else {
   617         SDL_DFB_CHECK(devdata->
   618                       dfb->EnumInputDevices(devdata->dfb, input_device_cb,
   619                                             devdata));
   620     }
   621 }
   622 
   623 void
   624 DirectFB_QuitKeyboard(_THIS)
   625 {
   626     SDL_DFB_DEVICEDATA(_this);
   627     int ret;
   628 
   629     SDL_KeyboardQuit();
   630 
   631 }
   632 
   633 #if 0
   634 /* FIXME: Remove once determined this is not needed in fullscreen mode */
   635 void
   636 DirectFB_PumpEvents(_THIS)
   637 {
   638     SDL_DFB_DEVICEDATA(_this);
   639     DFBInputEvent evt;
   640     static last_x = 0, last_y = 0;
   641 
   642     while (devdata->eventbuffer->GetEvent(devdata->eventbuffer,
   643                                           DFB_EVENT(&evt)) == DFB_OK) {
   644         SDL_keysym keysym;
   645         DFBInputDeviceModifierMask mod;
   646 
   647         if (evt.clazz = DFEC_INPUT) {
   648             if (evt.flags & DIEF_MODIFIERS)
   649                 mod = evt.modifiers;
   650             else
   651                 mod = 0;
   652 
   653             switch (evt.type) {
   654             case DIET_BUTTONPRESS:
   655                 posted += SDL_PrivateMouseButton(SDL_PRESSED,
   656                                                  DirectFB_TranslateButton
   657                                                  (evt.button), 0, 0);
   658                 break;
   659             case DIET_BUTTONRELEASE:
   660                 posted += SDL_PrivateMouseButton(SDL_RELEASED,
   661                                                  DirectFB_TranslateButton
   662                                                  (evt.button), 0, 0);
   663                 break;
   664             case DIET_KEYPRESS:
   665                 posted += SDL_PrivateKeyboard(SDL_PRESSED,
   666                                               DirectFB_TranslateKey
   667                                               (evt.key_id, evt.key_symbol,
   668                                                mod, &keysym));
   669                 break;
   670             case DIET_KEYRELEASE:
   671                 posted += SDL_PrivateKeyboard(SDL_RELEASED,
   672                                               DirectFB_TranslateKey
   673                                               (evt.key_id, evt.key_symbol,
   674                                                mod, &keysym));
   675                 break;
   676             case DIET_AXISMOTION:
   677                 if (evt.flags & DIEF_AXISREL) {
   678                     if (evt.axis == DIAI_X)
   679                         posted +=
   680                             SDL_PrivateMouseMotion(0, 1, evt.axisrel, 0);
   681                     else if (evt.axis == DIAI_Y)
   682                         posted +=
   683                             SDL_PrivateMouseMotion(0, 1, 0, evt.axisrel);
   684                 } else if (evt.flags & DIEF_AXISABS) {
   685                     if (evt.axis == DIAI_X)
   686                         last_x = evt.axisabs;
   687                     else if (evt.axis == DIAI_Y)
   688                         last_y = evt.axisabs;
   689                     posted += SDL_PrivateMouseMotion(0, 0, last_x, last_y);
   690                 }
   691                 break;
   692             default:
   693                 ;
   694             }
   695         }
   696     }
   697 }
   698 #endif