General improvements for user custom event registration
authorSam Lantinga <slouken@libsdl.org>
Thu, 25 Mar 2010 01:08:26 -0700
changeset 4429 faa9fc8e7f67
parent 4428 68dfd6df47da
child 4432 77ebcd41b577
General improvements for user custom event registration * Switched event type to enum (int32) * Switched polling by mask to polling by type range * Added SDL_RegisterEvents() to allow dynamic user event registration * Spread events out to allow inserting new related events without breaking binary compatibility * Added padding to event structures so they're the same size regardless of 32-bit compiler structure packing settings * Split SDL_HasEvent() to SDL_HasEvent() for a single event and SDL_HasEvents() for a range of events * Added SDL_GetEventState() as a shortcut for SDL_EventState(X, SDL_QUERY) * Added SDL_FlushEvent() and SDL_FlushEvents() to clear events from the event queue
include/SDL_compat.h
include/SDL_events.h
src/SDL_compat.c
src/events/SDL_events.c
src/events/SDL_events_c.h
src/events/SDL_keyboard.c
src/events/SDL_mouse.c
src/events/SDL_quit.c
src/events/SDL_windowevents.c
src/joystick/SDL_joystick.c
src/video/win32/SDL_win32events.c
src/video/x11/SDL_x11events.c
test/threadwin.c
--- a/include/SDL_compat.h	Wed Mar 10 15:07:20 2010 +0000
+++ b/include/SDL_compat.h	Thu Mar 25 01:08:26 2010 -0700
@@ -91,12 +91,34 @@
 #define SDL_LOGPAL 0x01
 #define SDL_PHYSPAL 0x02
 
-#define SDL_ACTIVEEVENT	SDL_EVENT_RESERVED1
-#define SDL_VIDEORESIZE	SDL_EVENT_RESERVED2
-#define SDL_VIDEOEXPOSE	SDL_EVENT_RESERVED3
-#define SDL_ACTIVEEVENTMASK	SDL_EVENTMASK(SDL_ACTIVEEVENT)
-#define SDL_VIDEORESIZEMASK SDL_EVENTMASK(SDL_VIDEORESIZE)
-#define SDL_VIDEOEXPOSEMASK SDL_EVENTMASK(SDL_VIDEOEXPOSE)
+#define SDL_ACTIVEEVENT	SDL_EVENT_COMPAT1
+#define SDL_VIDEORESIZE	SDL_EVENT_COMPAT2
+#define SDL_VIDEOEXPOSE	SDL_EVENT_COMPAT3
+#define SDL_ACTIVEEVENTMASK	SDL_ACTIVEEVENT, SDL_ACTIVEEVENT
+#define SDL_VIDEORESIZEMASK SDL_VIDEORESIZE, SDL_VIDEORESIZE
+#define SDL_VIDEOEXPOSEMASK SDL_VIDEOEXPOSE, SDL_VIDEOEXPOSE
+#define SDL_WINDOWEVENTMASK SDL_WINDOWEVENT, SDL_WINDOWEVENT
+#define SDL_KEYDOWNMASK SDL_KEYDOWN, SDL_KEYDOWN
+#define SDL_KEYUPMASK SDL_KEYUP, SDL_KEYUP
+#define SDL_KEYEVENTMASK SDL_KEYDOWN, SDL_KEYUP
+#define SDL_TEXTEDITINGMASK SDL_TEXTEDITING, SDL_TEXTEDITING
+#define SDL_TEXTINPUTMASK SDL_TEXTINPUT, SDL_TEXTINPUT
+#define SDL_MOUSEMOTIONMASK SDL_MOUSEMOTION, SDL_MOUSEMOTION
+#define SDL_MOUSEBUTTONDOWNMASK SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN
+#define SDL_MOUSEBUTTONUPMASK SDL_MOUSEBUTTONUP, SDL_MOUSEBUTTONUP
+#define SDL_MOUSEWHEELMASK SDL_MOUSEWHEEL, SDL_MOUSEWHEEL
+#define SDL_MOUSEEVENTMASK SDL_MOUSEMOTION, SDL_MOUSEBUTTONUP
+#define SDL_JOYAXISMOTIONMASK SDL_JOYAXISMOTION, SDL_JOYAXISMOTION
+#define SDL_JOYBALLMOTIONMASK SDL_JOYBALLMOTION, SDL_JOYBALLMOTION
+#define SDL_JOYHATMOTIONMASK SDL_JOYHATMOTION, SDL_JOYHATMOTION
+#define SDL_JOYBUTTONDOWNMASK SDL_JOYBUTTONDOWN, SDL_JOYBUTTONDOWN
+#define SDL_JOYBUTTONUPMASK SDL_JOYBUTTONUP, SDL_JOYBUTTONUP
+#define SDL_JOYEVENTMASK SDL_JOYAXISMOTION, SDL_JOYBUTTONUP
+#define SDL_QUITMASK SDL_QUIT, SDL_QUIT
+#define SDL_SYSWMEVENTMASK SDL_SYSWMEVENT, SDL_SYSWMEVENT
+#define SDL_PROXIMITYINMASK SDL_PROXIMITYIN, SDL_PROXIMITYIN
+#define SDL_PROXIMITYOUTMASK SDL_PROXIMITYOUT, SDL_PROXIMITYOUT
+#define SDL_ALLEVENTS SDL_FIRSTEVENT, SDL_LASTEVENT
 
 #define SDL_BUTTON_WHEELUP	4
 #define SDL_BUTTON_WHEELDOWN	5
