Date: Sun, 07 Dec 2008 13:35:23 +0100
authorSam Lantinga
Mon, 08 Dec 2008 00:52:12 +0000
changeset 28606ce28e5287e9
parent 2859 99210400e8b9
child 2861 25745ac3d785
Date: Sun, 07 Dec 2008 13:35:23 +0100
From: Couriersud
Subject: SDL: Mouse last_x, last_y into SDL_Mouse

the attached diff moves the static vars last_x and last_y into
SDL_Mouse. These, as far as I understand it, should be tied to the
individual mouse.

The patch also makes the code check for out of window conditions of
mouse->x,y when relative movements are passed to MouseSendMotion.

Also attached is the latest DirectFB code (dfb20081208) supporting
multiple mice and keyboards. This works quite well with sdlmame now. It
however needs more testing with different directfb configurations.
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/video/SDL_video.c
src/video/directfb/SDL_DirectFB_events.c
src/video/directfb/SDL_DirectFB_mouse.c
src/video/directfb/SDL_DirectFB_video.c
src/video/directfb/SDL_DirectFB_video.h
     1.1 --- a/src/events/SDL_mouse.c	Mon Dec 08 00:27:32 2008 +0000
     1.2 +++ b/src/events/SDL_mouse.c	Mon Dec 08 00:52:12 2008 +0000
     1.3 @@ -33,7 +33,6 @@
     1.4  static SDL_Mouse **SDL_mice = NULL;
     1.5  static int *SDL_IdIndex = NULL;
     1.6  static int SDL_highestId = -1;
     1.7 -static int last_x, last_y;      /* the last reported x and y coordinates by the system cursor */
     1.8  
     1.9  
    1.10  /* Public functions */
    1.11 @@ -61,12 +60,15 @@
    1.12      }
    1.13      if (id > SDL_highestId) {
    1.14          int *indexes;
    1.15 +        int i;
    1.16          indexes = (int *) SDL_realloc(SDL_IdIndex, (id + 1) * sizeof(int));
    1.17          if (!indexes) {
    1.18              SDL_OutOfMemory();
    1.19              return -1;
    1.20          }
    1.21          SDL_IdIndex = indexes;
    1.22 +        for (i = SDL_highestId + 1; i <= id; i++)
    1.23 +            SDL_IdIndex[i] = -1;
    1.24          SDL_IdIndex[id] = index;
    1.25          SDL_highestId = id;
    1.26      } else {
    1.27 @@ -378,8 +380,8 @@
    1.28          return 0;
    1.29      }
    1.30  
    1.31 -    last_x = x;
    1.32 -    last_y = y;
    1.33 +    mouse->last_x = x;
    1.34 +    mouse->last_y = y;
    1.35      if (SDL_ProcessEvents[type] == SDL_ENABLE) {
    1.36          SDL_Event event;
    1.37          event.proximity.which = (Uint8) index;
    1.38 @@ -405,6 +407,7 @@
    1.39      int posted;
    1.40      int xrel;
    1.41      int yrel;
    1.42 +    int x_max = 0, y_max = 0;
    1.43  
    1.44      if (!mouse || mouse->flush_motion) {
    1.45          return 0;
    1.46 @@ -412,8 +415,8 @@
    1.47  
    1.48      /* if the mouse is out of proximity we don't to want to have any motion from it */
    1.49      if (mouse->proximity == SDL_FALSE) {
    1.50 -        last_x = x;
    1.51 -        last_y = y;
    1.52 +        mouse->last_x = x;
    1.53 +        mouse->last_y = y;
    1.54          return 0;
    1.55      }
    1.56  
    1.57 @@ -421,11 +424,11 @@
    1.58      if (relative) {
    1.59          xrel = x;
    1.60          yrel = y;
    1.61 -        x = (last_x + x);
    1.62 -        y = (last_y + y);
    1.63 +        x = (mouse->last_x + x);
    1.64 +        y = (mouse->last_y + y);
    1.65      } else {
    1.66 -        xrel = x - last_x;
    1.67 -        yrel = y - last_y;
    1.68 +        xrel = x - mouse->last_x;
    1.69 +        yrel = y - mouse->last_y;
    1.70      }
    1.71  
    1.72      /* Drop events that don't change state */
    1.73 @@ -441,27 +444,26 @@
    1.74          mouse->x = x;
    1.75          mouse->y = y;
    1.76      } else {
    1.77 -        /* while using the relative mode and many windows, we have to be
    1.78 -           sure that the pointers find themselves inside the windows */
    1.79 -        int x_max, y_max;
    1.80 +        mouse->x += xrel;
    1.81 +        mouse->y += yrel;
    1.82 +    }
    1.83  
    1.84 -        SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
    1.85 +    SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
    1.86  
    1.87 -        if (mouse->x + xrel > x_max) {
    1.88 -            mouse->x = x_max;
    1.89 -        } else if (mouse->x + xrel < 0) {
    1.90 -            mouse->x = 0;
    1.91 -        } else {
    1.92 -            mouse->x += xrel;
    1.93 -        }
    1.94 -        if (mouse->y + yrel > y_max) {
    1.95 -            mouse->y = y_max;
    1.96 -        } else if (mouse->y + yrel < 0) {
    1.97 -            mouse->y = 0;
    1.98 -        } else {
    1.99 -            mouse->y += yrel;
   1.100 -        }
   1.101 +    /* make sure that the pointers find themselves inside the windows */
   1.102 +    /* only check if mouse->xmax is set ! */
   1.103 +    if (x_max && mouse->x > x_max) {
   1.104 +        mouse->x = x_max;
   1.105 +    } else if (mouse->x < 0) {
   1.106 +        mouse->x = 0;
   1.107      }
   1.108 +
   1.109 +    if (y_max && mouse->y > y_max) {
   1.110 +        mouse->y = y_max;
   1.111 +    } else if (mouse->y < 0) {
   1.112 +        mouse->y = 0;
   1.113 +    }
   1.114 +
   1.115      mouse->xdelta += xrel;
   1.116      mouse->ydelta += yrel;
   1.117      mouse->pressure = pressure;
   1.118 @@ -491,8 +493,8 @@
   1.119          event.motion.cursor = mouse->current_end;
   1.120          posted = (SDL_PushEvent(&event) > 0);
   1.121      }
   1.122 -    last_x = x;
   1.123 -    last_y = y;
   1.124 +    mouse->last_x = x;
   1.125 +    mouse->last_y = y;
   1.126      return posted;
   1.127  }
   1.128  
     2.1 --- a/src/events/SDL_mouse_c.h	Mon Dec 08 00:27:32 2008 +0000
     2.2 +++ b/src/events/SDL_mouse_c.h	Mon Dec 08 00:52:12 2008 +0000
     2.3 @@ -71,6 +71,7 @@
     2.4      int z;                      /* for future use */
     2.5      int xdelta;
     2.6      int ydelta;
     2.7 +    int last_x, last_y;         /* the last reported x and y coordinates */
     2.8      char *name;
     2.9      Uint8 buttonstate;
    2.10      SDL_bool relative_mode;
     3.1 --- a/src/video/SDL_video.c	Mon Dec 08 00:27:32 2008 +0000
     3.2 +++ b/src/video/SDL_video.c	Mon Dec 08 00:52:12 2008 +0000
     3.3 @@ -1054,7 +1054,7 @@
     3.4  {
     3.5      SDL_Window *window = SDL_GetWindowFromID(windowID);
     3.6  
     3.7 -    if (!window) {
     3.8 +    if (window) {
     3.9          if (w) {
    3.10              *w = window->w;
    3.11          }
     4.1 --- a/src/video/directfb/SDL_DirectFB_events.c	Mon Dec 08 00:27:32 2008 +0000
     4.2 +++ b/src/video/directfb/SDL_DirectFB_events.c	Mon Dec 08 00:52:12 2008 +0000
     4.3 @@ -33,12 +33,16 @@
     4.4  #include "SDL_DirectFB_events.h"
     4.5  
     4.6  /* The translation tables from a DirectFB keycode to a SDL keysym */
     4.7 -static SDLKey keymap[256];
     4.8 +static SDLKey oskeymap[256];
     4.9 +static int sys_ids;
    4.10  
    4.11  static SDL_keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
    4.12                                           SDL_keysym * keysym);
    4.13 +static SDL_keysym *DirectFB_TranslateKeyInputEvent(_THIS, int index,
    4.14 +                                                   DFBInputEvent * evt,
    4.15 +                                                   SDL_keysym * keysym);
    4.16  
    4.17 -static void DirectFB_InitOSKeymap(_THIS);
    4.18 +static void DirectFB_InitOSKeymap(_THIS, SDLKey * keypmap, int numkeys);
    4.19  static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
    4.20  
    4.21  static void
    4.22 @@ -65,19 +69,68 @@
    4.23  
    4.24  }
    4.25  
    4.26 +static void
    4.27 +FocusAllMice(_THIS, SDL_WindowID id)
    4.28 +{
    4.29 +    SDL_DFB_DEVICEDATA(_this);
    4.30 +    int index;
    4.31 +
    4.32 +    for (index = 0; index < devdata->num_mice; index++)
    4.33 +        SDL_SetMouseFocus(devdata->mouse_id[index], id);
    4.34 +}
    4.35 +
    4.36 +
    4.37 +static void
    4.38 +FocusAllKeyboards(_THIS, SDL_WindowID id)
    4.39 +{
    4.40 +    SDL_DFB_DEVICEDATA(_this);
    4.41 +    int index;
    4.42 +
    4.43 +    for (index = 0; index < devdata->num_keyboard; index++)
    4.44 +        SDL_SetKeyboardFocus(index, id);
    4.45 +}
    4.46 +
    4.47 +static void
    4.48 +MotionAllMice(_THIS, int x, int y)
    4.49 +{
    4.50 +    SDL_DFB_DEVICEDATA(_this);
    4.51 +    int index;
    4.52 +
    4.53 +    for (index = 0; index < devdata->num_mice; index++) {
    4.54 +        SDL_Mouse *mouse = SDL_GetMouse(index);
    4.55 +        mouse->x = mouse->last_x = x;
    4.56 +        mouse->y = mouse->last_y = y;
    4.57 +        //SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0);
    4.58 +    }
    4.59 +}
    4.60 +
    4.61 +static int
    4.62 +KbdIndex(_THIS, int id)
    4.63 +{
    4.64 +    SDL_DFB_DEVICEDATA(_this);
    4.65 +    int index;
    4.66 +
    4.67 +    for (index = 0; index < devdata->num_keyboard; index++) {
    4.68 +        if (devdata->keyboard[index].id == id)
    4.69 +            return index;
    4.70 +    }
    4.71 +    return -1;
    4.72 +}
    4.73 +
    4.74  void
    4.75  DirectFB_PumpEventsWindow(_THIS)
    4.76  {
    4.77      SDL_DFB_DEVICEDATA(_this);
    4.78      DFB_WindowData *p;
    4.79 -    DFBWindowEvent evt;
    4.80      DFBInputEvent ievt;
    4.81 -    SDL_WindowID grabbed_window;
    4.82 +    Sint32 /* SDL_WindowID */ grabbed_window;
    4.83      char text[5];
    4.84 +    int kbd_idx;
    4.85  
    4.86      grabbed_window = -1;
    4.87  
    4.88      for (p = devdata->firstwin; p != NULL; p = p->next) {
    4.89 +        DFBWindowEvent evt;
    4.90          SDL_Window *w = SDL_GetWindowFromID(p->id);
    4.91  
    4.92          if (w->flags & SDL_WINDOW_INPUT_GRABBED) {
    4.93 @@ -91,34 +144,62 @@
    4.94              if (evt.clazz == DFEC_WINDOW) {
    4.95                  switch (evt.type) {
    4.96                  case DWET_BUTTONDOWN:
    4.97 -                    SDL_SendMouseButton(devdata->mouse, SDL_PRESSED,
    4.98 -                                        DirectFB_TranslateButton(evt.button));
    4.99 +                    if (!LINUX_INPUT_SUPPORT) {
   4.100 +                        SDL_SendMouseMotion(devdata->mouse_id[0], 0, evt.cx,
   4.101 +                                            evt.cy, 0);
   4.102 +                        SDL_SendMouseButton(devdata->mouse_id[0], SDL_PRESSED,
   4.103 +                                            DirectFB_TranslateButton(evt.
   4.104 +                                                                     button));
   4.105 +                    } else {
   4.106 +                        MotionAllMice(_this, evt.x, evt.y);
   4.107 +                    }
   4.108                      break;
   4.109                  case DWET_BUTTONUP:
   4.110 -                    SDL_SendMouseButton(devdata->mouse, SDL_RELEASED,
   4.111 -                                        DirectFB_TranslateButton(evt.button));
   4.112 +                    if (!LINUX_INPUT_SUPPORT) {
   4.113 +                        SDL_SendMouseMotion(devdata->mouse_id[0], 0, evt.cx,
   4.114 +                                            evt.cy, 0);
   4.115 +                        SDL_SendMouseButton(devdata->mouse_id[0],
   4.116 +                                            SDL_RELEASED,
   4.117 +                                            DirectFB_TranslateButton(evt.
   4.118 +                                                                     button));
   4.119 +                    } else {
   4.120 +                        MotionAllMice(_this, evt.x, evt.y);
   4.121 +                    }
   4.122                      break;
   4.123                  case DWET_MOTION:
   4.124 -                    if (!(w->flags & SDL_WINDOW_INPUT_GRABBED))
   4.125 -                        SDL_SendMouseMotion(devdata->mouse, 0, evt.cx, evt.cy,
   4.126 -                                            0);
   4.127 +                    if (!LINUX_INPUT_SUPPORT) {
   4.128 +                        if (!(w->flags & SDL_WINDOW_INPUT_GRABBED))
   4.129 +                            SDL_SendMouseMotion(devdata->mouse_id[0], 0,
   4.130 +                                                evt.cx, evt.cy, 0);
   4.131 +                    } else {
   4.132 +                        /* relative movements are not exact! 
   4.133 +                         * This code should limit the number of events sent.
   4.134 +                         * However it kills MAME axis recognition ... */
   4.135 +                        static int cnt = 0;
   4.136 +                        if (1 && ++cnt > 20) {
   4.137 +                            MotionAllMice(_this, evt.x, evt.y);
   4.138 +                            cnt = 0;
   4.139 +                        }
   4.140 +                    }
   4.141                      break;
   4.142                  case DWET_KEYDOWN:
   4.143 -                    DirectFB_TranslateKey(_this, &evt, &keysym);
   4.144 -                    SDL_SendKeyboardKey(devdata->keyboard, SDL_PRESSED,
   4.145 -                                        keysym.scancode);
   4.146 -                    if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   4.147 -                        SDL_memcpy(text, &keysym.unicode, 4);
   4.148 -                        text[4] = 0;
   4.149 -                        if (*text) {
   4.150 -                            SDL_SendKeyboardText(devdata->keyboard, text);
   4.151 +                    if (!LINUX_INPUT_SUPPORT) {
   4.152 +                        DirectFB_TranslateKey(_this, &evt, &keysym);
   4.153 +                        SDL_SendKeyboardKey(0, SDL_PRESSED, keysym.scancode);
   4.154 +                        if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   4.155 +                            SDL_memcpy(text, &keysym.unicode, 4);
   4.156 +                            text[4] = 0;
   4.157 +                            if (*text) {
   4.158 +                                SDL_SendKeyboardText(0, text);
   4.159 +                            }
   4.160                          }
   4.161                      }
   4.162                      break;
   4.163                  case DWET_KEYUP:
   4.164 -                    DirectFB_TranslateKey(_this, &evt, &keysym);
   4.165 -                    SDL_SendKeyboardKey(devdata->keyboard, SDL_RELEASED,
   4.166 -                                        keysym.scancode);
   4.167 +                    if (!LINUX_INPUT_SUPPORT) {
   4.168 +                        DirectFB_TranslateKey(_this, &evt, &keysym);
   4.169 +                        SDL_SendKeyboardKey(0, SDL_RELEASED, keysym.scancode);
   4.170 +                    }
   4.171                      break;
   4.172                  case DWET_POSITION_SIZE:
   4.173                      if (evt.x != w->x || evt.y != w->y)
   4.174 @@ -143,23 +224,24 @@
   4.175                      break;
   4.176                  case DWET_GOTFOCUS:
   4.177                      DirectFB_SetContext(_this, p->id);
   4.178 -                    SDL_SetKeyboardFocus(devdata->keyboard, p->id);
   4.179 +                    FocusAllKeyboards(_this, p->id);
   4.180                      SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_FOCUS_GAINED,
   4.181                                          0, 0);
   4.182                      break;
   4.183                  case DWET_LOSTFOCUS:
   4.184                      SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_FOCUS_LOST, 0,
   4.185                                          0);
   4.186 -                    SDL_SetKeyboardFocus(devdata->keyboard, 0);
   4.187 +                    FocusAllKeyboards(_this, 0);
   4.188                      break;
   4.189                  case DWET_ENTER:
   4.190                      /* SDL_DirectFB_ReshowCursor(_this, 0); */
   4.191 -                    SDL_SetMouseFocus(devdata->mouse, p->id);
   4.192 +                    FocusAllMice(_this, p->id);
   4.193 +                    MotionAllMice(_this, evt.x, evt.y);
   4.194                      SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_ENTER, 0, 0);
   4.195                      break;
   4.196                  case DWET_LEAVE:
   4.197                      SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_LEAVE, 0, 0);
   4.198 -                    SDL_SetMouseFocus(devdata->mouse, 0);
   4.199 +                    FocusAllMice(_this, 0);
   4.200                      /* SDL_DirectFB_ReshowCursor(_this, 1); */
   4.201                      break;
   4.202                  default:
   4.203 @@ -174,32 +256,94 @@
   4.204      /* Now get relative events in case we need them */
   4.205      while (devdata->events->GetEvent(devdata->events,
   4.206                                       DFB_EVENT(&ievt)) == DFB_OK) {
   4.207 -        if (grabbed_window >= 0) {
   4.208 +        SDL_keysym keysym;
   4.209 +
   4.210 +        switch (ievt.type) {
   4.211 +        case DIET_AXISMOTION:
   4.212 +            if (!LINUX_INPUT_SUPPORT) {
   4.213 +                if ((grabbed_window >= 0) && (ievt.flags & DIEF_AXISREL)) {
   4.214 +                    printf("rel devid %d\n", ievt.device_id);
   4.215 +                    if (ievt.axis == DIAI_X)
   4.216 +                        SDL_SendMouseMotion(ievt.device_id, 1, ievt.axisrel,
   4.217 +                                            0, 0);
   4.218 +                    else if (ievt.axis == DIAI_Y)
   4.219 +                        SDL_SendMouseMotion(ievt.device_id, 1, 0,
   4.220 +                                            ievt.axisrel, 0);
   4.221 +                }
   4.222 +            }
   4.223 +            break;
   4.224 +        }
   4.225 +        if (LINUX_INPUT_SUPPORT) {
   4.226 +            IDirectFBInputDevice *idev;
   4.227 +            static int last_x, last_y;
   4.228 +
   4.229              switch (ievt.type) {
   4.230              case DIET_AXISMOTION:
   4.231 -                if (ievt.flags & DIEF_AXISREL) {
   4.232 +                if (ievt.flags & DIEF_AXISABS) {
   4.233                      if (ievt.axis == DIAI_X)
   4.234 -                        SDL_SendMouseMotion(devdata->mouse, 1, ievt.axisrel,
   4.235 +                        last_x = ievt.axisabs;
   4.236 +                    else if (ievt.axis == DIAI_Y)
   4.237 +                        last_y = ievt.axisabs;
   4.238 +                    if (!(ievt.flags & DIEF_FOLLOW))
   4.239 +                        SDL_SendMouseMotion(ievt.device_id, 0, last_x, last_y,
   4.240 +                                            0);
   4.241 +                } else if (ievt.flags & DIEF_AXISREL) {
   4.242 +                    //printf("rel %d %d\n", ievt.device_id, ievt.axisrel);
   4.243 +                    if (ievt.axis == DIAI_X)
   4.244 +                        SDL_SendMouseMotion(ievt.device_id, 1, ievt.axisrel,
   4.245                                              0, 0);
   4.246                      else if (ievt.axis == DIAI_Y)
   4.247 -                        SDL_SendMouseMotion(devdata->mouse, 1, 0,
   4.248 +                        SDL_SendMouseMotion(ievt.device_id, 1, 0,
   4.249                                              ievt.axisrel, 0);
   4.250                  }
   4.251                  break;
   4.252 -            default:
   4.253 -                ;
   4.254 +            case DIET_KEYPRESS:
   4.255 +                kbd_idx = KbdIndex(_this, ievt.device_id);
   4.256 +                DirectFB_TranslateKeyInputEvent(_this, kbd_idx, &ievt,
   4.257 +                                                &keysym);
   4.258 +                SDL_SendKeyboardKey(kbd_idx, SDL_PRESSED, keysym.scancode);
   4.259 +                if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
   4.260 +                    SDL_memcpy(text, &keysym.unicode, 4);
   4.261 +                    text[4] = 0;
   4.262 +                    if (*text) {
   4.263 +                        SDL_SendKeyboardText(kbd_idx, text);
   4.264 +                    }
   4.265 +                }
   4.266 +                break;
   4.267 +            case DIET_KEYRELEASE:
   4.268 +                kbd_idx = KbdIndex(_this, ievt.device_id);
   4.269 +                DirectFB_TranslateKeyInputEvent(_this, kbd_idx, &ievt,
   4.270 +                                                &keysym);
   4.271 +                SDL_SendKeyboardKey(kbd_idx, SDL_RELEASED, keysym.scancode);
   4.272 +                break;
   4.273 +            case DIET_BUTTONPRESS:
   4.274 +                if (ievt.buttons & DIBM_LEFT)
   4.275 +                    SDL_SendMouseButton(ievt.device_id, SDL_PRESSED, 1);
   4.276 +                if (ievt.buttons & DIBM_MIDDLE)
   4.277 +                    SDL_SendMouseButton(ievt.device_id, SDL_PRESSED, 2);
   4.278 +                if (ievt.buttons & DIBM_RIGHT)
   4.279 +                    SDL_SendMouseButton(ievt.device_id, SDL_PRESSED, 3);
   4.280 +                break;
   4.281 +            case DIET_BUTTONRELEASE:
   4.282 +                if (!(ievt.buttons & DIBM_LEFT))
   4.283 +                    SDL_SendMouseButton(ievt.device_id, SDL_RELEASED, 1);
   4.284 +                if (!(ievt.buttons & DIBM_MIDDLE))
   4.285 +                    SDL_SendMouseButton(ievt.device_id, SDL_RELEASED, 2);
   4.286 +                if (!(ievt.buttons & DIBM_RIGHT))
   4.287 +                    SDL_SendMouseButton(ievt.device_id, SDL_RELEASED, 3);
   4.288 +                break;
   4.289              }
   4.290          }
   4.291      }
   4.292  }
   4.293  
   4.294  void
   4.295 -DirectFB_InitOSKeymap(_THIS)
   4.296 +DirectFB_InitOSKeymap(_THIS, SDLKey * keymap, int numkeys)
   4.297  {
   4.298      int i;
   4.299  
   4.300      /* Initialize the DirectFB key translation table */
   4.301 -    for (i = 0; i < SDL_arraysize(keymap); ++i)
   4.302 +    for (i = 0; i < numkeys; ++i)
   4.303          keymap[i] = SDL_SCANCODE_UNKNOWN;
   4.304  
   4.305      keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
   4.306 @@ -332,9 +476,10 @@
   4.307      else
   4.308          keysym->scancode = SDL_SCANCODE_UNKNOWN;
   4.309  
   4.310 -    if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->kbdgeneric) {
   4.311 -        if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(keymap))
   4.312 -            keysym->scancode = keymap[evt->key_id - DIKI_UNKNOWN];
   4.313 +    if (keysym->scancode == SDL_SCANCODE_UNKNOWN
   4.314 +        || devdata->keyboard[0].is_generic) {
   4.315 +        if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
   4.316 +            keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
   4.317          else
   4.318              keysym->scancode = SDL_SCANCODE_UNKNOWN;
   4.319      }
   4.320 @@ -348,6 +493,34 @@
   4.321      return keysym;
   4.322  }
   4.323  
   4.324 +static SDL_keysym *
   4.325 +DirectFB_TranslateKeyInputEvent(_THIS, int index, DFBInputEvent * evt,
   4.326 +                                SDL_keysym * keysym)
   4.327 +{
   4.328 +    SDL_DFB_DEVICEDATA(_this);
   4.329 +
   4.330 +    if (evt->key_code >= 0
   4.331 +        && evt->key_code < SDL_arraysize(linux_scancode_table))
   4.332 +        keysym->scancode = linux_scancode_table[evt->key_code];
   4.333 +    else
   4.334 +        keysym->scancode = SDL_SCANCODE_UNKNOWN;
   4.335 +
   4.336 +    if (keysym->scancode == SDL_SCANCODE_UNKNOWN
   4.337 +        || devdata->keyboard[index].is_generic) {
   4.338 +        if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
   4.339 +            keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
   4.340 +        else
   4.341 +            keysym->scancode = SDL_SCANCODE_UNKNOWN;
   4.342 +    }
   4.343 +
   4.344 +    keysym->unicode =
   4.345 +        (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
   4.346 +    if (keysym->unicode == 0
   4.347 +        && (evt->key_symbol > 0 && evt->key_symbol < 255))
   4.348 +        keysym->unicode = evt->key_symbol;
   4.349 +
   4.350 +    return keysym;
   4.351 +}
   4.352  static int
   4.353  DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
   4.354  {
   4.355 @@ -373,14 +546,49 @@
   4.356  
   4.357      if ((desc.caps & DIDTF_KEYBOARD) && device_id == DIDID_KEYBOARD) {
   4.358          SDL_zero(keyboard);
   4.359 -        devdata->keyboard = SDL_AddKeyboard(&keyboard, -1);
   4.360 +        SDL_AddKeyboard(&keyboard, 0);
   4.361 +        devdata->keyboard[0].id = device_id;
   4.362 +        devdata->keyboard[0].is_generic = 0;
   4.363          if (!strncmp("X11", desc.name, 3))
   4.364 -            devdata->kbdgeneric = 1;
   4.365 +            devdata->keyboard[0].is_generic = 1;
   4.366  
   4.367          SDL_GetDefaultKeymap(keymap);
   4.368 -        SDL_SetKeymap(devdata->keyboard, 0, keymap, SDL_NUM_SCANCODES);
   4.369 +        SDL_SetKeymap(0, 0, keymap, SDL_NUM_SCANCODES);
   4.370 +        devdata->num_keyboard++;
   4.371 +
   4.372 +        return DFENUM_CANCEL;
   4.373      }
   4.374 -    return DFB_OK;
   4.375 +    return DFENUM_OK;
   4.376 +}
   4.377 +
   4.378 +static DFBEnumerationResult
   4.379 +EnumKeyboards(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
   4.380 +              void *callbackdata)
   4.381 +{
   4.382 +    DFB_DeviceData *devdata = callbackdata;
   4.383 +    SDL_Keyboard keyboard;
   4.384 +    SDLKey keymap[SDL_NUM_SCANCODES];
   4.385 +
   4.386 +    if (sys_ids) {
   4.387 +        if (device_id >= 0x10)
   4.388 +            return DFENUM_OK;
   4.389 +    } else {
   4.390 +        if (device_id < 0x10)
   4.391 +            return DFENUM_OK;
   4.392 +    }
   4.393 +    if ((desc.caps & DIDTF_KEYBOARD)) {
   4.394 +        SDL_zero(keyboard);
   4.395 +        SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
   4.396 +        devdata->keyboard[devdata->num_keyboard].id = device_id;
   4.397 +        devdata->keyboard[devdata->num_keyboard].is_generic = 0;
   4.398 +        if (!strncmp("X11", desc.name, 3))
   4.399 +            devdata->keyboard[devdata->num_keyboard].is_generic = 1;
   4.400 +
   4.401 +        SDL_GetDefaultKeymap(keymap);
   4.402 +        SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES);
   4.403 +        devdata->num_keyboard++;
   4.404 +    }
   4.405 +    return DFENUM_OK;
   4.406  }
   4.407  
   4.408  void
   4.409 @@ -389,12 +597,24 @@
   4.410      SDL_DFB_DEVICEDATA(_this);
   4.411      int ret;
   4.412  
   4.413 -    DirectFB_InitOSKeymap(_this);
   4.414 +    DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
   4.415  
   4.416 -    devdata->kbdgeneric = 0;
   4.417 -
   4.418 -    SDL_DFB_CHECK(devdata->dfb->
   4.419 -                  EnumInputDevices(devdata->dfb, input_device_cb, devdata));
   4.420 +    devdata->num_keyboard = 0;
   4.421 +    if (LINUX_INPUT_SUPPORT) {
   4.422 +        sys_ids = 0;
   4.423 +        SDL_DFB_CHECK(devdata->dfb->
   4.424 +                      EnumInputDevices(devdata->dfb, EnumKeyboards, devdata));
   4.425 +        if (devdata->num_keyboard == 0) {
   4.426 +            sys_ids = 1;
   4.427 +            SDL_DFB_CHECK(devdata->dfb->
   4.428 +                          EnumInputDevices(devdata->dfb, EnumKeyboards,
   4.429 +                                           devdata));
   4.430 +        }
   4.431 +    } else {
   4.432 +        SDL_DFB_CHECK(devdata->dfb->
   4.433 +                      EnumInputDevices(devdata->dfb, input_device_cb,
   4.434 +                                       devdata));
   4.435 +    }
   4.436  }
   4.437  
   4.438  void
   4.439 @@ -403,7 +623,7 @@
   4.440      SDL_DFB_DEVICEDATA(_this);
   4.441      int ret;
   4.442  
   4.443 -    SDL_DelKeyboard(devdata->keyboard);
   4.444 +    SDL_KeyboardQuit();
   4.445  
   4.446  }
   4.447  
     5.1 --- a/src/video/directfb/SDL_DirectFB_mouse.c	Mon Dec 08 00:27:32 2008 +0000
     5.2 +++ b/src/video/directfb/SDL_DirectFB_mouse.c	Mon Dec 08 00:52:12 2008 +0000
     5.3 @@ -35,22 +35,67 @@
     5.4                                 int x, int y);
     5.5  static void DirectFB_FreeMouse(SDL_Mouse * mouse);
     5.6  
     5.7 +static int id_mask;
     5.8 +
     5.9 +static DFBEnumerationResult
    5.10 +EnumMice(DFBInputDeviceID device_id,
    5.11 +         DFBInputDeviceDescription desc, void *callbackdata)
    5.12 +{
    5.13 +    DFB_DeviceData *devdata = callbackdata;
    5.14 +
    5.15 +    if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) {
    5.16 +        SDL_Mouse mouse;
    5.17 +
    5.18 +        SDL_zero(mouse);
    5.19 +        mouse.CreateCursor = DirectFB_CreateCursor;
    5.20 +        mouse.ShowCursor = DirectFB_ShowCursor;
    5.21 +        mouse.MoveCursor = DirectFB_MoveCursor;
    5.22 +        mouse.FreeCursor = DirectFB_FreeCursor;
    5.23 +        mouse.WarpMouse = DirectFB_WarpMouse;
    5.24 +        mouse.FreeMouse = DirectFB_FreeMouse;
    5.25 +        mouse.cursor_shown = 1;
    5.26 +
    5.27 +        SDL_SetMouseIndexId(device_id, devdata->num_mice);
    5.28 +        SDL_AddMouse(&mouse, devdata->num_mice, desc.name, 0, 0, 1);
    5.29 +        devdata->mouse_id[devdata->num_mice] = device_id;
    5.30 +        devdata->num_mice++;
    5.31 +    }
    5.32 +    return DFENUM_OK;
    5.33 +}
    5.34 +
    5.35  void
    5.36  DirectFB_InitMouse(_THIS)
    5.37  {
    5.38      SDL_DFB_DEVICEDATA(_this);
    5.39 -    SDL_Mouse mouse;
    5.40 +
    5.41 +    devdata->num_mice = 0;
    5.42 +    if (LINUX_INPUT_SUPPORT) {
    5.43 +        /* try non-core devices first */
    5.44 +        id_mask = 0xF0;
    5.45 +        devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
    5.46 +        if (devdata->num_mice == 0) {
    5.47 +            /* try core devices */
    5.48 +            id_mask = 0x0F;
    5.49 +            devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
    5.50 +        }
    5.51 +    }
    5.52 +    if (devdata->num_mice == 0) {
    5.53 +        SDL_Mouse mouse;
    5.54  
    5.55 -    SDL_zero(mouse);
    5.56 -    mouse.CreateCursor = DirectFB_CreateCursor;
    5.57 -    mouse.ShowCursor = DirectFB_ShowCursor;
    5.58 -    mouse.MoveCursor = DirectFB_MoveCursor;
    5.59 -    mouse.FreeCursor = DirectFB_FreeCursor;
    5.60 -    mouse.WarpMouse = DirectFB_WarpMouse;
    5.61 -    mouse.FreeMouse = DirectFB_FreeMouse;
    5.62 -    mouse.cursor_shown = 1;
    5.63 -    SDL_SetMouseIndexId(0, 0);  /* ID == Index ! */
    5.64 -    devdata->mouse = SDL_AddMouse(&mouse, 0, "Mouse", 0, 0, 1);
    5.65 +        SDL_zero(mouse);
    5.66 +        mouse.CreateCursor = DirectFB_CreateCursor;
    5.67 +        mouse.ShowCursor = DirectFB_ShowCursor;
    5.68 +        mouse.MoveCursor = DirectFB_MoveCursor;
    5.69 +        mouse.FreeCursor = DirectFB_FreeCursor;
    5.70 +        mouse.WarpMouse = DirectFB_WarpMouse;
    5.71 +        mouse.FreeMouse = DirectFB_FreeMouse;
    5.72 +        mouse.cursor_shown = 1;
    5.73 +
    5.74 +        SDL_SetMouseIndexId(0, 0);      /* ID == Index ! */
    5.75 +        devdata->mouse_id[0] = 0;
    5.76 +        SDL_AddMouse(&mouse, 0, "Mouse", 0, 0, 1);
    5.77 +        devdata->num_mice = 1;
    5.78 +    }
    5.79  }
    5.80  
    5.81  void
    5.82 @@ -58,7 +103,11 @@
    5.83  {
    5.84      SDL_DFB_DEVICEDATA(_this);
    5.85  
    5.86 -    SDL_DelMouse(devdata->mouse);
    5.87 +    if (LINUX_INPUT_SUPPORT) {
    5.88 +        SDL_MouseQuit();
    5.89 +    } else {
    5.90 +        SDL_DelMouse(0);
    5.91 +    }
    5.92  }
    5.93  
    5.94  /* Create a cursor from a surface */
     6.1 --- a/src/video/directfb/SDL_DirectFB_video.c	Mon Dec 08 00:27:32 2008 +0000
     6.2 +++ b/src/video/directfb/SDL_DirectFB_video.c	Mon Dec 08 00:52:12 2008 +0000
     6.3 @@ -155,9 +155,16 @@
     6.4          devdata->use_yuv_underlays = atoi(stemp);
     6.5  
     6.6      /* Create global Eventbuffer for axis events */
     6.7 -    SDL_DFB_CHECKERR(dfb->
     6.8 -                     CreateInputEventBuffer(dfb, DICAPS_AXES /*DICAPS_ALL */ ,
     6.9 -                                            DFB_TRUE, &devdata->events));
    6.10 +    if (LINUX_INPUT_SUPPORT) {
    6.11 +        SDL_DFB_CHECKERR(dfb->
    6.12 +                         CreateInputEventBuffer(dfb, DICAPS_ALL,
    6.13 +                                                DFB_TRUE, &devdata->events));
    6.14 +    } else {
    6.15 +        SDL_DFB_CHECKERR(dfb->
    6.16 +                         CreateInputEventBuffer(dfb,
    6.17 +                                                DICAPS_AXES /*DICAPS_ALL */ ,
    6.18 +                                                DFB_TRUE, &devdata->events));
    6.19 +    }
    6.20  
    6.21      devdata->initialized = 1;
    6.22      devdata->dfb = dfb;
     7.1 --- a/src/video/directfb/SDL_DirectFB_video.h	Mon Dec 08 00:27:32 2008 +0000
     7.2 +++ b/src/video/directfb/SDL_DirectFB_video.h	Mon Dec 08 00:52:12 2008 +0000
     7.3 @@ -31,6 +31,8 @@
     7.4  
     7.5  #include "SDL_mouse.h"
     7.6  
     7.7 +#define LINUX_INPUT_SUPPORT	1
     7.8 +
     7.9  #define DEBUG 0
    7.10  #define LOG_CHANNEL 	stdout
    7.11  
    7.12 @@ -124,9 +126,14 @@
    7.13      int initialized;
    7.14  
    7.15      IDirectFB *dfb;
    7.16 -    int mouse;
    7.17 -    int keyboard;
    7.18 -    int kbdgeneric;
    7.19 +    int num_mice;
    7.20 +    int mouse_id[0x100];
    7.21 +    int num_keyboard;
    7.22 +    struct
    7.23 +    {
    7.24 +        int is_generic;
    7.25 +        int id;
    7.26 +    } keyboard[10];
    7.27      DFB_WindowData *firstwin;
    7.28  
    7.29      int use_yuv_underlays;