From d1032fa54858f37f41bf258b4c888cbadd8b384a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 25 Mar 2010 01:08:26 -0700 Subject: [PATCH] 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 | 34 +++- include/SDL_events.h | 262 ++++++++++++++++-------------- src/SDL_compat.c | 4 +- src/events/SDL_events.c | 168 +++++++++++++------ src/events/SDL_events_c.h | 3 - src/events/SDL_keyboard.c | 8 +- src/events/SDL_mouse.c | 10 +- src/events/SDL_quit.c | 2 +- src/events/SDL_windowevents.c | 2 +- src/joystick/SDL_joystick.c | 10 +- src/video/win32/SDL_win32events.c | 2 +- src/video/x11/SDL_x11events.c | 2 +- test/threadwin.c | 12 +- 13 files changed, 312 insertions(+), 207 deletions(-) diff --git a/include/SDL_compat.h b/include/SDL_compat.h index 558fbf093..3b7a7acf7 100644 --- a/include/SDL_compat.h +++ b/include/SDL_compat.h @@ -91,12 +91,34 @@ extern "C" { #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 diff --git a/include/SDL_events.h b/include/SDL_events.h index f2cfbd760..640b0096b 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -54,83 +54,67 @@ extern "C" { */ 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_WindowEvent */ 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_KeyboardEvent */ 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_TextEditingEvent */ 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_TextInputEvent */ 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_MouseMotionEvent */ 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_MouseButtonEvent */ 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_JoyAxisEvent */ 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_JoyBallEvent */ 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 @@ typedef struct SDL_JoyHatEvent * * Note that zero means the POV is centered. */ + Uint8 padding1; } SDL_JoyHatEvent; /** @@ -264,10 +280,11 @@ typedef struct SDL_JoyHatEvent */ 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_JoyButtonEvent */ typedef struct SDL_QuitEvent { - Uint8 type; /**< ::SDL_QUIT */ + Uint32 type; /**< ::SDL_QUIT */ } SDL_QuitEvent; /** @@ -283,11 +300,11 @@ typedef struct SDL_QuitEvent */ 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_SysWMmsg SDL_SysWMmsg; */ 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_ProximityEvent /*@{*/ 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 struct SDL_ResizeEvent */ 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 @@ typedef enum */ 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 @@ extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, * - 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 diff --git a/src/SDL_compat.c b/src/SDL_compat.c index 0319581e2..a985dc35f 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -196,13 +196,13 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event) 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; diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 7e5b1670c..c361ccb61 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -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 @@ SDL_Unlock_EventThread(void) } } +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 @@ SDL_GobbleEvents(void *unused) } #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 @@ SDL_EventThreadID(void) void SDL_StopEventLoop(void) { + int i; + /* Halt the event thread, if running */ SDL_StopEventThread(); @@ -207,6 +225,14 @@ SDL_StopEventLoop(void) 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 @@ SDL_StartEventLoop(Uint32 flags) /* 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 @@ SDL_CutEvent(int spot) /* 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 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, } 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_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, } 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, mask) > 0); + return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0); +} + +void +SDL_FlushEvent(Uint32 type) +{ + 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 @@ SDL_PumpEvents(void) } #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 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout) 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 @@ SDL_PushEvent(SDL_Event * event) 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 @@ SDL_FilterEvents(SDL_EventFilter filter, void *userdata) } 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)); + if (SDL_disabled_events[hi] && + (SDL_disabled_events[hi]->bits[lo/32] & (1 << (lo&31)))) { + current_state = SDL_DISABLE; + } else { + current_state = SDL_ENABLE; + } + + 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); - return (current_state); } - /* 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)); - } - while (SDL_PollEvent(&bitbucket) > 0); - break; - default: - /* Querying state? */ - break; + 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 (current_state); + return event_base; } /* This is a generic event handler. @@ -528,7 +596,7 @@ SDL_SendSysWMEvent(SDL_SysWMmsg * message) 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; diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 33bffb6f0..2f48e0614 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -47,7 +47,4 @@ extern void SDL_QuitQuit(void); 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: */ diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 973f9de9a..a975ae098 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -688,7 +688,7 @@ SDL_SendKeyboardKey(int index, Uint8 state, SDL_scancode scancode) SDL_Keyboard *keyboard = SDL_GetKeyboard(index); int posted; Uint16 modstate; - Uint8 type; + Uint32 type; if (!keyboard || !scancode) { return 0; @@ -800,7 +800,7 @@ SDL_SendKeyboardKey(int index, Uint8 state, SDL_scancode scancode) /* 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 @@ SDL_SendKeyboardText(int index, const char *text) /* 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 @@ SDL_SendEditingText(const char *text, int start, int length) /* 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; diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 19ebadaea..c9e229654 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -365,7 +365,7 @@ SDL_SendProximity(int id, int x, int y, int type) 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 @@ SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure) /* 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 @@ SDL_SendMouseButton(int id, Uint8 state, Uint8 button) 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 @@ SDL_SendMouseButton(int id, Uint8 state, Uint8 button) /* 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 @@ SDL_SendMouseWheel(int index, int x, int y) /* 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; diff --git a/src/events/SDL_quit.c b/src/events/SDL_quit.c index f92665cee..ba4c7b49f 100644 --- a/src/events/SDL_quit.c +++ b/src/events/SDL_quit.c @@ -85,7 +85,7 @@ SDL_SendQuit(void) 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); diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c index 54fa922a3..2a7a7c7db 100644 --- a/src/events/SDL_windowevents.c +++ b/src/events/SDL_windowevents.c @@ -144,7 +144,7 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, /* 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; diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index d6f6090bf..6a99c4bf9 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -445,7 +445,7 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) /* 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 @@ SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value) /* 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 @@ SDL_PrivateJoystickBall(SDL_Joystick * joystick, Uint8 ball, /* 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 @@ SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state) /* 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 @@ SDL_JoystickEventState(int state) #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, }; diff --git a/src/video/win32/SDL_win32events.c b/src/video/win32/SDL_win32events.c index 58033c39c..df4a3b722 100644 --- a/src/video/win32/SDL_win32events.c +++ b/src/video/win32/SDL_win32events.c @@ -109,7 +109,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 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); diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 211aa9364..598093fed 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -53,7 +53,7 @@ X11_DispatchEvent(_THIS) } /* 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); diff --git a/test/threadwin.c b/test/threadwin.c index 0e356ba72..dfd1c3c9c 100644 --- a/test/threadwin.c +++ b/test/threadwin.c @@ -133,14 +133,10 @@ HandleMouse(void *unused) { 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 @@ HandleKeyboard(void *unused) { 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 @@ main(int argc, char *argv[]) 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 */