--- a/include/SDL_events.h	Wed Mar 10 15:07:20 2010 +0000
+++ b/include/SDL_events.h	Thu Mar 25 01:08:26 2010 -0700
@@ -54,83 +54,67 @@
  */
 typedef enum
 {
-    SDL_NOEVENT = 0,            /**< Unused (do not remove) */
-    SDL_WINDOWEVENT,            /**< Window state change */
-    SDL_KEYDOWN,                /**< Keys pressed */
+    SDL_FIRSTEVENT     = 0,     /**< Unused (do not remove) */
+
+    /* Application events */
+    SDL_QUIT           = 0x100, /**< User-requested quit */
+
+    /* Window events */
+    SDL_WINDOWEVENT    = 0x200, /**< Window state change */
+    SDL_SYSWMEVENT,             /**< System specific event */
+
+    /* Keyboard events */
+    SDL_KEYDOWN        = 0x300, /**< Keys pressed */
     SDL_KEYUP,                  /**< Keys released */
     SDL_TEXTEDITING,            /**< Keyboard text editing (composition) */
     SDL_TEXTINPUT,              /**< Keyboard text input */
-    SDL_MOUSEMOTION,            /**< Mouse moved */
+
+    /* Mouse events */
+    SDL_MOUSEMOTION    = 0x400, /**< Mouse moved */
     SDL_MOUSEBUTTONDOWN,        /**< Mouse button pressed */
     SDL_MOUSEBUTTONUP,          /**< Mouse button released */
     SDL_MOUSEWHEEL,             /**< Mouse wheel motion */
-    SDL_JOYAXISMOTION,          /**< Joystick axis motion */
+
+    /* Tablet events */
+    SDL_PROXIMITYIN    = 0x500, /**< Proximity In event */
+    SDL_PROXIMITYOUT,           /**< Proximity Out event */
+
+    /* Joystick events */
+    SDL_JOYAXISMOTION  = 0x600, /**< Joystick axis motion */
     SDL_JOYBALLMOTION,          /**< Joystick trackball motion */
     SDL_JOYHATMOTION,           /**< Joystick hat position change */
     SDL_JOYBUTTONDOWN,          /**< Joystick button pressed */
     SDL_JOYBUTTONUP,            /**< Joystick button released */
-    SDL_QUIT,                   /**< User-requested quit */
-    SDL_SYSWMEVENT,             /**< System specific event */
-    SDL_PROXIMITYIN,            /**< Proximity In event */
-    SDL_PROXIMITYOUT,           /**< Proximity Out event */
-    SDL_EVENT_RESERVED1,        /**< Reserved for future use... */
-    SDL_EVENT_RESERVED2,        /**< Reserved for future use... */
-    SDL_EVENT_RESERVED3,        /**< Reserved for future use... */
-    /** Events ::SDL_USEREVENT through ::SDL_MAXEVENTS-1 are for your use */
-    SDL_USEREVENT = 24,
+
+    /* Obsolete events */
+    SDL_EVENT_COMPAT1 = 0x7000, /**< SDL 1.2 events for compatibility */
+    SDL_EVENT_COMPAT2,
+    SDL_EVENT_COMPAT3,
+
+    /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
+     *  and should be allocated with SDL_RegisterEvents()
+     */
+    SDL_USEREVENT    = 0x8000,
+
     /**
      *  This last event is only for bounding internal arrays
-     *  It is the number of bits in the event mask datatype -- Uint32
      */
-    SDL_NUMEVENTS = 32
+    SDL_LASTEVENT    = 0xFFFF
 } SDL_EventType;
 
