Final merge of Google Summer of Code 2008 work...
authorSam Lantinga <slouken@libsdl.org>
Mon, 25 Aug 2008 06:33:00 +0000
changeset 271044e49d3fa6cf
parent 2709 fd3f0f1147e7
child 2711 62e7af9b2b67
Final merge of Google Summer of Code 2008 work...

Many-mouse and tablet support
by Szymon Wilczek, mentored by Ryan C. Gordon

Everything concerning the project is noted on the wiki:
http://wilku.ravenlord.ws/doku.php?id=start
configure.in
include/SDL_events.h
include/SDL_keysym.h
include/SDL_mouse.h
src/SDL_compat.c
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/video/cocoa/SDL_cocoamouse.m
src/video/cocoa/SDL_cocoawindow.m
src/video/win32/SDL_win32events.c
src/video/win32/SDL_win32mouse.c
src/video/win32/SDL_win32video.c
src/video/win32/SDL_win32window.c
src/video/x11/SDL_x11dyn.h
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11mouse.c
src/video/x11/SDL_x11sym.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11window.c
test/testalpha.c
test/testgl.c
     1.1 --- a/configure.in	Mon Aug 25 05:30:28 2008 +0000
     1.2 +++ b/configure.in	Mon Aug 25 06:33:00 2008 +0000
     1.3 @@ -1033,6 +1033,9 @@
     1.4              SOURCES="$SOURCES $srcdir/src/video/Xext/XmuStdCmap/*.c"
     1.5              EXTRA_CFLAGS="$EXTRA_CFLAGS $X_CFLAGS"
     1.6  
     1.7 +echo "FIXME: Need to get dynamic loading of XInput working"
     1.8 +	    enable_x11_shared=no
     1.9 +
    1.10              if test x$enable_x11_shared = xmaybe; then
    1.11                  enable_x11_shared=$x11_symbols_private
    1.12              fi
    1.13 @@ -1055,7 +1058,7 @@
    1.14                  AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT, "$x11ext_lib")
    1.15              else
    1.16                  enable_x11_shared=no
    1.17 -                EXTRA_LDFLAGS="$EXTRA_LDFLAGS $X_LIBS -lX11 -lXext"
    1.18 +                EXTRA_LDFLAGS="$EXTRA_LDFLAGS $X_LIBS -lX11 -lXext -lXi"
    1.19              fi
    1.20              have_video=yes
    1.21  
     2.1 --- a/include/SDL_events.h	Mon Aug 25 05:30:28 2008 +0000
     2.2 +++ b/include/SDL_events.h	Mon Aug 25 06:33:00 2008 +0000
     2.3 @@ -72,9 +72,11 @@
     2.4      SDL_JOYBUTTONUP,            /**< Joystick button released */
     2.5      SDL_QUIT,                   /**< User-requested quit */
     2.6      SDL_SYSWMEVENT,             /**< System specific event */
     2.7 +    SDL_PROXIMITYIN,            /**< Proximity In event */
     2.8 +    SDL_PROXIMITYOUT,           /**< Proximity Out event */
     2.9      SDL_EVENT_RESERVED1,        /**< Reserved for future use... */
    2.10 -    SDL_EVENT_RESERVED2,        /**< Reserved for future use... */
    2.11 -    SDL_EVENT_RESERVED3,        /**< Reserved for future use... */
    2.12 +    SDL_EVENT_RESERVED2,
    2.13 +    SDL_EVENT_RESERVED3,
    2.14      /* Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */
    2.15      SDL_USEREVENT = 24,
    2.16      /* This last event is only for bounding internal arrays
    2.17 @@ -112,7 +114,9 @@
    2.18          SDL_EVENTMASK(SDL_JOYHATMOTION) |
    2.19          SDL_EVENTMASK(SDL_JOYBUTTONDOWN) | SDL_EVENTMASK(SDL_JOYBUTTONUP),
    2.20      SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT),
    2.21 -    SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT)
    2.22 +    SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT),
    2.23 +    SDL_PROXIMITYINMASK = SDL_EVENTMASK(SDL_PROXIMITYIN),
    2.24 +    SDL_PROXIMITYOUTMASK = SDL_EVENTMASK(SDL_PROXIMITYOUT)
    2.25  } SDL_EventMask;
    2.26  #define SDL_ALLEVENTS		0xFFFFFFFF
    2.27  
    2.28 @@ -170,6 +174,13 @@
    2.29      Uint8 state;            /**< The current button state */
    2.30      int x;                  /**< X coordinate, relative to window */
    2.31      int y;                  /**< Y coordinate, relative to window */
    2.32 +    int z;                  /**< Z coordinate, for future use */
    2.33 +    int pressure;           /**< Pressure reported by tablets */
    2.34 +    int pressure_max;       /**< Maximum value of the pressure reported by the device */
    2.35 +    int pressure_min;       /**< Minimum value of the pressure reported by the device */
    2.36 +    int rotation;           /**< For future use */
    2.37 +    int tilt;               /**< For future use */
    2.38 +    int cursor;             /**< The cursor being used in the event */
    2.39      int xrel;               /**< The relative motion in the X direction */
    2.40      int yrel;               /**< The relative motion in the Y direction */
    2.41      SDL_WindowID windowID;  /**< The window with mouse focus, if any */
    2.42 @@ -316,6 +327,15 @@
    2.43      int h;
    2.44  } SDL_ResizeEvent;
    2.45  
    2.46 +typedef struct SDL_ProximityEvent
    2.47 +{
    2.48 +    Uint8 type;
    2.49 +    Uint8 which;
    2.50 +    int cursor;
    2.51 +    int x;
    2.52 +    int y;
    2.53 +} SDL_ProximityEvent;
    2.54 +
    2.55  /**
    2.56   * \union SDL_Event
    2.57   *
    2.58 @@ -337,6 +357,7 @@
    2.59      SDL_QuitEvent quit;             /**< Quit request event data */
    2.60      SDL_UserEvent user;             /**< Custom event data */
    2.61      SDL_SysWMEvent syswm;           /**< System dependent window event data */
    2.62 +    SDL_ProximityEvent proximity;   /**< Proximity In or Out event */
    2.63  
    2.64      /* Temporarily here for backwards compatibility */
    2.65      SDL_ActiveEvent active;
     3.1 --- a/include/SDL_keysym.h	Mon Aug 25 05:30:28 2008 +0000
     3.2 +++ b/include/SDL_keysym.h	Mon Aug 25 06:33:00 2008 +0000
     3.3 @@ -242,7 +242,7 @@
     3.4      SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN),
     3.5      SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP),
     3.6      SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT),
     3.7 -    SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP),
     3.8 +    SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP)
     3.9  };
    3.10  
    3.11  /**
     4.1 --- a/include/SDL_mouse.h	Mon Aug 25 05:30:28 2008 +0000
     4.2 +++ b/include/SDL_mouse.h	Mon Aug 25 06:33:00 2008 +0000
     4.3 @@ -72,7 +72,7 @@
     4.4   *
     4.5   * \brief Get the window which currently has focus for the currently selected mouse.
     4.6   */
     4.7 -extern DECLSPEC SDL_WindowID SDLCALL SDL_GetMouseFocusWindow(void);
     4.8 +extern DECLSPEC SDL_WindowID SDLCALL SDL_GetMouseFocusWindow(int index);
     4.9  
    4.10  /**
    4.11   * \fn int SDL_SetRelativeMouseMode(SDL_bool enabled)
    4.12 @@ -92,7 +92,8 @@
    4.13   *
    4.14   * \sa SDL_GetRelativeMouseMode()
    4.15   */
    4.16 -extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled);
    4.17 +extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(int index,
    4.18 +                                                     SDL_bool enabled);
    4.19  
    4.20  /**
    4.21   * \fn SDL_bool SDL_GetRelativeMouseMode()
    4.22 @@ -101,7 +102,7 @@
    4.23   *
    4.24   * \sa SDL_SetRelativeMouseMode()
    4.25   */
    4.26 -extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void);
    4.27 +extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(int index);
    4.28  
    4.29  /**
    4.30   * \fn Uint8 SDL_GetMouseState(int *x, int *y)
    4.31 @@ -113,7 +114,7 @@
    4.32   * mouse cursor position relative to the focus window for the currently
    4.33   * selected mouse.  You can pass NULL for either x or y.
    4.34   */
    4.35 -extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int *x, int *y);
    4.36 +extern DECLSPEC Uint8 SDLCALL SDL_GetMouseState(int index, int *x, int *y);
    4.37  
    4.38  /**
    4.39   * \fn Uint8 SDL_GetRelativeMouseState(int *x, int *y)
    4.40 @@ -124,7 +125,8 @@
    4.41   * be tested using the SDL_BUTTON(X) macros, and x and y are set to the
    4.42   * mouse deltas since the last call to SDL_GetRelativeMouseState().
    4.43   */
    4.44 -extern DECLSPEC Uint8 SDLCALL SDL_GetRelativeMouseState(int *x, int *y);
    4.45 +extern DECLSPEC Uint8 SDLCALL SDL_GetRelativeMouseState(int index, int *x,
    4.46 +                                                        int *y);
    4.47  
    4.48  /**
    4.49   * \fn void SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y)
    4.50 @@ -203,6 +205,16 @@
    4.51     Button 2:	Middle mouse button
    4.52     Button 3:	Right mouse button
    4.53   */
    4.54 +
    4.55 +/* FIXME: Where do these functions go in this header?
    4.56 +          Also, add doxygen documentation for these...
    4.57 +*/
    4.58 +extern DECLSPEC char *SDLCALL SDL_GetMouseName(int index);
    4.59 +
    4.60 +extern DECLSPEC int SDLCALL SDL_GetCursorsNumber(int index);
    4.61 +
    4.62 +extern DECLSPEC int SDLCALL SDL_GetCurrentCursor(int index);
    4.63 +
    4.64  #define SDL_BUTTON(X)		(1 << ((X)-1))
    4.65  #define SDL_BUTTON_LEFT		1
    4.66  #define SDL_BUTTON_MIDDLE	2
     5.1 --- a/src/SDL_compat.c	Mon Aug 25 05:30:28 2008 +0000
     5.2 +++ b/src/SDL_compat.c	Mon Aug 25 06:33:00 2008 +0000
     5.3 @@ -256,7 +256,7 @@
     5.4              }
     5.5  
     5.6              selected = SDL_SelectMouse(event->wheel.which);
     5.7 -            SDL_GetMouseState(&x, &y);
     5.8 +            SDL_GetMouseState(selected, &x, &y);
     5.9              SDL_SelectMouse(selected);
    5.10  
    5.11              if (event->wheel.y > 0) {
     6.1 --- a/src/events/SDL_mouse.c	Mon Aug 25 05:30:28 2008 +0000
     6.2 +++ b/src/events/SDL_mouse.c	Mon Aug 25 06:33:00 2008 +0000
     6.3 @@ -28,9 +28,13 @@
     6.4  #include "default_cursor.h"
     6.5  
     6.6  
     6.7 -static int SDL_num_mice;
     6.8 -static int SDL_current_mouse;
     6.9 -static SDL_Mouse **SDL_mice;
    6.10 +static int SDL_num_mice = 0;
    6.11 +static int SDL_current_mouse = -1;
    6.12 +static SDL_Mouse **SDL_mice = NULL;
    6.13 +static int *SDL_IdIndex = NULL;
    6.14 +static int SDL_highestId = -1;
    6.15 +static int last_x, last_y;      /* the last reported x and y coordinates by the system cursor */
    6.16 +int x_max, y_max;               /* current window width and height */
    6.17  
    6.18  
    6.19  /* Public functions */
    6.20 @@ -50,10 +54,44 @@
    6.21  }
    6.22  
    6.23  int
    6.24 -SDL_AddMouse(const SDL_Mouse * mouse, int index)
    6.25 +SDL_SetMouseIndexId(int id, int index)
    6.26 +{
    6.27 +    if (id < 0) {
    6.28 +        SDL_SetError("Invalid Mouse ID");
    6.29 +        return -1;
    6.30 +    }
    6.31 +    if (id > SDL_highestId) {
    6.32 +        int *indexes;
    6.33 +        indexes = (int *) SDL_realloc(SDL_IdIndex, (id + 1) * sizeof(int));
    6.34 +        if (!indexes) {
    6.35 +            SDL_OutOfMemory();
    6.36 +            return -1;
    6.37 +        }
    6.38 +        SDL_IdIndex = indexes;
    6.39 +        SDL_IdIndex[id] = index;
    6.40 +        SDL_highestId = id;
    6.41 +    } else {
    6.42 +        SDL_IdIndex[id] = index;
    6.43 +    }
    6.44 +    return 1;
    6.45 +}
    6.46 +
    6.47 +SDL_Mouse *
    6.48 +SDL_GetMouseByID(int id)
    6.49 +{
    6.50 +    if (id < 0 || id > SDL_highestId) {
    6.51 +        return NULL;
    6.52 +    }
    6.53 +    return SDL_GetMouse(SDL_IdIndex[id]);
    6.54 +}
    6.55 +
    6.56 +int
    6.57 +SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name, int pressure_max,
    6.58 +             int pressure_min, int ends)
    6.59  {
    6.60      SDL_Mouse **mice;
    6.61      int selected_mouse;
    6.62 +    int length;
    6.63  
    6.64      /* Add the mouse to the list of mice */
    6.65      if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) {
    6.66 @@ -75,7 +113,13 @@
    6.67      }
    6.68      *SDL_mice[index] = *mouse;
    6.69  
    6.70 -    /* Create the default cursor for the mouse */
    6.71 +    /* we're setting the mouse properties */
    6.72 +    length = 0;
    6.73 +    length = SDL_strlen(name);
    6.74 +    SDL_mice[index]->name = SDL_malloc((length + 1) * sizeof(char));
    6.75 +    SDL_strlcpy(SDL_mice[index]->name, name, length);
    6.76 +    SDL_mice[index]->pressure_max = pressure_max;
    6.77 +    SDL_mice[index]->pressure_min = pressure_min;
    6.78      SDL_mice[index]->cursor_shown = SDL_TRUE;
    6.79      selected_mouse = SDL_SelectMouse(index);
    6.80      SDL_mice[index]->cur_cursor = NULL;
    6.81 @@ -83,6 +127,14 @@
    6.82          SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH,
    6.83                           DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
    6.84      SDL_SetCursor(SDL_mice[index]->def_cursor);
    6.85 +    /* we're assuming that all mice are in the computer sensing zone */
    6.86 +    SDL_mice[index]->proximity = SDL_TRUE;
    6.87 +    /* we're assuming that all mice are working in the absolute position mode
    6.88 +       thanx to that, the users that don't want to use many mice don't have to
    6.89 +       worry about anything */
    6.90 +    SDL_mice[index]->relative_mode = SDL_FALSE;
    6.91 +    SDL_mice[index]->current_end = 0;
    6.92 +    SDL_mice[index]->total_ends = ends;
    6.93      SDL_SelectMouse(selected_mouse);
    6.94  
    6.95      return index;
    6.96 @@ -98,6 +150,7 @@
    6.97      }
    6.98  
    6.99      mouse->def_cursor = NULL;
   6.100 +    SDL_free(mouse->name);
   6.101      while (mouse->cursors) {
   6.102          SDL_FreeCursor(mouse->cursors);
   6.103      }
   6.104 @@ -155,9 +208,9 @@
   6.105  }
   6.106  
   6.107  SDL_WindowID
   6.108 -SDL_GetMouseFocusWindow()
   6.109 +SDL_GetMouseFocusWindow(int index)
   6.110  {
   6.111 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   6.112 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.113  
   6.114      if (!mouse) {
   6.115          return 0;
   6.116 @@ -177,9 +230,9 @@
   6.117  }
   6.118  
   6.119  int
   6.120 -SDL_SetRelativeMouseMode(SDL_bool enabled)
   6.121 +SDL_SetRelativeMouseMode(int index, SDL_bool enabled)
   6.122  {
   6.123 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   6.124 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.125  
   6.126      if (!mouse) {
   6.127          return -1;
   6.128 @@ -205,9 +258,9 @@
   6.129  }
   6.130  
   6.131  SDL_bool
   6.132 -SDL_GetRelativeMouseMode()
   6.133 +SDL_GetRelativeMouseMode(int index)
   6.134  {
   6.135 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   6.136 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.137  
   6.138      if (!mouse) {
   6.139          return SDL_FALSE;
   6.140 @@ -216,9 +269,9 @@
   6.141  }
   6.142  
   6.143  Uint8
   6.144 -SDL_GetMouseState(int *x, int *y)
   6.145 +SDL_GetMouseState(int index, int *x, int *y)
   6.146  {
   6.147 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   6.148 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.149  
   6.150      if (!mouse) {
   6.151          if (x) {
   6.152 @@ -240,9 +293,9 @@
   6.153  }
   6.154  
   6.155  Uint8
   6.156 -SDL_GetRelativeMouseState(int *x, int *y)
   6.157 +SDL_GetRelativeMouseState(int index, int *x, int *y)
   6.158  {
   6.159 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   6.160 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.161  
   6.162      if (!mouse) {
   6.163          if (x) {
   6.164 @@ -266,16 +319,18 @@
   6.165  }
   6.166  
   6.167  void
   6.168 -SDL_SetMouseFocus(int index, SDL_WindowID windowID)
   6.169 +SDL_SetMouseFocus(int id, SDL_WindowID windowID)
   6.170  {
   6.171 -    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.172 -    int i;
   6.173 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   6.174 +    int i, index;
   6.175      SDL_bool focus;
   6.176  
   6.177      if (!mouse || (mouse->focus == windowID)) {
   6.178          return;
   6.179      }
   6.180  
   6.181 +    index = SDL_IdIndex[id];
   6.182 +
   6.183      /* See if the current window has lost focus */
   6.184      if (mouse->focus) {
   6.185          focus = SDL_FALSE;
   6.186 @@ -315,28 +370,62 @@
   6.187  }
   6.188  
   6.189  int
   6.190 -SDL_SendMouseMotion(int index, int relative, int x, int y)
   6.191 +SDL_SendProximity(int id, int x, int y, int type)
   6.192  {
   6.193 -    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.194 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   6.195 +    int posted = 0;
   6.196 +    last_x = x;
   6.197 +    last_y = y;
   6.198 +    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
   6.199 +        SDL_Event event;
   6.200 +        event.proximity.which = (Uint8) index;
   6.201 +        event.proximity.x = x;
   6.202 +        event.proximity.y = y;
   6.203 +        event.proximity.cursor = mouse->current_end;
   6.204 +        event.proximity.type = type;
   6.205 +        posted = (SDL_PushEvent(&event) > 0);
   6.206 +        if (type == SDL_PROXIMITYIN) {
   6.207 +            mouse->proximity = SDL_TRUE;
   6.208 +        } else {
   6.209 +            mouse->proximity = SDL_FALSE;
   6.210 +        }
   6.211 +    }
   6.212 +    return posted;
   6.213 +}
   6.214 +
   6.215 +int
   6.216 +SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure)
   6.217 +{
   6.218 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   6.219      int posted;
   6.220      int xrel;
   6.221      int yrel;
   6.222  
   6.223 +    /* while using the relative mode and many windows, we have to be sure,
   6.224 +       that the pointers find themselves inside the windows */
   6.225 +    if (x > x_max) {
   6.226 +        x = x_max;
   6.227 +    }
   6.228 +    if (y > y_max) {
   6.229 +        y = y_max;
   6.230 +    }
   6.231 +
   6.232      if (!mouse || mouse->flush_motion) {
   6.233          return 0;
   6.234      }
   6.235  
   6.236 -    if (relative) {
   6.237 -        /* Push the cursor around */
   6.238 -        xrel = x;
   6.239 -        yrel = y;
   6.240 -        x = (mouse->x + xrel);
   6.241 -        y = (mouse->y + yrel);
   6.242 -    } else {
   6.243 -        xrel = x - mouse->x;
   6.244 -        yrel = y - mouse->y;
   6.245 +    /* if the mouse is out of proximity we don't to want to have any motion from it */
   6.246 +    if (mouse->proximity == SDL_FALSE) {
   6.247 +        last_x = x;
   6.248 +        last_y = y;
   6.249 +        return 0;
   6.250      }
   6.251  
   6.252 +    /* the relative motion is calculated regarding the system cursor last position */
   6.253 +
   6.254 +    xrel = x - last_x;
   6.255 +    yrel = y - last_y;
   6.256 +
   6.257      /* Drop events that don't change state */
   6.258      if (!xrel && !yrel) {
   6.259  #if 0
   6.260 @@ -345,13 +434,29 @@
   6.261          return 0;
   6.262      }
   6.263  
   6.264 -    /* Update internal mouse state */
   6.265 -    if (!mouse->relative_mode) {
   6.266 +    /* Update internal mouse coordinates */
   6.267 +    if (mouse->relative_mode == SDL_FALSE) {
   6.268          mouse->x = x;
   6.269          mouse->y = y;
   6.270 +    } else {
   6.271 +        if (mouse->x + xrel > x_max) {
   6.272 +            mouse->x = x_max;
   6.273 +        } else if (mouse->x + xrel < 0) {
   6.274 +            mouse->x = 0;
   6.275 +        } else {
   6.276 +            mouse->x += xrel;
   6.277 +        }
   6.278 +        if (mouse->y + yrel > y_max) {
   6.279 +            mouse->y = y_max;
   6.280 +        } else if (mouse->y + yrel < 0) {
   6.281 +            mouse->y = 0;
   6.282 +        } else {
   6.283 +            mouse->y += yrel;
   6.284 +        }
   6.285      }
   6.286      mouse->xdelta += xrel;
   6.287      mouse->ydelta += yrel;
   6.288 +    mouse->pressure = pressure;
   6.289  
   6.290      /* Move the mouse cursor, if needed */
   6.291      if (mouse->cursor_shown && !mouse->relative_mode &&
   6.292 @@ -361,25 +466,32 @@
   6.293  
   6.294      /* Post the event, if desired */
   6.295      posted = 0;
   6.296 -    if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) {
   6.297 +    if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE &&
   6.298 +        mouse->proximity == SDL_TRUE) {
   6.299          SDL_Event event;
   6.300          event.motion.type = SDL_MOUSEMOTION;
   6.301          event.motion.which = (Uint8) index;
   6.302          event.motion.state = mouse->buttonstate;
   6.303          event.motion.x = mouse->x;
   6.304          event.motion.y = mouse->y;
   6.305 +        event.motion.pressure = mouse->pressure;
   6.306          event.motion.xrel = xrel;
   6.307          event.motion.yrel = yrel;
   6.308          event.motion.windowID = mouse->focus;
   6.309 +        event.motion.pressure_max = mouse->pressure_max;
   6.310 +        event.motion.pressure_min = mouse->pressure_min;
   6.311 +        event.motion.cursor = mouse->current_end;
   6.312          posted = (SDL_PushEvent(&event) > 0);
   6.313      }
   6.314 +    last_x = x;
   6.315 +    last_y = y;
   6.316      return posted;
   6.317  }
   6.318  
   6.319  int
   6.320 -SDL_SendMouseButton(int index, Uint8 state, Uint8 button)
   6.321 +SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
   6.322  {
   6.323 -    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.324 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   6.325      int posted;
   6.326      Uint8 type;
   6.327  
   6.328 @@ -398,10 +510,6 @@
   6.329          mouse->buttonstate |= SDL_BUTTON(button);
   6.330          break;
   6.331      case SDL_RELEASED:
   6.332 -        if (!(mouse->buttonstate & SDL_BUTTON(button))) {
   6.333 -            /* Ignore this event, no state change */
   6.334 -            return 0;
   6.335 -        }
   6.336          type = SDL_MOUSEBUTTONUP;
   6.337          mouse->buttonstate &= ~SDL_BUTTON(button);
   6.338          break;
   6.339 @@ -463,7 +571,7 @@
   6.340          mouse->WarpMouse(mouse, windowID, x, y);
   6.341      } else {
   6.342          SDL_SetMouseFocus(SDL_current_mouse, windowID);
   6.343 -        SDL_SendMouseMotion(SDL_current_mouse, 0, x, y);
   6.344 +        SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0);
   6.345      }
   6.346  }
   6.347  
   6.348 @@ -649,4 +757,53 @@
   6.349      return shown;
   6.350  }
   6.351  
   6.352 +char *
   6.353 +SDL_GetMouseName(int index)
   6.354 +{
   6.355 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.356 +    if (!mouse) {
   6.357 +        return NULL;
   6.358 +    }
   6.359 +    return mouse->name;
   6.360 +}
   6.361 +
   6.362 +void
   6.363 +SDL_UpdateCoordinates(int x, int y)
   6.364 +{
   6.365 +    x_max = x;
   6.366 +    y_max = y;
   6.367 +}
   6.368 +
   6.369 +void
   6.370 +SDL_ChangeEnd(int id, int end)
   6.371 +{
   6.372 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   6.373 +
   6.374 +    if (mouse) {
   6.375 +        mouse->current_end = end;
   6.376 +    }
   6.377 +}
   6.378 +
   6.379 +int
   6.380 +SDL_GetCursorsNumber(int index)
   6.381 +{
   6.382 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.383 +
   6.384 +    if (!mouse) {
   6.385 +        return -1;
   6.386 +    }
   6.387 +    return mouse->total_ends;
   6.388 +}
   6.389 +
   6.390 +int
   6.391 +SDL_GetCurrentCursor(int index)
   6.392 +{
   6.393 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   6.394 +
   6.395 +    if (!mouse) {
   6.396 +        return -1;
   6.397 +    }
   6.398 +    return mouse->current_end;
   6.399 +}
   6.400 +
   6.401  /* vi: set ts=4 sw=4 expandtab: */
     7.1 --- a/src/events/SDL_mouse_c.h	Mon Aug 25 05:30:28 2008 +0000
     7.2 +++ b/src/events/SDL_mouse_c.h	Mon Aug 25 06:33:00 2008 +0000
     7.3 @@ -29,9 +29,7 @@
     7.4  struct SDL_Cursor
     7.5  {
     7.6      SDL_Mouse *mouse;
     7.7 -
     7.8      SDL_Cursor *next;
     7.9 -
    7.10      void *driverdata;
    7.11  };
    7.12  
    7.13 @@ -56,14 +54,27 @@
    7.14      /* Free the mouse when it's time */
    7.15      void (*FreeMouse) (SDL_Mouse * mouse);
    7.16  
    7.17 +    /* data common for tablets */
    7.18 +    int pressure;
    7.19 +    int pressure_max;
    7.20 +    int pressure_min;
    7.21 +    int tilt;                   /* for future use */
    7.22 +    int rotation;               /* for future use */
    7.23 +    int total_ends;
    7.24 +    int current_end;
    7.25 +
    7.26      /* Data common to all mice */
    7.27      SDL_WindowID focus;
    7.28 +    int which;
    7.29      int x;
    7.30      int y;
    7.31 +    int z;                      /* for future use */
    7.32      int xdelta;
    7.33      int ydelta;
    7.34 +    char *name;
    7.35      Uint8 buttonstate;
    7.36      SDL_bool relative_mode;
    7.37 +    SDL_bool proximity;
    7.38      SDL_bool flush_motion;
    7.39  
    7.40      SDL_Cursor *cursors;
    7.41 @@ -74,17 +85,23 @@
    7.42      void *driverdata;
    7.43  };
    7.44  
    7.45 -
    7.46  /* Initialize the mouse subsystem */
    7.47  extern int SDL_MouseInit(void);
    7.48  
    7.49  /* Get the mouse at an index */
    7.50  extern SDL_Mouse *SDL_GetMouse(int index);
    7.51  
    7.52 +/* Assign an id to a mouse at an index */
    7.53 +extern int SDL_SetMouseIndexId(int id, int index);
    7.54 +
    7.55 +/* Get the mouse by id */
    7.56 +extern SDL_Mouse *SDL_GetMouseByID(int id);
    7.57 +
    7.58  /* Add a mouse, possibly reattaching at a particular index (or -1),
    7.59     returning the index of the mouse, or -1 if there was an error.
    7.60   */
    7.61 -extern int SDL_AddMouse(const SDL_Mouse * mouse, int index);
    7.62 +extern int SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name,
    7.63 +                        int pressure_max, int pressure_min, int ends);
    7.64  
    7.65  /* Remove a mouse at an index, clearing the slot for later */
    7.66  extern void SDL_DelMouse(int index);
    7.67 @@ -93,20 +110,24 @@
    7.68  extern void SDL_ResetMouse(int index);
    7.69  
    7.70  /* Set the mouse focus window */
    7.71 -extern void SDL_SetMouseFocus(int index, SDL_WindowID windowID);
    7.72 +extern void SDL_SetMouseFocus(int id, SDL_WindowID windowID);
    7.73  
    7.74  /* Send a mouse motion event for a mouse at an index */
    7.75 -extern int SDL_SendMouseMotion(int index, int relative, int x, int y);
    7.76 +extern int SDL_SendMouseMotion(int id, int relative, int x, int y, int z);
    7.77  
    7.78  /* Send a mouse button event for a mouse at an index */
    7.79 -extern int SDL_SendMouseButton(int index, Uint8 state, Uint8 button);
    7.80 +extern int SDL_SendMouseButton(int id, Uint8 state, Uint8 button);
    7.81  
    7.82  /* Send a mouse wheel event for a mouse at an index */
    7.83 -extern int SDL_SendMouseWheel(int index, int x, int y);
    7.84 +extern int SDL_SendMouseWheel(int id, int x, int y);
    7.85  
    7.86  /* Shutdown the mouse subsystem */
    7.87  extern void SDL_MouseQuit(void);
    7.88  
    7.89 +/* FIXME: Where do these functions go in this header? */
    7.90 +extern void SDL_UpdateCoordinates(int x, int y);
    7.91 +extern void SDL_ChangeEnd(int id, int end);
    7.92 +
    7.93  #endif /* _SDL_mouse_c_h */
    7.94  
    7.95  /* vi: set ts=4 sw=4 expandtab: */
     8.1 --- a/src/video/cocoa/SDL_cocoamouse.m	Mon Aug 25 05:30:28 2008 +0000
     8.2 +++ b/src/video/cocoa/SDL_cocoamouse.m	Mon Aug 25 06:33:00 2008 +0000
     8.3 @@ -32,7 +32,8 @@
     8.4      SDL_Mouse mouse;
     8.5  
     8.6      SDL_zero(mouse);
     8.7 -    data->mouse = SDL_AddMouse(&mouse, -1);
     8.8 +    data->mouse = SDL_AddMouse(&mouse, -1, "Mouse", 0, 0, 1);
     8.9 +    SDL_SetMouseIndexId(data->mouse, data->mouse);
    8.10  }
    8.11  
    8.12  void
     9.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Mon Aug 25 05:30:28 2008 +0000
     9.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Aug 25 06:33:00 2008 +0000
     9.3 @@ -250,7 +250,7 @@
     9.4          if (mouse->focus != _data->windowID) {
     9.5              SDL_SetMouseFocus(index, _data->windowID);
     9.6          }
     9.7 -        SDL_SendMouseMotion(index, 0, (int)point.x, (int)point.y);
     9.8 +        SDL_SendMouseMotion(index, 0, (int)point.x, (int)point.y, 0);
     9.9      }
    9.10  }
    9.11  
    10.1 --- a/src/video/win32/SDL_win32events.c	Mon Aug 25 05:30:28 2008 +0000
    10.2 +++ b/src/video/win32/SDL_win32events.c	Mon Aug 25 06:33:00 2008 +0000
    10.3 @@ -19,6 +19,12 @@
    10.4      Sam Lantinga
    10.5      slouken@libsdl.org
    10.6  */
    10.7 +
    10.8 +#if (_WIN32_WINNT < 0x0501)
    10.9 +#undef _WIN32_WINNT
   10.10 +#define _WIN32_WINNT 0x0501
   10.11 +#endif
   10.12 +
   10.13  #include "SDL_config.h"
   10.14  
   10.15  #include "SDL_win32video.h"
   10.16 @@ -26,6 +32,11 @@
   10.17  #include "SDL_vkeys.h"
   10.18  #include "../../events/SDL_events_c.h"
   10.19  
   10.20 +#include <wintab.h>
   10.21 +#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR)
   10.22 +#define PACKETMODE 0
   10.23 +#include <pktdef.h>
   10.24 +
   10.25  /*#define WMMSG_DEBUG*/
   10.26  #ifdef WMMSG_DEBUG
   10.27  #include <stdio.h>
   10.28 @@ -49,6 +60,12 @@
   10.29  #define GET_XBUTTON_WPARAM(w) (HIWORD(w))
   10.30  #endif
   10.31  
   10.32 +extern HCTX *g_hCtx;
   10.33 +extern HANDLE *mice;
   10.34 +extern int total_mice;
   10.35 +extern int tablet;
   10.36 +int pressure = 0;               /* the pressure reported by the tablet */
   10.37 +
   10.38  static WPARAM
   10.39  RemapVKEY(WPARAM wParam, LPARAM lParam)
   10.40  {
   10.41 @@ -84,6 +101,8 @@
   10.42  WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
   10.43  {
   10.44      SDL_WindowData *data;
   10.45 +    RAWINPUT *raw;
   10.46 +    PACKET packet;
   10.47  
   10.48      /* Send a SDL_SYSWMEVENT if the application wants them */
   10.49      if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
   10.50 @@ -114,10 +133,40 @@
   10.51          fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam);
   10.52          fclose(log);
   10.53      }
   10.54 +
   10.55  #endif
   10.56  
   10.57      switch (msg) {
   10.58  
   10.59 +    case WT_PACKET:
   10.60 +        {
   10.61 +            /* if we receive such data we need to update the pressure */
   10.62 +            if (WTPacket((HCTX) lParam, wParam, &packet)) {
   10.63 +                SDL_ChangeEnd(tablet, (int) packet.pkCursor);
   10.64 +                pressure = (int) packet.pkNormalPressure;
   10.65 +            }
   10.66 +        }
   10.67 +        break;
   10.68 +
   10.69 +    case WT_PROXIMITY:
   10.70 +        {
   10.71 +            /* checking where the proximity message showed up */
   10.72 +            int h_context = LOWORD(lParam);
   10.73 +            LPPOINT point;
   10.74 +            GetCursorPos(&point);
   10.75 +            ScreenToClient(hwnd, &point);
   10.76 +
   10.77 +            /* are we in proximity or out of proximity */
   10.78 +            if (h_context == 0) {
   10.79 +                SDL_SendProximity(tablet, (int) (&point->x),
   10.80 +                                  (int) (&point->y), SDL_PROXIMITYOUT);
   10.81 +            } else {
   10.82 +                SDL_SendProximity(tablet, (int) (&point->x),
   10.83 +                                  (int) (&point->y), SDL_PROXIMITYIN);
   10.84 +            }
   10.85 +        }
   10.86 +        break;
   10.87 +
   10.88      case WM_SHOWWINDOW:
   10.89          {
   10.90              if (wParam) {
   10.91 @@ -161,48 +210,72 @@
   10.92                                          SDL_WINDOWEVENT_MINIMIZED, 0, 0);
   10.93                  }
   10.94              }
   10.95 -            return (0);
   10.96          }
   10.97 -        break;
   10.98 +        return (0);
   10.99  
  10.100 -    case WM_MOUSEMOVE:
  10.101 +    case WM_INPUT:             /* mouse events */
  10.102          {
  10.103 +            LPBYTE lpb;
  10.104 +            int w, h;
  10.105 +            const RAWINPUTHEADER *header;
  10.106              int index;
  10.107 -            SDL_Mouse *mouse;
  10.108 -            int x, y;
  10.109 +            int i;
  10.110 +            int size = 0;
  10.111 +            const RAWMOUSE *raw_mouse = NULL;
  10.112 +            LPPOINT point;
  10.113 +            USHORT flags;
  10.114  
  10.115 -            index = data->videodata->mouse;
  10.116 -            mouse = SDL_GetMouse(index);
  10.117 +            /* we're collecting data from the mouse */
  10.118 +            GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size,
  10.119 +                            sizeof(RAWINPUTHEADER));
  10.120 +            lpb = SDL_malloc(size * sizeof(LPBYTE));
  10.121 +            GetRawInputData((HRAWINPUT) lParam, RID_INPUT, lpb, &size,
  10.122 +                            sizeof(RAWINPUTHEADER));
  10.123 +            raw = (RAWINPUT *) lpb;
  10.124 +            header = &raw->header;
  10.125 +            flags = raw->data.mouse.usButtonFlags;
  10.126  
  10.127 -            if (mouse->focus != data->windowID) {
  10.128 -                TRACKMOUSEEVENT tme;
  10.129 +            /* we're checking which mouse generated the event */
  10.130 +            for (i = 0; i < total_mice; ++i) {
  10.131 +                if (mice[i] == header->hDevice) {
  10.132 +                    index = i;
  10.133 +                    break;
  10.134 +                }
  10.135 +            }
  10.136 +            GetCursorPos(&point);
  10.137 +            ScreenToClient(hwnd, &point);
  10.138 +            SDL_GetWindowSize(data->windowID, &w, &h);
  10.139 +            SDL_UpdateCoordinates(w, h);        /* we're updating the current window size */
  10.140  
  10.141 -                tme.cbSize = sizeof(tme);
  10.142 -                tme.dwFlags = TME_LEAVE;
  10.143 -                tme.hwndTrack = hwnd;
  10.144 -                TrackMouseEvent(&tme);
  10.145 -
  10.146 -                SDL_SetMouseFocus(index, data->windowID);
  10.147 +            /* if the message was sent by a tablet we have to send also pressure */
  10.148 +            if (i == tablet) {
  10.149 +                SDL_SendMouseMotion(index, 0, (int) (&point->x),
  10.150 +                                    (int) (&point->y), pressure);
  10.151 +            } else {
  10.152 +                SDL_SendMouseMotion(index, 0, (int) (&point->x),
  10.153 +                                    (int) (&point->y), 0);
  10.154              }
  10.155 -
  10.156 -            /* mouse has moved within the window */
  10.157 -            x = LOWORD(lParam);
  10.158 -            y = HIWORD(lParam);
  10.159 -            if (mouse->relative_mode) {
  10.160 -                int w, h;
  10.161 -                POINT center;
  10.162 -                SDL_GetWindowSize(data->windowID, &w, &h);
  10.163 -                center.x = (w / 2);
  10.164 -                center.y = (h / 2);
  10.165 -                x -= center.x;
  10.166 -                y -= center.y;
  10.167 -                if (x || y) {
  10.168 -                    ClientToScreen(hwnd, &center);
  10.169 -                    SetCursorPos(center.x, center.y);
  10.170 -                    SDL_SendMouseMotion(index, 1, x, y);
  10.171 +            /* we're sending mouse buttons messages to check up if sth changed */
  10.172 +            if (flags & RI_MOUSE_BUTTON_1_DOWN) {
  10.173 +                SDL_SendMouseButton(index, SDL_PRESSED, SDL_BUTTON_LEFT);
  10.174 +            } else if (flags & RI_MOUSE_BUTTON_1_UP) {
  10.175 +                SDL_SendMouseButton(index, SDL_RELEASED, SDL_BUTTON_LEFT);
  10.176 +            }
  10.177 +            if (flags & RI_MOUSE_BUTTON_2_DOWN) {
  10.178 +                SDL_SendMouseButton(index, SDL_PRESSED, SDL_BUTTON_MIDDLE);
  10.179 +            } else if (flags & RI_MOUSE_BUTTON_2_UP) {
  10.180 +                SDL_SendMouseButton(index, SDL_RELEASED, SDL_BUTTON_MIDDLE);
  10.181 +            }
  10.182 +            if (flags & RI_MOUSE_BUTTON_3_DOWN) {
  10.183 +                SDL_SendMouseButton(index, SDL_PRESSED, SDL_BUTTON_RIGHT);
  10.184 +            } else if (flags & RI_MOUSE_BUTTON_3_UP) {
  10.185 +                SDL_SendMouseButton(index, SDL_RELEASED, SDL_BUTTON_RIGHT);
  10.186 +            }
  10.187 +            if (flags & RI_MOUSE_WHEEL) {
  10.188 +                if (raw->data.mouse.usButtonData != 0) {
  10.189 +                    SDL_SendMouseWheel(index, 0,
  10.190 +                                       raw->data.mouse.usButtonData);
  10.191                  }
  10.192 -            } else {
  10.193 -                SDL_SendMouseMotion(index, 0, x, y);
  10.194              }
  10.195          }
  10.196          return (0);
  10.197 @@ -221,117 +294,6 @@
  10.198          }
  10.199          return (0);
  10.200  
  10.201 -    case WM_LBUTTONDOWN:
  10.202 -    case WM_LBUTTONUP:
  10.203 -    case WM_MBUTTONDOWN:
  10.204 -    case WM_MBUTTONUP:
  10.205 -    case WM_RBUTTONDOWN:
  10.206 -    case WM_RBUTTONUP:
  10.207 -    case WM_XBUTTONDOWN:
  10.208 -    case WM_XBUTTONUP:
  10.209 -        {
  10.210 -            int xbuttonval = 0;
  10.211 -            int index;
  10.212 -            SDL_Mouse *mouse;
  10.213 -            Uint8 button, state;
  10.214 -
  10.215 -            /* DJM:
  10.216 -               We want the SDL window to take focus so that
  10.217 -               it acts like a normal windows "component"
  10.218 -               (e.g. gains keyboard focus on a mouse click).
  10.219 -             */
  10.220 -            SetFocus(hwnd);
  10.221 -
  10.222 -            index = data->videodata->mouse;
  10.223 -            mouse = SDL_GetMouse(index);
  10.224 -
  10.225 -            /* Figure out which button to use */
  10.226 -            switch (msg) {
  10.227 -            case WM_LBUTTONDOWN:
  10.228 -                button = SDL_BUTTON_LEFT;
  10.229 -                state = SDL_PRESSED;
  10.230 -                break;
  10.231 -            case WM_LBUTTONUP:
  10.232 -                button = SDL_BUTTON_LEFT;
  10.233 -                state = SDL_RELEASED;
  10.234 -                break;
  10.235 -            case WM_MBUTTONDOWN:
  10.236 -                button = SDL_BUTTON_MIDDLE;
  10.237 -                state = SDL_PRESSED;
  10.238 -                break;
  10.239 -            case WM_MBUTTONUP:
  10.240 -                button = SDL_BUTTON_MIDDLE;
  10.241 -                state = SDL_RELEASED;
  10.242 -                break;
  10.243 -            case WM_RBUTTONDOWN:
  10.244 -                button = SDL_BUTTON_RIGHT;
  10.245 -                state = SDL_PRESSED;
  10.246 -                break;
  10.247 -            case WM_RBUTTONUP:
  10.248 -                button = SDL_BUTTON_RIGHT;
  10.249 -                state = SDL_RELEASED;
  10.250 -                break;
  10.251 -            case WM_XBUTTONDOWN:
  10.252 -                xbuttonval = GET_XBUTTON_WPARAM(wParam);
  10.253 -                button = SDL_BUTTON_X1 + xbuttonval - 1;
  10.254 -                state = SDL_PRESSED;
  10.255 -                break;
  10.256 -            case WM_XBUTTONUP:
  10.257 -                xbuttonval = GET_XBUTTON_WPARAM(wParam);
  10.258 -                button = SDL_BUTTON_X1 + xbuttonval - 1;
  10.259 -                state = SDL_RELEASED;
  10.260 -                break;
  10.261 -            default:
  10.262 -                /* Eh? Unknown button? */
  10.263 -                return (0);
  10.264 -            }
  10.265 -            if (state == SDL_PRESSED) {
  10.266 -                /* Grab mouse so we get up events */
  10.267 -                if (++data->mouse_pressed > 0) {
  10.268 -                    SetCapture(hwnd);
  10.269 -                }
  10.270 -            } else {
  10.271 -                /* Release mouse after all up events */
  10.272 -                if (--data->mouse_pressed <= 0) {
  10.273 -                    ReleaseCapture();
  10.274 -                    data->mouse_pressed = 0;
  10.275 -                }
  10.276 -            }
  10.277 -
  10.278 -            if (!mouse->relative_mode) {
  10.279 -                int x, y;
  10.280 -                x = LOWORD(lParam);
  10.281 -                y = HIWORD(lParam);
  10.282 -                SDL_SendMouseMotion(index, 0, x, y);
  10.283 -            }
  10.284 -            SDL_SendMouseButton(index, state, button);
  10.285 -
  10.286 -            /*
  10.287 -             * MSDN says:
  10.288 -             *  "Unlike the WM_LBUTTONUP, WM_MBUTTONUP, and WM_RBUTTONUP
  10.289 -             *   messages, an application should return TRUE from [an
  10.290 -             *   XBUTTON message] if it processes it. Doing so will allow
  10.291 -             *   software that simulates this message on Microsoft Windows
  10.292 -             *   systems earlier than Windows 2000 to determine whether
  10.293 -             *   the window procedure processed the message or called
  10.294 -             *   DefWindowProc to process it.
  10.295 -             */
  10.296 -            if (xbuttonval > 0) {
  10.297 -                return (TRUE);
  10.298 -            }
  10.299 -        }
  10.300 -        return (0);
  10.301 -
  10.302 -    case WM_MOUSEWHEEL:
  10.303 -        {
  10.304 -            int index;
  10.305 -            int motion = (short) HIWORD(wParam);
  10.306 -
  10.307 -            index = data->videodata->mouse;
  10.308 -            SDL_SendMouseWheel(index, 0, motion);
  10.309 -        }
  10.310 -        return (0);
  10.311 -
  10.312      case WM_SYSKEYDOWN:
  10.313      case WM_KEYDOWN:
  10.314          {
  10.315 @@ -426,6 +388,7 @@
  10.316                      wParam = VK_ENTER;
  10.317                  break;
  10.318              }
  10.319 +
  10.320              /* Windows only reports keyup for print screen */
  10.321              if (wParam == VK_SNAPSHOT
  10.322                  && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] ==
  10.323 @@ -499,11 +462,9 @@
  10.324                 inside their function, so I have to do it here.
  10.325               */
  10.326              style = GetWindowLong(hwnd, GWL_STYLE);
  10.327 -            AdjustWindowRect(&size,
  10.328 -                             style,
  10.329 -                             style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd) !=
  10.330 -                             NULL);
  10.331 -
  10.332 +            AdjustWindowRect(&size, style,
  10.333 +                             style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd)
  10.334 +                             != NULL);
  10.335              w = size.right - size.left;
  10.336              h = size.bottom - size.top;
  10.337  
  10.338 @@ -661,8 +622,9 @@
  10.339  
  10.340      /* Register the application class */
  10.341      class.hCursor = NULL;
  10.342 -    class.hIcon = LoadImage(SDL_Instance, SDL_Appname,
  10.343 -                            IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
  10.344 +    class.hIcon =
  10.345 +        LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0,
  10.346 +                  LR_DEFAULTCOLOR);
  10.347      class.lpszMenuName = NULL;
  10.348      class.lpszClassName = SDL_Appname;
  10.349      class.hbrBackground = NULL;
  10.350 @@ -707,11 +669,8 @@
  10.351  {
  10.352      TCHAR buffer[1024];
  10.353      char *message;
  10.354 -
  10.355 -    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  10.356 -                  NULL,
  10.357 -                  GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL);
  10.358 -
  10.359 +    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
  10.360 +                  buffer, SDL_arraysize(buffer), NULL);
  10.361      message = WIN_StringToUTF8(buffer);
  10.362      SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ":" : "", message);
  10.363      SDL_free(message);
    11.1 --- a/src/video/win32/SDL_win32mouse.c	Mon Aug 25 05:30:28 2008 +0000
    11.2 +++ b/src/video/win32/SDL_win32mouse.c	Mon Aug 25 06:33:00 2008 +0000
    11.3 @@ -19,20 +19,179 @@
    11.4      Sam Lantinga
    11.5      slouken@libsdl.org
    11.6  */
    11.7 +
    11.8 +/* we need to define it, so that raw input is included*/
    11.9 +
   11.10 +#if (_WIN32_WINNT < 0x0501)
   11.11 +#undef _WIN32_WINNT
   11.12 +#define _WIN32_WINNT 0x0501
   11.13 +#endif
   11.14 +
   11.15  #include "SDL_config.h"
   11.16  
   11.17  #include "SDL_win32video.h"
   11.18  
   11.19  #include "../../events/SDL_mouse_c.h"
   11.20  
   11.21 +#include <wintab.h>
   11.22 +
   11.23 +#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR)
   11.24 +#define PACKETMODE 0
   11.25 +#include <pktdef.h>
   11.26 +extern HANDLE *mice;
   11.27 +extern int total_mice;
   11.28 +extern int tablet;
   11.29 +
   11.30  void
   11.31  WIN_InitMouse(_THIS)
   11.32  {
   11.33 +    int index = 0;
   11.34 +    RAWINPUTDEVICELIST *deviceList = NULL;
   11.35 +    int devCount = 0;
   11.36 +    int i;
   11.37 +    int tmp = 0;
   11.38 +    char *buffer = NULL;
   11.39 +    char *tab = "wacom";        /* since windows does't give us handles to tablets, we have to detect a tablet by it's name */
   11.40 +    const char *rdp = "rdp_mou";
   11.41      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   11.42 -    SDL_Mouse mouse;
   11.43  
   11.44 -    SDL_zero(mouse);
   11.45 -    data->mouse = SDL_AddMouse(&mouse, -1);
   11.46 +    /* we're checking for the number of rawinput devices */
   11.47 +    if (GetRawInputDeviceList(NULL, &devCount, sizeof(RAWINPUTDEVICELIST))) {
   11.48 +        return;
   11.49 +    }
   11.50 +
   11.51 +    deviceList = SDL_malloc(sizeof(RAWINPUTDEVICELIST) * devCount);
   11.52 +
   11.53 +    /* we're getting the raw input device list */
   11.54 +    GetRawInputDeviceList(deviceList, &devCount, sizeof(RAWINPUTDEVICELIST));
   11.55 +    mice = SDL_malloc(devCount * sizeof(HANDLE));
   11.56 +
   11.57 +    /* we're getting the details of the devices */
   11.58 +    for (i = 0; i < devCount; ++i) {
   11.59 +        int is_rdp = 0;
   11.60 +        int j;
   11.61 +        int k;
   11.62 +        char *default_device_name = "Pointing device xx";
   11.63 +        const char *reg_key_root = "System\\CurrentControlSet\\Enum\\";
   11.64 +        char *device_name = SDL_malloc(256 * sizeof(char));
   11.65 +        char *key_name = NULL;
   11.66 +        char *tmp_name = NULL;
   11.67 +        LONG rc = 0;
   11.68 +        HKEY hkey;
   11.69 +        DWORD regtype = REG_SZ;
   11.70 +        DWORD out = 256 * sizeof(char);
   11.71 +        SDL_Mouse mouse;
   11.72 +        int l;
   11.73 +        if (deviceList[i].dwType != RIM_TYPEMOUSE) {    /* if a device isn't a mouse type we don't want it */
   11.74 +            continue;
   11.75 +        }
   11.76 +        if (GetRawInputDeviceInfoA
   11.77 +            (deviceList[i].hDevice, RIDI_DEVICENAME, NULL, &tmp) < 0) {
   11.78 +            continue;
   11.79 +        }
   11.80 +        buffer = SDL_malloc((tmp + 1) * sizeof(char));
   11.81 +        key_name = SDL_malloc(tmp + sizeof(reg_key_root) * sizeof(char));
   11.82 +
   11.83 +        /* we're getting the device registry path and polishing it to get it's name,
   11.84 +           surely there must be an easier way, but we haven't found it yet */
   11.85 +        if (GetRawInputDeviceInfoA
   11.86 +            (deviceList[i].hDevice, RIDI_DEVICENAME, buffer, &tmp) < 0) {
   11.87 +            continue;
   11.88 +        }
   11.89 +        buffer += 4;
   11.90 +        tmp -= 4;
   11.91 +        tmp_name = buffer;
   11.92 +        for (j = 0; j < tmp; ++j) {
   11.93 +            if (*tmp_name == '#') {
   11.94 +                *tmp_name = '\\';
   11.95 +            }
   11.96 +
   11.97 +            else if (*tmp_name == '{') {
   11.98 +                break;
   11.99 +            }
  11.100 +            ++tmp_name;
  11.101 +        }
  11.102 +        *tmp_name = '\0';
  11.103 +        SDL_memcpy(key_name, reg_key_root, SDL_strlen(reg_key_root));
  11.104 +        SDL_memcpy(key_name + (SDL_strlen(reg_key_root)), buffer, j + 1);
  11.105 +        l = SDL_strlen(key_name);
  11.106 +        is_rdp = 0;
  11.107 +        if (l >= 7) {
  11.108 +            for (j = 0; j < l - 7; ++j) {
  11.109 +                for (k = 0; k < 7; ++k) {
  11.110 +                    if (rdp[k] !=
  11.111 +                        SDL_tolower((unsigned char) key_name[j + k])) {
  11.112 +                        break;
  11.113 +                    }
  11.114 +                }
  11.115 +                if (k == 7) {
  11.116 +                    is_rdp = 1;
  11.117 +                    break;
  11.118 +                }
  11.119 +            }
  11.120 +        }
  11.121 +        if (is_rdp == 1) {
  11.122 +            SDL_free(buffer);
  11.123 +            SDL_free(key_name);
  11.124 +            SDL_free(device_name);
  11.125 +            is_rdp = 0;
  11.126 +            continue;
  11.127 +        }
  11.128 +
  11.129 +        /* we're opening the registry key to get the mouse name */
  11.130 +        rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_name, 0, KEY_READ, &hkey);
  11.131 +        if (rc != ERROR_SUCCESS) {
  11.132 +            SDL_memcpy(device_name, default_device_name,
  11.133 +                       SDL_strlen(default_device_name));
  11.134 +        }
  11.135 +        rc = RegQueryValueExA(hkey, "DeviceDesc", NULL, &regtype, device_name,
  11.136 +                              &out);
  11.137 +        RegCloseKey(hkey);
  11.138 +        if (rc != ERROR_SUCCESS) {
  11.139 +            SDL_memcpy(device_name, default_device_name,
  11.140 +                       SDL_strlen(default_device_name));
  11.141 +        }
  11.142 +
  11.143 +        /* we're saving the handle to the device */
  11.144 +        mice[index] = deviceList[i].hDevice;
  11.145 +        SDL_zero(mouse);
  11.146 +        SDL_SetMouseIndexId(index, index);
  11.147 +        l = SDL_strlen(device_name);
  11.148 +
  11.149 +        /* we're checking if the device isn't by any chance a tablet */
  11.150 +        if (tablet == -1) {
  11.151 +            for (j = 0; j < l - 5; ++j) {
  11.152 +                for (k = 0; k < 5; ++k) {
  11.153 +                    if (tab[k] !=
  11.154 +                        SDL_tolower((unsigned char) device_name[j + k])) {
  11.155 +                        break;
  11.156 +                    }
  11.157 +                }
  11.158 +                if (k == 5) {
  11.159 +                    tablet = index;
  11.160 +                    break;
  11.161 +                }
  11.162 +            }
  11.163 +        }
  11.164 +
  11.165 +        /* if it's a tablet, let's read it's maximum and minimum pressure */
  11.166 +        if (tablet == index) {
  11.167 +            AXIS pressure;
  11.168 +            int cursors;
  11.169 +            WTInfo(WTI_DEVICES, DVC_NPRESSURE, &pressure);
  11.170 +            WTInfo(WTI_DEVICES, DVC_NCSRTYPES, &cursors);
  11.171 +            data->mouse =
  11.172 +                SDL_AddMouse(&mouse, index, device_name, pressure.axMax,
  11.173 +                             pressure.axMin, cursors);
  11.174 +        } else {
  11.175 +            data->mouse = SDL_AddMouse(&mouse, index, device_name, 0, 0, 1);
  11.176 +        }
  11.177 +        ++index;
  11.178 +        SDL_free(buffer);
  11.179 +        SDL_free(key_name);
  11.180 +    }
  11.181 +    total_mice = index;
  11.182 +    SDL_free(deviceList);
  11.183  }
  11.184  
  11.185  void
  11.186 @@ -40,7 +199,8 @@
  11.187  {
  11.188      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
  11.189  
  11.190 -    SDL_DelMouse(data->mouse);
  11.191 +    /* let's delete all of the mice */
  11.192 +    SDL_MouseQuit();
  11.193  }
  11.194  
  11.195  /* vi: set ts=4 sw=4 expandtab: */
    12.1 --- a/src/video/win32/SDL_win32video.c	Mon Aug 25 05:30:28 2008 +0000
    12.2 +++ b/src/video/win32/SDL_win32video.c	Mon Aug 25 06:33:00 2008 +0000
    12.3 @@ -31,10 +31,17 @@
    12.4  #include "SDL_d3drender.h"
    12.5  #include "SDL_gdirender.h"
    12.6  
    12.7 +#include <wintab.h>
    12.8 +
    12.9  /* Initialization/Query functions */
   12.10  static int WIN_VideoInit(_THIS);
   12.11  static void WIN_VideoQuit(_THIS);
   12.12  
   12.13 +int total_mice = 0;             /* total mouse count */
   12.14 +HANDLE *mice = NULL;            /* the handles to the detected mice */
   12.15 +HCTX *g_hCtx = NULL;            /* handles to tablet contexts */
   12.16 +int tablet = -1;                /* we're assuming that there is no tablet */
   12.17 +
   12.18  /* WIN32 driver bootstrap functions */
   12.19  
   12.20  static int
   12.21 @@ -140,8 +147,7 @@
   12.22  }
   12.23  
   12.24  VideoBootStrap WIN32_bootstrap = {
   12.25 -    "win32", "SDL Win32/64 video driver",
   12.26 -    WIN_Available, WIN_CreateDevice
   12.27 +    "win32", "SDL Win32/64 video driver", WIN_Available, WIN_CreateDevice
   12.28  };
   12.29  
   12.30  
   12.31 @@ -157,6 +163,7 @@
   12.32      GDI_AddRenderDriver(_this);
   12.33  #endif
   12.34  
   12.35 +    g_hCtx = SDL_malloc(sizeof(HCTX));
   12.36      WIN_InitKeyboard(_this);
   12.37      WIN_InitMouse(_this);
   12.38  
   12.39 @@ -169,6 +176,7 @@
   12.40      WIN_QuitModes(_this);
   12.41      WIN_QuitKeyboard(_this);
   12.42      WIN_QuitMouse(_this);
   12.43 +    SDL_free(g_hCtx);
   12.44  }
   12.45  
   12.46  /* vim: set ts=4 sw=4 expandtab: */
    13.1 --- a/src/video/win32/SDL_win32window.c	Mon Aug 25 05:30:28 2008 +0000
    13.2 +++ b/src/video/win32/SDL_win32window.c	Mon Aug 25 06:33:00 2008 +0000
    13.3 @@ -19,6 +19,14 @@
    13.4      Sam Lantinga
    13.5      slouken@libsdl.org
    13.6  */
    13.7 +
    13.8 +/* we need to define it, so that raw input is included */
    13.9 +
   13.10 +#if (_WIN32_WINNT < 0x0501)
   13.11 +#undef _WIN32_WINNT
   13.12 +#define _WIN32_WINNT 0x0501
   13.13 +#endif
   13.14 +
   13.15  #include "SDL_config.h"
   13.16  
   13.17  #include "../SDL_sysvideo.h"
   13.18 @@ -29,6 +37,15 @@
   13.19  /* This is included after SDL_win32video.h, which includes windows.h */
   13.20  #include "SDL_syswm.h"
   13.21  
   13.22 +#include <wintab.h>
   13.23 +
   13.24 +/* we're telling wintab that we want to receive movement, button events and pressure information in packets */
   13.25 +#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR)
   13.26 +#define PACKETMODE 0
   13.27 +#include <pktdef.h>
   13.28 +
   13.29 +extern HCTX *g_hCtx;            /* the table of tablet event contexts, each windows has to have it's own tablet context */
   13.30 +int highestId = 0;              /* the highest id of the tablet context */
   13.31  
   13.32  static int
   13.33  SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
   13.34 @@ -132,6 +149,9 @@
   13.35  int
   13.36  WIN_CreateWindow(_THIS, SDL_Window * window)
   13.37  {
   13.38 +    RAWINPUTDEVICE Rid;
   13.39 +    AXIS TabX, TabY;
   13.40 +    LOGCONTEXT lc;
   13.41      HWND hwnd;
   13.42      HWND top;
   13.43      RECT rect;
   13.44 @@ -180,13 +200,53 @@
   13.45      hwnd =
   13.46          CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
   13.47                       SDL_Instance, NULL);
   13.48 -    WIN_PumpEvents(_this);
   13.49 -
   13.50      if (!hwnd) {
   13.51          WIN_SetError("Couldn't create window");
   13.52          return -1;
   13.53      }
   13.54  
   13.55 +    /* we're configuring the tablet data. See Wintab reference for more info */
   13.56 +    if (WTInfo(WTI_DEFSYSCTX, 0, &lc) != 0) {
   13.57 +        lc.lcPktData = PACKETDATA;
   13.58 +        lc.lcPktMode = PACKETMODE;
   13.59 +        lc.lcOptions |= CXO_MESSAGES;
   13.60 +        lc.lcOptions |= CXO_SYSTEM;
   13.61 +        lc.lcMoveMask = PACKETDATA;
   13.62 +        lc.lcBtnDnMask = lc.lcBtnUpMask = PACKETDATA;
   13.63 +        WTInfo(WTI_DEVICES, DVC_X, &TabX);
   13.64 +        WTInfo(WTI_DEVICES, DVC_Y, &TabY);
   13.65 +        lc.lcInOrgX = 0;
   13.66 +        lc.lcInOrgY = 0;
   13.67 +        lc.lcInExtX = TabX.axMax;
   13.68 +        lc.lcInExtY = TabY.axMax;
   13.69 +        lc.lcOutOrgX = 0;
   13.70 +        lc.lcOutOrgY = 0;
   13.71 +        lc.lcOutExtX = GetSystemMetrics(SM_CXSCREEN);
   13.72 +        lc.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN);
   13.73 +        if (window->id > highestId) {
   13.74 +            HCTX *tmp_hctx;
   13.75 +            highestId = window->id;
   13.76 +            tmp_hctx =
   13.77 +                (HCTX *) SDL_realloc(g_hCtx, (highestId + 1) * sizeof(HCTX));
   13.78 +            if (!tmp_hctx) {
   13.79 +                SDL_OutOfMemory();
   13.80 +                DestroyWindow(hwnd);
   13.81 +                return -1;
   13.82 +            }
   13.83 +            g_hCtx = tmp_hctx;
   13.84 +        }
   13.85 +        g_hCtx[window->id] = WTOpen(hwnd, &lc, TRUE);
   13.86 +    }
   13.87 +
   13.88 +    /* we're telling the window, we want it to report raw input events from mice */
   13.89 +    Rid.usUsagePage = 0x01;
   13.90 +    Rid.usUsage = 0x02;
   13.91 +    Rid.dwFlags = RIDEV_INPUTSINK;
   13.92 +    Rid.hwndTarget = hwnd;
   13.93 +    RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
   13.94 +
   13.95 +    WIN_PumpEvents(_this);
   13.96 +
   13.97      if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) {
   13.98          DestroyWindow(hwnd);
   13.99          return -1;
  13.100 @@ -389,6 +449,7 @@
  13.101  #endif
  13.102          ReleaseDC(data->hwnd, data->hdc);
  13.103          if (data->created) {
  13.104 +            WTClose(g_hCtx[window->id]);
  13.105              DestroyWindow(data->hwnd);
  13.106          }
  13.107          SDL_free(data);
    14.1 --- a/src/video/x11/SDL_x11dyn.h	Mon Aug 25 05:30:28 2008 +0000
    14.2 +++ b/src/video/x11/SDL_x11dyn.h	Mon Aug 25 06:33:00 2008 +0000
    14.3 @@ -29,7 +29,7 @@
    14.4  #include <X11/Xatom.h>
    14.5  #include <X11/Xlibint.h>
    14.6  #include <X11/Xproto.h>
    14.7 -
    14.8 +//#include <X11/extensions/XInput.h>
    14.9  #include "../Xext/extensions/Xext.h"
   14.10  #include "../Xext/extensions/extutil.h"
   14.11  
    15.1 --- a/src/video/x11/SDL_x11events.c	Mon Aug 25 05:30:28 2008 +0000
    15.2 +++ b/src/video/x11/SDL_x11events.c	Mon Aug 25 06:33:00 2008 +0000
    15.3 @@ -29,6 +29,12 @@
    15.4  #include "SDL_x11video.h"
    15.5  #include "../../events/SDL_events_c.h"
    15.6  
    15.7 +extern int motion;              /* the motion event id defined by an XInput function */
    15.8 +extern int button_pressed;      /* the button_pressed event id defined by an XInput function */
    15.9 +extern int button_released;     /* the button_released event id defined by an XInput function */
   15.10 +extern int proximity_in;        /* the proximity in event defined by an XInput function */
   15.11 +extern int proximity_out;       /* the proximity out event defined by an XInput function */
   15.12 +
   15.13  static void
   15.14  X11_DispatchEvent(_THIS)
   15.15  {
   15.16 @@ -91,9 +97,10 @@
   15.17  #endif
   15.18              if ((xevent.xcrossing.mode != NotifyGrab) &&
   15.19                  (xevent.xcrossing.mode != NotifyUngrab)) {
   15.20 -                SDL_SetMouseFocus(videodata->mouse, data->windowID);
   15.21 -                SDL_SendMouseMotion(videodata->mouse, 0, xevent.xcrossing.x,
   15.22 -                                    xevent.xcrossing.y);
   15.23 +                XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
   15.24 +                SDL_SetMouseFocus(move->deviceid, data->windowID);
   15.25 +                SDL_SendMouseMotion(move->deviceid, 0, move->x,
   15.26 +                                    move->y, move->axis_data[2]);
   15.27              }
   15.28          }
   15.29          break;
   15.30 @@ -111,9 +118,8 @@
   15.31              if ((xevent.xcrossing.mode != NotifyGrab) &&
   15.32                  (xevent.xcrossing.mode != NotifyUngrab) &&
   15.33                  (xevent.xcrossing.detail != NotifyInferior)) {
   15.34 -                SDL_SendMouseMotion(videodata->mouse, 0,
   15.35 -                                    xevent.xcrossing.x, xevent.xcrossing.y);
   15.36 -                SDL_SetMouseFocus(videodata->mouse, 0);
   15.37 +                XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
   15.38 +                SDL_SetMouseFocus(move->deviceid, 0);
   15.39              }
   15.40          }
   15.41          break;
   15.42 @@ -166,30 +172,6 @@
   15.43          }
   15.44          break;
   15.45  
   15.46 -        /* Mouse motion? */
   15.47 -    case MotionNotify:{
   15.48 -#ifdef DEBUG_MOTION
   15.49 -            printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
   15.50 -#endif
   15.51 -            SDL_SendMouseMotion(videodata->mouse, 0, xevent.xmotion.x,
   15.52 -                                xevent.xmotion.y);
   15.53 -        }
   15.54 -        break;
   15.55 -
   15.56 -        /* Mouse button press? */
   15.57 -    case ButtonPress:{
   15.58 -            SDL_SendMouseButton(videodata->mouse, SDL_PRESSED,
   15.59 -                                xevent.xbutton.button);
   15.60 -        }
   15.61 -        break;
   15.62 -
   15.63 -        /* Mouse button release? */
   15.64 -    case ButtonRelease:{
   15.65 -            SDL_SendMouseButton(videodata->mouse, SDL_RELEASED,
   15.66 -                                xevent.xbutton.button);
   15.67 -        }
   15.68 -        break;
   15.69 -
   15.70          /* Key press? */
   15.71      case KeyPress:{
   15.72              KeyCode keycode = xevent.xkey.keycode;
   15.73 @@ -301,8 +283,44 @@
   15.74          break;
   15.75  
   15.76      default:{
   15.77 +            if (xevent.type == motion) {        /* MotionNotify */
   15.78 +#ifdef DEBUG_MOTION
   15.79 +                printf("X11 motion: %d,%d\n", xevent.xmotion.x,
   15.80 +                       xevent.xmotion.y);
   15.81 +#endif
   15.82 +                XWindowAttributes attrib;
   15.83 +                XGetWindowAttributes(videodata->display,
   15.84 +                                     ((XAnyEvent *) & xevent)->window,
   15.85 +                                     &attrib);
   15.86 +                SDL_UpdateCoordinates(attrib.width, attrib.height);
   15.87 +                XDeviceMotionEvent *move = (XDeviceMotionEvent *) & xevent;
   15.88 +                SDL_SendMouseMotion(move->deviceid, 0, move->x,
   15.89 +                                    move->y, move->axis_data[2]);
   15.90 +            } else if (xevent.type == button_pressed) { /* ButtonPress */
   15.91 +                XDeviceButtonPressedEvent *pressed =
   15.92 +                    (XDeviceButtonPressedEvent *) & xevent;
   15.93 +                SDL_SendMouseButton(pressed->deviceid, SDL_PRESSED,
   15.94 +                                    pressed->button);
   15.95 +            } else if (xevent.type == button_released) {        /* ButtonRelease */
   15.96 +                XDeviceButtonReleasedEvent *released =
   15.97 +                    (XDeviceButtonReleasedEvent *) & xevent;
   15.98 +                SDL_SendMouseButton(released->deviceid, SDL_RELEASED,
   15.99 +                                    released->button);
  15.100 +            } else if (xevent.type == proximity_in) {
  15.101 +                XProximityNotifyEvent *proximity =
  15.102 +                    (XProximityNotifyEvent *) & xevent;
  15.103 +                SDL_SendProximity(proximity->deviceid, proximity->x,
  15.104 +                                  proximity->y, SDL_PROXIMITYIN);
  15.105 +            } else if (xevent.type == proximity_out) {
  15.106 +                XProximityNotifyEvent *proximity =
  15.107 +                    (XProximityNotifyEvent *) & xevent;
  15.108 +                SDL_SendProximity(proximity->deviceid, proximity->x,
  15.109 +                                  proximity->y, SDL_PROXIMITYOUT);
  15.110 +            }
  15.111  #ifdef DEBUG_XEVENTS
  15.112 -            printf("Unhandled event %d\n", xevent.type);
  15.113 +            else {
  15.114 +                printf("Unhandled event %d\n", xevent.type);
  15.115 +            }
  15.116  #endif
  15.117          }
  15.118          break;
    16.1 --- a/src/video/x11/SDL_x11mouse.c	Mon Aug 25 05:30:28 2008 +0000
    16.2 +++ b/src/video/x11/SDL_x11mouse.c	Mon Aug 25 06:33:00 2008 +0000
    16.3 @@ -28,11 +28,70 @@
    16.4  void
    16.5  X11_InitMouse(_THIS)
    16.6  {
    16.7 +    extern XDevice **SDL_XDevices;
    16.8 +    XDevice **newDevices;
    16.9 +    int i, j, index = 0, numOfDevices;
   16.10 +    extern int SDL_NumOfXDevices;
   16.11 +    XDeviceInfo *DevList;
   16.12 +    XAnyClassPtr deviceClass;
   16.13      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   16.14 -    SDL_Mouse mouse;
   16.15  
   16.16 -    SDL_zero(mouse);
   16.17 -    data->mouse = SDL_AddMouse(&mouse, -1);
   16.18 +    /* we're getting the list of input devices */
   16.19 +    DevList = XListInputDevices(data->display, &numOfDevices);
   16.20 +    SDL_XDevices = (XDevice **) SDL_malloc(sizeof(XDevice));
   16.21 +
   16.22 +    /* we're aquiring valuators:mices, tablets, etc. */
   16.23 +    for (i = 0; i < numOfDevices; ++i) {
   16.24 +        /* if it's the core pointer or core keyborard we don't want it */
   16.25 +        if ((DevList[i].use != IsXPointer && DevList[i].use != IsXKeyboard)) {
   16.26 +            /* we have to check all of the device classes */
   16.27 +            deviceClass = DevList[i].inputclassinfo;
   16.28 +            for (j = 0; j < DevList[i].num_classes; ++j) {
   16.29 +                if (deviceClass->class == ValuatorClass) {      /* bingo ;) */
   16.30 +                    XValuatorInfo *valInfo;
   16.31 +                    SDL_Mouse mouse;
   16.32 +
   16.33 +                    newDevices =
   16.34 +                        (XDevice **) SDL_realloc(SDL_XDevices,
   16.35 +                                                 (index +
   16.36 +                                                  1) * sizeof(*newDevices));
   16.37 +                    if (!newDevices) {
   16.38 +                        SDL_OutOfMemory();
   16.39 +                        return;
   16.40 +                    }
   16.41 +                    SDL_XDevices = newDevices;
   16.42 +                    SDL_XDevices[index] =
   16.43 +                        XOpenDevice(data->display, DevList[i].id);
   16.44 +                    SDL_zero(mouse);
   16.45 +
   16.46 +                    /* the id of the device differs from its index
   16.47 +                     * so we're assigning the index of a device to it's id */
   16.48 +                    SDL_SetMouseIndexId(DevList[i].id, index);
   16.49 +                    /* lets get the device parameters */
   16.50 +                    valInfo = (XValuatorInfo *) deviceClass;
   16.51 +                    /* if the device reports pressure, lets check it parameteres */
   16.52 +                    if (valInfo->num_axes > 2) {
   16.53 +                        data->mouse =
   16.54 +                            SDL_AddMouse(&mouse, index++, DevList[i].name,
   16.55 +                                         valInfo->axes[2].max_value,
   16.56 +                                         valInfo->axes[2].min_value, 1);
   16.57 +                    } else {
   16.58 +                        data->mouse =
   16.59 +                            SDL_AddMouse(&mouse, index++, DevList[i].name, 0,
   16.60 +                                         0, 1);
   16.61 +                    }
   16.62 +                    break;
   16.63 +                }
   16.64 +                /* if it's not class we're interested in, lets go further */
   16.65 +                deviceClass =
   16.66 +                    (XAnyClassPtr) ((char *) deviceClass +
   16.67 +                                    deviceClass->length);
   16.68 +            }
   16.69 +        }
   16.70 +    }
   16.71 +    XFreeDeviceList(DevList);
   16.72 +
   16.73 +    SDL_NumOfXDevices = index;
   16.74  }
   16.75  
   16.76  void
   16.77 @@ -40,7 +99,8 @@
   16.78  {
   16.79      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   16.80  
   16.81 -    SDL_DelMouse(data->mouse);
   16.82 +    /* let's delete all of the mice */
   16.83 +    SDL_MouseQuit();
   16.84  }
   16.85  
   16.86  /* vi: set ts=4 sw=4 expandtab: */
    17.1 --- a/src/video/x11/SDL_x11sym.h	Mon Aug 25 05:30:28 2008 +0000
    17.2 +++ b/src/video/x11/SDL_x11sym.h	Mon Aug 25 06:33:00 2008 +0000
    17.3 @@ -144,6 +144,11 @@
    17.4  SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
    17.5  SDL_X11_SYM(XExtensionErrorHandler,XSetExtensionErrorHandler,(XExtensionErrorHandler a),(a),return)
    17.6  
    17.7 +/*SDL_X11_SYM(XDeviceInfo* , XListInputDevices, (Display* a, int* b), (a,b),return)
    17.8 +SDL_X11_SYM(void, XFreeDeviceList, (XDeviceInfo* a), (a),)
    17.9 +SDL_X11_SYM(int, XSelectExtensionEvent,(Display* a, Window b, XEventClass* c, int d),(a,b,c,d),return)
   17.10 +SDL_X11_SYM(XDevice* ,XOpenDevice,(Display* a, XID b), (a,b),return)*/
   17.11 +
   17.12  #if NeedWidePrototypes
   17.13  SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return)
   17.14  #else
    18.1 --- a/src/video/x11/SDL_x11video.c	Mon Aug 25 05:30:28 2008 +0000
    18.2 +++ b/src/video/x11/SDL_x11video.c	Mon Aug 25 06:33:00 2008 +0000
    18.3 @@ -27,8 +27,14 @@
    18.4  #include "../SDL_pixels_c.h"
    18.5  
    18.6  #include "SDL_x11video.h"
    18.7 -//#include "SDL_d3drender.h"
    18.8 -//#include "SDL_gdirender.h"
    18.9 +
   18.10 +XDevice **SDL_XDevices;
   18.11 +int SDL_NumOfXDevices;
   18.12 +XEventClass SDL_XEvents[256];
   18.13 +int SDL_NumOfXEvents;
   18.14 +
   18.15 +int motion, button_pressed, button_released;    /* the definitions of the mice events */
   18.16 +int proximity_in, proximity_out;
   18.17  
   18.18  /* Initialization/Query functions */
   18.19  static int X11_VideoInit(_THIS);
   18.20 @@ -97,7 +103,6 @@
   18.21  X11_DeleteDevice(SDL_VideoDevice * device)
   18.22  {
   18.23      SDL_VideoData *data = (SDL_VideoData *) device->driverdata;
   18.24 -
   18.25      if (data->display) {
   18.26          XCloseDisplay(data->display);
   18.27      }
   18.28 @@ -212,6 +217,8 @@
   18.29  int
   18.30  X11_VideoInit(_THIS)
   18.31  {
   18.32 +    int i, index = 0, event_code;
   18.33 +    XEventClass xEvent;
   18.34      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   18.35  
   18.36      /* Get the window class name, usually the name of the application */
   18.37 @@ -241,6 +248,42 @@
   18.38      }
   18.39      X11_InitMouse(_this);
   18.40  
   18.41 +    /* we're generating the table of events that should be recognized */
   18.42 +    for (i = 0; i < SDL_NumOfXDevices; ++i) {
   18.43 +        /* button events */
   18.44 +        DeviceButtonPress(SDL_XDevices[i], event_code, xEvent);
   18.45 +        if (xEvent) {
   18.46 +            SDL_XEvents[index++] = xEvent;
   18.47 +            button_pressed = event_code;
   18.48 +        }
   18.49 +        DeviceButtonRelease(SDL_XDevices[i], event_code, xEvent);
   18.50 +        if (xEvent) {
   18.51 +            SDL_XEvents[index++] = xEvent;
   18.52 +            button_released = event_code;
   18.53 +        }
   18.54 +
   18.55 +        /* proximity events */
   18.56 +        ProximityIn(SDL_XDevices[i], event_code, xEvent);
   18.57 +        if (xEvent) {
   18.58 +            SDL_XEvents[index++] = xEvent;
   18.59 +            proximity_in = event_code;
   18.60 +        }
   18.61 +        ProximityOut(SDL_XDevices[i], event_code, xEvent);
   18.62 +        if (xEvent) {
   18.63 +            SDL_XEvents[index++] = xEvent;
   18.64 +            proximity_out = event_code;
   18.65 +        }
   18.66 +
   18.67 +        /* motion events */
   18.68 +        DeviceMotionNotify(SDL_XDevices[i], event_code, xEvent);
   18.69 +        if (xEvent) {
   18.70 +            SDL_XEvents[index++] = xEvent;
   18.71 +            motion = event_code;
   18.72 +        }
   18.73 +
   18.74 +    }
   18.75 +    SDL_NumOfXEvents = index;
   18.76 +
   18.77      return 0;
   18.78  }
   18.79  
   18.80 @@ -263,6 +306,7 @@
   18.81      X11_QuitModes(_this);
   18.82      X11_QuitKeyboard(_this);
   18.83      X11_QuitMouse(_this);
   18.84 +    free(SDL_XDevices);
   18.85  }
   18.86  
   18.87  /* vim: set ts=4 sw=4 expandtab: */
    19.1 --- a/src/video/x11/SDL_x11video.h	Mon Aug 25 05:30:28 2008 +0000
    19.2 +++ b/src/video/x11/SDL_x11video.h	Mon Aug 25 06:33:00 2008 +0000
    19.3 @@ -29,6 +29,7 @@
    19.4  #include <X11/Xlib.h>
    19.5  #include <X11/Xutil.h>
    19.6  #include <X11/Xatom.h>
    19.7 +#include <X11/extensions/XInput.h>
    19.8  
    19.9  #if SDL_VIDEO_DRIVER_X11_XINERAMA
   19.10  #include "../Xext/extensions/Xinerama.h"
   19.11 @@ -68,7 +69,7 @@
   19.12      int numwindows;
   19.13      SDL_WindowData **windowlist;
   19.14      int windowlistlength;
   19.15 -    int mouse;
   19.16 +    int *mouse;
   19.17      int keyboard;
   19.18      Atom WM_DELETE_WINDOW;
   19.19      SDL_scancode key_layout[256];
    20.1 --- a/src/video/x11/SDL_x11window.c	Mon Aug 25 05:30:28 2008 +0000
    20.2 +++ b/src/video/x11/SDL_x11window.c	Mon Aug 25 06:33:00 2008 +0000
    20.3 @@ -153,6 +153,8 @@
    20.4      XSizeHints *sizehints;
    20.5      XWMHints *wmhints;
    20.6      XClassHint *classhints;
    20.7 +    extern XEventClass SDL_XEvents[];
    20.8 +    extern int SDL_NumOfXEvents;
    20.9  
   20.10  #if SDL_VIDEO_DRIVER_X11_XINERAMA
   20.11  /* FIXME
   20.12 @@ -481,6 +483,7 @@
   20.13          Uint32 fevent = 0;
   20.14          pXGetICValues(((SDL_WindowData *) window->driverdata)->ic,
   20.15                        XNFilterEvents, &fevent, NULL);
   20.16 +        XMapWindow(data->display, w);
   20.17          XSelectInput(data->display, w,
   20.18                       (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
   20.19                        ExposureMask | ButtonPressMask | ButtonReleaseMask |
   20.20 @@ -489,6 +492,7 @@
   20.21                        KeymapStateMask | fevent));
   20.22      }
   20.23  #else
   20.24 +    XMapWindow(data->display, w);
   20.25      XSelectInput(data->display, w,
   20.26                   (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
   20.27                    ExposureMask | ButtonPressMask | ButtonReleaseMask |
   20.28 @@ -497,6 +501,9 @@
   20.29                    KeymapStateMask));
   20.30  #endif
   20.31  
   20.32 +    /* we're informing the display what extension events we want to receive from it */
   20.33 +    XSelectExtensionEvent(data->display, w, SDL_XEvents, SDL_NumOfXEvents);
   20.34 +
   20.35      return 0;
   20.36  }
   20.37  
    21.1 --- a/test/testalpha.c	Mon Aug 25 05:30:28 2008 +0000
    21.2 +++ b/test/testalpha.c	Mon Aug 25 06:33:00 2008 +0000
    21.3 @@ -273,7 +273,7 @@
    21.4      if (light != NULL) {
    21.5          int x, y;
    21.6  
    21.7 -        SDL_GetMouseState(&x, &y);
    21.8 +        SDL_GetMouseState(0, &x, &y);
    21.9          FlashLight(screen, light, x, y);
   21.10      }
   21.11  
    22.1 --- a/test/testgl.c	Mon Aug 25 05:30:28 2008 +0000
    22.2 +++ b/test/testgl.c	Mon Aug 25 06:33:00 2008 +0000
    22.3 @@ -270,7 +270,7 @@
    22.4      }
    22.5  
    22.6      /* Move the image around */
    22.7 -    SDL_GetMouseState(&x, &y);
    22.8 +    SDL_GetMouseState(0, &x, &y);
    22.9      x -= w / 2;
   22.10      y -= h / 2;
   22.11