-/*@{*/
-#define SDL_EVENTMASK(X)	(1<<(X))
-/**
- * \brief Predefined event masks
- */
-typedef enum
-{
-    SDL_WINDOWEVENTMASK = SDL_EVENTMASK(SDL_WINDOWEVENT),
-    SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN),
-    SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP),
-    SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN) | SDL_EVENTMASK(SDL_KEYUP),
-    SDL_TEXTEDITINGMASK = SDL_EVENTMASK(SDL_TEXTEDITING),
-    SDL_TEXTINPUTMASK = SDL_EVENTMASK(SDL_TEXTINPUT),
-    SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION),
-    SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN),
-    SDL_MOUSEBUTTONUPMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONUP),
-    SDL_MOUSEWHEELMASK = SDL_EVENTMASK(SDL_MOUSEWHEEL),
-    SDL_MOUSEEVENTMASK = SDL_EVENTMASK(SDL_MOUSEMOTION) |
-        SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN) | SDL_EVENTMASK(SDL_MOUSEBUTTONUP),
-    SDL_JOYAXISMOTIONMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION),
-    SDL_JOYBALLMOTIONMASK = SDL_EVENTMASK(SDL_JOYBALLMOTION),
-    SDL_JOYHATMOTIONMASK = SDL_EVENTMASK(SDL_JOYHATMOTION),
-    SDL_JOYBUTTONDOWNMASK = SDL_EVENTMASK(SDL_JOYBUTTONDOWN),
-    SDL_JOYBUTTONUPMASK = SDL_EVENTMASK(SDL_JOYBUTTONUP),
-    SDL_JOYEVENTMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION) |
-        SDL_EVENTMASK(SDL_JOYBALLMOTION) |
-        SDL_EVENTMASK(SDL_JOYHATMOTION) |
-        SDL_EVENTMASK(SDL_JOYBUTTONDOWN) | SDL_EVENTMASK(SDL_JOYBUTTONUP),
-    SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT),
-    SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT),
-    SDL_PROXIMITYINMASK = SDL_EVENTMASK(SDL_PROXIMITYIN),
-    SDL_PROXIMITYOUTMASK = SDL_EVENTMASK(SDL_PROXIMITYOUT)
-} SDL_EventMask;
-#define SDL_ALLEVENTS		0xFFFFFFFF
-/*@}*/
-
 /**
  *  \brief Window state change event data (event.window.*)
  */
 typedef struct SDL_WindowEvent
 {
-    Uint8 type;             /**< ::SDL_WINDOWEVENT */
-    Uint32 windowID;        /**< The associated window */
-    Uint8 event;            /**< ::SDL_WindowEventID */
-    int data1;              /**< event dependent data */
-    int data2;              /**< event dependent data */
+    Uint32 type;        /**< ::SDL_WINDOWEVENT */
+    Uint32 windowID;    /**< The associated window */
+    Uint8 event;        /**< ::SDL_WindowEventID */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    int data1;          /**< event dependent data */
+    int data2;          /**< event dependent data */
 } SDL_WindowEvent;
 
 /**
@@ -138,11 +122,13 @@
  */
 typedef struct SDL_KeyboardEvent
 {
-    Uint8 type;             /**< ::SDL_KEYDOWN or ::SDL_KEYUP */
-    Uint32 windowID;        /**< The window with keyboard focus, if any */
-    Uint8 which;            /**< The keyboard device index */
-    Uint8 state;            /**< ::SDL_PRESSED or ::SDL_RELEASED */
-    SDL_keysym keysym;      /**< The key that was pressed or released */
+    Uint32 type;        /**< ::SDL_KEYDOWN or ::SDL_KEYUP */
+    Uint32 windowID;    /**< The window with keyboard focus, if any */
+    Uint8 which;        /**< The keyboard device index */
+    Uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
+    Uint8 padding1;
+    Uint8 padding2;
+    SDL_keysym keysym;  /**< The key that was pressed or released */
 } SDL_KeyboardEvent;
 
 #define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32)
@@ -151,7 +137,7 @@
  */
 typedef struct SDL_TextEditingEvent
 {
-    Uint8 type;                                 /**< ::SDL_TEXTEDITING */
+    Uint32 type;                                /**< ::SDL_TEXTEDITING */
     char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE];  /**< The editing text */
     int start;                                  /**< The start cursor of selected editing text */
     int length;                                 /**< The length of selected editing text */
@@ -164,9 +150,12 @@
  */
 typedef struct SDL_TextInputEvent
 {
-    Uint8 type;                               /**< ::SDL_TEXTINPUT */
+    Uint32 type;                              /**< ::SDL_TEXTINPUT */
     Uint32 windowID;                          /**< The window with keyboard focus, if any */
     Uint8 which;                              /**< The keyboard device index */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
     char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];  /**< The input text */
 } SDL_TextInputEvent;
 
@@ -175,22 +164,24 @@
  */
 typedef struct SDL_MouseMotionEvent
 {
-    Uint8 type;             /**< ::SDL_MOUSEMOTION */
-    Uint32 windowID;        /**< The window with mouse focus, if any */
-    Uint8 which;            /**< The mouse device index */
-    Uint8 state;            /**< The current button state */
-    int x;                  /**< X coordinate, relative to window */
-    int y;                  /**< Y coordinate, relative to window */
-    int z;                  /**< Z coordinate, for future use */
-    int pressure;           /**< Pressure reported by tablets */
-    int pressure_max;       /**< Maximum value of the pressure reported by the device */
-    int pressure_min;       /**< Minimum value of the pressure reported by the device */
-    int rotation;           /**< For future use */
-    int tilt_x;             /**< For future use */
-    int tilt_y;             /**< For future use */
-    int cursor;             /**< The cursor being used in the event */
-    int xrel;               /**< The relative motion in the X direction */
-    int yrel;               /**< The relative motion in the Y direction */
+    Uint32 type;        /**< ::SDL_MOUSEMOTION */
+    Uint32 windowID;    /**< The window with mouse focus, if any */
+    Uint8 which;        /**< The mouse device index */
+    Uint8 state;        /**< The current button state */
+    Uint8 padding1;
+    Uint8 padding2;
+    int x;              /**< X coordinate, relative to window */
+    int y;              /**< Y coordinate, relative to window */
+    int z;              /**< Z coordinate, for future use */
+    int pressure;       /**< Pressure reported by tablets */
+    int pressure_max;   /**< Maximum value of the pressure reported by the device */
+    int pressure_min;   /**< Minimum value of the pressure reported by the device */
+    int rotation;       /**< For future use */
+    int tilt_x;         /**< For future use */
+    int tilt_y;         /**< For future use */
+    int cursor;         /**< The cursor being used in the event */
+    int xrel;           /**< The relative motion in the X direction */
+    int yrel;           /**< The relative motion in the Y direction */
 } SDL_MouseMotionEvent;
 
 /**
@@ -198,13 +189,14 @@
  */
 typedef struct SDL_MouseButtonEvent
 {
-    Uint8 type;             /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */
-    Uint32 windowID;        /**< The window with mouse focus, if any */
-    Uint8 which;            /**< The mouse device index */
-    Uint8 button;           /**< The mouse button index */
-    Uint8 state;            /**< ::SDL_PRESSED or ::SDL_RELEASED */
-    int x;                  /**< X coordinate, relative to window */
-    int y;                  /**< Y coordinate, relative to window */
+    Uint32 type;        /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */
+    Uint32 windowID;    /**< The window with mouse focus, if any */
+    Uint8 which;        /**< The mouse device index */
+    Uint8 button;       /**< The mouse button index */
+    Uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
+    Uint8 padding1;
+    int x;              /**< X coordinate, relative to window */
+    int y;              /**< Y coordinate, relative to window */
 } SDL_MouseButtonEvent;
 
 /**
@@ -212,21 +204,42 @@
  */
 typedef struct SDL_MouseWheelEvent
 {
-    Uint8 type;             /**< ::SDL_MOUSEWHEEL */
-    Uint32 windowID;        /**< The window with mouse focus, if any */
-    Uint8 which;            /**< The mouse device index */
-    int x;                  /**< The amount scrolled horizontally */
-    int y;                  /**< The amount scrolled vertically */
+    Uint32 type;        /**< ::SDL_MOUSEWHEEL */
+    Uint32 windowID;    /**< The window with mouse focus, if any */
+    Uint8 which;        /**< The mouse device index */
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    int x;              /**< The amount scrolled horizontally */
+    int y;              /**< The amount scrolled vertically */
 } SDL_MouseWheelEvent;
 
 /**
+ * \brief Tablet pen proximity event
+ */
+typedef struct SDL_ProximityEvent
+{
+    Uint32 type;        /**< ::SDL_PROXIMITYIN or ::SDL_PROXIMITYOUT */
+    Uint32 windowID;    /**< The associated window */
+    Uint8 which;
+    Uint8 padding1;
+    Uint8 padding2;
+    Uint8 padding3;
+    int cursor;
+    int x;
+    int y;
+} SDL_ProximityEvent;
+
+/**
  *  \brief Joystick axis motion event structure (event.jaxis.*)
  */
 typedef struct SDL_JoyAxisEvent
 {
-    Uint8 type;         /**< ::SDL_JOYAXISMOTION */
+    Uint32 type;        /**< ::SDL_JOYAXISMOTION */
     Uint8 which;        /**< The joystick device index */
     Uint8 axis;         /**< The joystick axis index */
+    Uint8 padding1;
+    Uint8 padding2;
     int value;          /**< The axis value (range: -32768 to 32767) */
 } SDL_JoyAxisEvent;
 
@@ -235,9 +248,11 @@
  */
 typedef struct SDL_JoyBallEvent
 {
-    Uint8 type;         /**< ::SDL_JOYBALLMOTION */
+    Uint32 type;        /**< ::SDL_JOYBALLMOTION */
     Uint8 which;        /**< The joystick device index */
     Uint8 ball;         /**< The joystick trackball index */
+    Uint8 padding1;
+    Uint8 padding2;
     int xrel;           /**< The relative motion in the X direction */
     int yrel;           /**< The relative motion in the Y direction */
 } SDL_JoyBallEvent;
@@ -247,7 +262,7 @@
  */
 typedef struct SDL_JoyHatEvent
 {
-    Uint8 type;         /**< ::SDL_JOYHATMOTION */
+    Uint32 type;        /**< ::SDL_JOYHATMOTION */
     Uint8 which;        /**< The joystick device index */
     Uint8 hat;          /**< The joystick hat index */
     Uint8 value;        /**< The hat position value.
@@ -257,6 +272,7 @@
                          *   
                          *   Note that zero means the POV is centered.
                          */
+    Uint8 padding1;
 } SDL_JoyHatEvent;
 
 /**
@@ -264,10 +280,11 @@
  */
 typedef struct SDL_JoyButtonEvent
 {
-    Uint8 type;         /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */
+    Uint32 type;        /**< ::SDL_JOYBUTTONDOWN or ::SDL_JOYBUTTONUP */
     Uint8 which;        /**< The joystick device index */
     Uint8 button;       /**< The joystick button index */
     Uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
+    Uint8 padding1;
 } SDL_JoyButtonEvent;
 
 /**
@@ -275,7 +292,7 @@
  */
 typedef struct SDL_QuitEvent
 {
-    Uint8 type;         /**< ::SDL_QUIT */
+    Uint32 type;        /**< ::SDL_QUIT */
 } SDL_QuitEvent;
 
 /**
@@ -283,11 +300,11 @@
  */
 typedef struct SDL_UserEvent
 {
-    Uint8 type;             /**< ::SDL_USEREVENT through ::SDL_NUMEVENTS-1 */
-    Uint32 windowID;        /**< The associated window if any*/
-    int code;               /**< User defined event code */
-    void *data1;            /**< User defined data pointer */
-    void *data2;            /**< User defined data pointer */
+    Uint32 type;        /**< ::SDL_USEREVENT through ::SDL_NUMEVENTS-1 */
+    Uint32 windowID;    /**< The associated window if any */
+    int code;           /**< User defined event code */
+    void *data1;        /**< User defined data pointer */
+    void *data2;        /**< User defined data pointer */
 } SDL_UserEvent;
 
 struct SDL_SysWMmsg;
@@ -300,20 +317,10 @@
  */
 typedef struct SDL_SysWMEvent
 {
-    Uint8 type;         /**< ::SDL_SYSWMEVENT */
+    Uint32 type;        /**< ::SDL_SYSWMEVENT */
     SDL_SysWMmsg *msg;  /**< driver dependent data, defined in SDL_syswm.h */
 } SDL_SysWMEvent;
 
-typedef struct SDL_ProximityEvent
-{
-    Uint8 type;
-    Uint32 windowID;    /**< The associated window */
-    Uint8 which;
-    int cursor;
-    int x;
-    int y;
-} SDL_ProximityEvent;
-
 #ifndef SDL_NO_COMPAT
 /**
  *  \addtogroup Compatibility 
@@ -326,14 +333,14 @@
 /*@{*/
 typedef struct SDL_ActiveEvent
 {
-    Uint8 type;
+    Uint32 type;
     Uint8 gain;
     Uint8 state;
 } SDL_ActiveEvent;
 
 typedef struct SDL_ResizeEvent
 {
-    Uint8 type;
+    Uint32 type;
     int w;
     int h;
 } SDL_ResizeEvent;
@@ -347,7 +354,7 @@
  */
 typedef union SDL_Event
 {
-    Uint8 type;                     /**< Event type, shared with all events */
+    Uint32 type;                    /**< Event type, shared with all events */
     SDL_WindowEvent window;         /**< Window event data */
     SDL_KeyboardEvent key;          /**< Keyboard event data */
     SDL_TextEditingEvent edit;      /**< Text editing event data */
@@ -413,13 +420,20 @@
  */
 extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents,
                                            SDL_eventaction action,
-                                           Uint32 mask);
+                                           Uint32 minType, Uint32 maxType);
 /*@}*/
 
 /**
  *  Checks to see if certain event types are in the event queue.
  */
-extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 mask);
+extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type);
+extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType);
+
+/**
+ *  This function clears events from the event queue
+ */
+extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type);
+extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType);
 
 /**
  *  \brief Polls for currently pending events.
@@ -520,8 +534,18 @@
  *   - If \c state is set to ::SDL_QUERY, SDL_EventState() will return the 
  *     current processing state of the specified event.
  */
-extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint8 type, int state);
+extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state);
 /*@}*/
+#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY)
+
+/**
+ *  This function allocates a set of user-defined events, and returns
+ *  the beginning event number for that set of events.
+ *
+ *  If there aren't enough user-defined events left, this function
+ *  returns (Uint32)-1
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
--- a/src/SDL_compat.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/SDL_compat.c	Thu Mar 25 01:08:26 2010 -0700
@@ -196,13 +196,13 @@
     case SDL_WINDOWEVENT:
         switch (event->window.event) {
         case SDL_WINDOWEVENT_EXPOSED:
-            if (!SDL_HasEvent(SDL_VIDEOEXPOSEMASK)) {
+            if (!SDL_HasEvent(SDL_VIDEOEXPOSE)) {
                 fake.type = SDL_VIDEOEXPOSE;
                 SDL_PushEvent(&fake);
             }
             break;
         case SDL_WINDOWEVENT_RESIZED:
-            SDL_PeepEvents(&fake, 1, SDL_GETEVENT, SDL_VIDEORESIZEMASK);
+            SDL_FlushEvent(SDL_VIDEORESIZE);
             fake.type = SDL_VIDEORESIZE;
             fake.resize.w = event->window.data1;
             fake.resize.h = event->window.data2;
--- a/src/events/SDL_events.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/events/SDL_events.c	Thu Mar 25 01:08:26 2010 -0700
@@ -37,8 +37,13 @@
 /* Public data -- the event filter */
 SDL_EventFilter SDL_EventOK = NULL;
 void *SDL_EventOKParam;
-Uint8 SDL_ProcessEvents[SDL_NUMEVENTS];
-static Uint32 SDL_eventstate = 0;
+
+typedef struct {
+    Uint32 bits[8];
+} SDL_DisabledEventBlock;
+
+static SDL_DisabledEventBlock *SDL_disabled_events[256];
+static Uint32 SDL_userevents = SDL_USEREVENT;
 
 /* Private data -- event queue */
 #define MAXEVENTS	128
@@ -84,6 +89,17 @@
     }
 }
 
+static __inline__ SDL_bool
+SDL_ShouldPollJoystick()
+{
+    if (SDL_numjoysticks &&
+        (!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] ||
+         SDL_JoystickEventState(SDL_QUERY))) {
+        return SDL_TRUE;
+    }
+    return SDL_FALSE;
+}
+
 static int SDLCALL
 SDL_GobbleEvents(void *unused)
 {
@@ -98,7 +114,7 @@
         }
 #if !SDL_JOYSTICK_DISABLED
         /* Check for joystick state change */
-        if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) {
+        if (SDL_ShouldPollJoystick()) {
             SDL_JoystickUpdate();
         }
 #endif
@@ -195,6 +211,8 @@
 void
 SDL_StopEventLoop(void)
 {
+    int i;
+
     /* Halt the event thread, if running */
     SDL_StopEventThread();
 
@@ -207,6 +225,14 @@
     SDL_EventQ.head = 0;
     SDL_EventQ.tail = 0;
     SDL_EventQ.wmmsg_next = 0;
+
+    /* Clear disabled event state */
+    for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
+        if (SDL_disabled_events[i]) {
+            SDL_free(SDL_disabled_events[i]);
+            SDL_disabled_events[i] = NULL;
+        }
+    }
 }
 
 /* This function (and associated calls) may be called more than once */
@@ -222,11 +248,7 @@
 
     /* No filter to start with, process most event types */
     SDL_EventOK = NULL;
-    SDL_memset(SDL_ProcessEvents, SDL_ENABLE, sizeof(SDL_ProcessEvents));
-    SDL_eventstate = ~0;
-    /* It's not save to call SDL_EventState() yet */
-    SDL_eventstate &= ~(0x00000001 << SDL_SYSWMEVENT);
-    SDL_ProcessEvents[SDL_SYSWMEVENT] = SDL_IGNORE;
+    SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
 
     /* Initialize event handlers */
     retcode = 0;
@@ -305,7 +327,7 @@
 /* Lock the event queue, take a peep at it, and unlock it */
 int
 SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
-               Uint32 mask)
+               Uint32 minType, Uint32 maxType)
 {
     int i, used;
 
@@ -332,7 +354,8 @@
             }
             spot = SDL_EventQ.head;
             while ((used < numevents) && (spot != SDL_EventQ.tail)) {
-                if (mask & SDL_EVENTMASK(SDL_EventQ.event[spot].type)) {
+                Uint32 type = SDL_EventQ.event[spot].type;
+                if (minType <= type && type <= maxType) {
                     events[used++] = SDL_EventQ.event[spot];
                     if (action == SDL_GETEVENT) {
                         spot = SDL_CutEvent(spot);
@@ -353,9 +376,44 @@
 }
 
 SDL_bool
-SDL_HasEvent(Uint32 mask)
+SDL_HasEvent(Uint32 type)
+{
+    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0);
+}
+
+SDL_bool
+SDL_HasEvents(Uint32 minType, Uint32 maxType)
+{
+    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0);
+}
+
+void
+SDL_FlushEvent(Uint32 type)
 {
-    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask) > 0);
+    SDL_FlushEvents(type, type);
+}
+
+void
+SDL_FlushEvents(Uint32 minType, Uint32 maxType)
+{
+    /* Don't look after we've quit */
+    if (!SDL_EventQ.active) {
+        return;
+    }
+
+    /* Lock the event queue */
+    if (SDL_mutexP(SDL_EventQ.lock) == 0) {
+        int spot = SDL_EventQ.head;
+        while (spot != SDL_EventQ.tail) {
+            Uint32 type = SDL_EventQ.event[spot].type;
+            if (minType <= type && type <= maxType) {
+                spot = SDL_CutEvent(spot);
+            } else {
+                spot = (spot + 1) % MAXEVENTS;
+            }
+        }
+        SDL_mutexV(SDL_EventQ.lock);
+    }
 }
 
 /* Run the system dependent event loops */
@@ -371,7 +429,7 @@
         }
 #if !SDL_JOYSTICK_DISABLED
         /* Check for joystick state change */
-        if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) {
+        if (SDL_ShouldPollJoystick()) {
             SDL_JoystickUpdate();
         }
 #endif
@@ -402,7 +460,7 @@
 
     for (;;) {
         SDL_PumpEvents();
-        switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
+        switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
         case -1:
             return 0;
         case 1:
@@ -428,7 +486,7 @@
     if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) {
         return 0;
     }
-    if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0) <= 0) {
+    if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
         return -1;
     }
     return 1;
@@ -476,48 +534,58 @@
 }
 
 Uint8
-SDL_EventState(Uint8 type, int state)
+SDL_EventState(Uint32 type, int state)
 {
-    SDL_Event bitbucket;
     Uint8 current_state;
+    Uint8 hi = ((type >> 8) & 0xff);
+    Uint8 lo = (type & 0xff);
 
-    /* If SDL_ALLEVENTS was specified... */
-    if (type == 0xFF) {
-        current_state = SDL_IGNORE;
-        for (type = 0; type < SDL_NUMEVENTS; ++type) {
-            if (SDL_ProcessEvents[type] != SDL_IGNORE) {
-                current_state = SDL_ENABLE;
-            }
-            SDL_ProcessEvents[type] = state;
-            if (state == SDL_ENABLE) {
-                SDL_eventstate |= (0x00000001 << (type));
-            } else {
-                SDL_eventstate &= ~(0x00000001 << (type));
-            }
-        }
-        while (SDL_PollEvent(&bitbucket) > 0);
-        return (current_state);
+    if (SDL_disabled_events[hi] &&
+        (SDL_disabled_events[hi]->bits[lo/32] & (1 << (lo&31)))) {
+        current_state = SDL_DISABLE;
+    } else {
+        current_state = SDL_ENABLE;
     }
 
-    /* Just set the state for one event type */
-    current_state = SDL_ProcessEvents[type];
-    switch (state) {
-    case SDL_IGNORE:
-    case SDL_ENABLE:
-        /* Set state and discard pending events */
-        SDL_ProcessEvents[type] = state;
-        if (state == SDL_ENABLE) {
-            SDL_eventstate |= (0x00000001 << (type));
-        } else {
-            SDL_eventstate &= ~(0x00000001 << (type));
+    if (state != current_state)
+    {
+        switch (state) {
+        case SDL_DISABLE:
+            /* Disable this event type and discard pending events */
+            if (!SDL_disabled_events[hi]) {
+                SDL_disabled_events[hi] = (SDL_DisabledEventBlock*) SDL_calloc(1, sizeof(SDL_DisabledEventBlock));
+                if (!SDL_disabled_events[hi]) {
+                    /* Out of memory, nothing we can do... */
+                    break;
+                }
+            }
+            SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
+            SDL_FlushEvent(type);
+            break;
+        case SDL_ENABLE:
+            SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
+            break;
+        default:
+            /* Querying state... */
+            break;
         }
-        while (SDL_PollEvent(&bitbucket) > 0);
-        break;
-    default:
-        /* Querying state? */
-        break;
     }
-    return (current_state);
+
+    return current_state;
+}
+
+Uint32
+SDL_RegisterEvents(int numevents)
+{
+    Uint32 event_base;
+
+    if (SDL_userevents+numevents <= SDL_LASTEVENT) {
+        event_base = SDL_userevents;
+        SDL_userevents += numevents;
+    } else {
+        event_base = (Uint32)-1;
+    }
+    return event_base;
 }
 
 /* This is a generic event handler.
@@ -528,7 +596,7 @@
     int posted;
 
     posted = 0;
-    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
         SDL_Event event;
         SDL_memset(&event, 0, sizeof(event));
         event.type = SDL_SYSWMEVENT;
--- a/src/events/SDL_events_c.h	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/events/SDL_events_c.h	Thu Mar 25 01:08:26 2010 -0700
@@ -47,7 +47,4 @@
 extern SDL_EventFilter SDL_EventOK;
 extern void *SDL_EventOKParam;
 
-/* The array of event processing states */
-extern Uint8 SDL_ProcessEvents[SDL_NUMEVENTS];
-
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/events/SDL_keyboard.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/events/SDL_keyboard.c	Thu Mar 25 01:08:26 2010 -0700
@@ -688,7 +688,7 @@
     SDL_Keyboard *keyboard = SDL_GetKeyboard(index);
     int posted;
     Uint16 modstate;
-    Uint8 type;
+    Uint32 type;
 
     if (!keyboard || !scancode) {
         return 0;
@@ -800,7 +800,7 @@
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
+    if (SDL_GetEventState(type) == SDL_ENABLE) {
         SDL_Event event;
         event.key.type = type;
         event.key.which = (Uint8) index;
@@ -827,7 +827,7 @@
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[SDL_TEXTINPUT] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) {
         SDL_Event event;
         event.text.type = SDL_TEXTINPUT;
         event.text.which = (Uint8) index;
@@ -845,7 +845,7 @@
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[SDL_TEXTEDITING] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_TEXTEDITING) == SDL_ENABLE) {
         SDL_Event event;
         event.edit.type = SDL_TEXTEDITING;
         event.edit.start = start;
--- a/src/events/SDL_mouse.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/events/SDL_mouse.c	Thu Mar 25 01:08:26 2010 -0700
@@ -365,7 +365,7 @@
 
     mouse->last_x = x;
     mouse->last_y = y;
-    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
+    if (SDL_GetEventState(type) == SDL_ENABLE) {
         SDL_Event event;
         event.proximity.which = (Uint8) index;
         event.proximity.x = x;
@@ -461,7 +461,7 @@
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE &&
+    if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE &&
         mouse->proximity == SDL_TRUE) {
         SDL_Event event;
         event.motion.type = SDL_MOUSEMOTION;
@@ -493,7 +493,7 @@
     int index = SDL_GetMouseIndexId(id);
     SDL_Mouse *mouse = SDL_GetMouse(index);
     int posted;
-    Uint8 type;
+    Uint32 type;
 
     if (!mouse) {
         return 0;
@@ -524,7 +524,7 @@
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
+    if (SDL_GetEventState(type) == SDL_ENABLE) {
         SDL_Event event;
         event.type = type;
         event.button.which = (Uint8) index;
@@ -550,7 +550,7 @@
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_MOUSEWHEEL;
         event.wheel.which = (Uint8) index;
--- a/src/events/SDL_quit.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/events/SDL_quit.c	Thu Mar 25 01:08:26 2010 -0700
@@ -85,7 +85,7 @@
     int posted;
 
     posted = 0;
-    if (SDL_ProcessEvents[SDL_QUIT] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_QUIT) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_QUIT;
         posted = (SDL_PushEvent(&event) > 0);
--- a/src/events/SDL_windowevents.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/events/SDL_windowevents.c	Thu Mar 25 01:08:26 2010 -0700
@@ -144,7 +144,7 @@
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_ProcessEvents[SDL_WINDOWEVENT] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_WINDOWEVENT;
         event.window.event = windowevent;
--- a/src/joystick/SDL_joystick.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/joystick/SDL_joystick.c	Thu Mar 25 01:08:26 2010 -0700
@@ -445,7 +445,7 @@
     /* Post the event, if desired */
     posted = 0;
 #if !SDL_EVENTS_DISABLED
-    if (SDL_ProcessEvents[SDL_JOYAXISMOTION] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) {
         SDL_Event event;
         event.type = SDL_JOYAXISMOTION;
         event.jaxis.which = joystick->index;
@@ -472,7 +472,7 @@
     /* Post the event, if desired */
     posted = 0;
 #if !SDL_EVENTS_DISABLED
-    if (SDL_ProcessEvents[SDL_JOYHATMOTION] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_JOYHATMOTION) == SDL_ENABLE) {
         SDL_Event event;
         event.jhat.type = SDL_JOYHATMOTION;
         event.jhat.which = joystick->index;
@@ -501,7 +501,7 @@
     /* Post the event, if desired */
     posted = 0;
 #if !SDL_EVENTS_DISABLED
-    if (SDL_ProcessEvents[SDL_JOYBALLMOTION] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_JOYBALLMOTION) == SDL_ENABLE) {
         SDL_Event event;
         event.jball.type = SDL_JOYBALLMOTION;
         event.jball.which = joystick->index;
@@ -544,7 +544,7 @@
     /* Post the event, if desired */
     posted = 0;
 #if !SDL_EVENTS_DISABLED
-    if (SDL_ProcessEvents[event.type] == SDL_ENABLE) {
+    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
         event.jbutton.which = joystick->index;
         event.jbutton.button = button;
         event.jbutton.state = state;
@@ -574,7 +574,7 @@
 #if SDL_EVENTS_DISABLED
     return SDL_IGNORE;
 #else
-    const Uint8 event_list[] = {
+    const Uint32 event_list[] = {
         SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION,
         SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP,
     };
--- a/src/video/win32/SDL_win32events.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/video/win32/SDL_win32events.c	Thu Mar 25 01:08:26 2010 -0700
@@ -109,7 +109,7 @@
     LRESULT returnCode = -1;
 
     /* Send a SDL_SYSWMEVENT if the application wants them */
-    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
         SDL_SysWMmsg wmmsg;
 
         SDL_VERSION(&wmmsg.version);
--- a/src/video/x11/SDL_x11events.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/src/video/x11/SDL_x11events.c	Thu Mar 25 01:08:26 2010 -0700
@@ -53,7 +53,7 @@
     }
 
     /* Send a SDL_SYSWMEVENT if the application wants them */
-    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
+    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
         SDL_SysWMmsg wmmsg;
 
         SDL_VERSION(&wmmsg.version);
--- a/test/threadwin.c	Wed Mar 10 15:07:20 2010 +0000
+++ b/test/threadwin.c	Thu Mar 25 01:08:26 2010 -0700
@@ -133,14 +133,10 @@
 {
     SDL_Event events[10];
     int i, found;
-    Uint32 mask;
 
     /* Handle mouse events here */
-    mask =
-        (SDL_MOUSEMOTIONMASK | SDL_MOUSEBUTTONDOWNMASK |
-         SDL_MOUSEBUTTONUPMASK);
     while (!done) {
-        found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
+        found = SDL_PeepEvents(events, 10, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEBUTTONUP);
         for (i = 0; i < found; ++i) {
             switch (events[i].type) {
                 /* We want to toggle visibility on buttonpress */
@@ -173,12 +169,10 @@
 {
     SDL_Event events[10];
     int i, found;
-    Uint32 mask;
 
     /* Handle mouse events here */
-    mask = (SDL_KEYDOWNMASK | SDL_KEYUPMASK);
     while (!done) {
-        found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
+        found = SDL_PeepEvents(events, 10, SDL_GETEVENT, SDL_KEYDOWN, SDL_KEYUP);
         for (i = 0; i < found; ++i) {
             switch (events[i].type) {
                 /* We want to toggle visibility on buttonpress */
@@ -329,7 +323,7 @@
         if (!(init_flags & SDL_INIT_EVENTTHREAD)) {
             SDL_PumpEvents();   /* Needed when event thread is off */
         }
-        if (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK)) {
+        if (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUIT, SDL_QUIT)) {
             done = 1;
         }
         /* Give up some CPU so the events can accumulate */