diff options
author | Sam Lantinga <slouken@libsdl.org> | 2010-03-25 01:08:26 -0700 |
---|---|---|
committer | Sam Lantinga <slouken@libsdl.org> | 2010-03-25 01:08:26 -0700 |
commit | 1fb2a69487ef045a584046a0f21d0ef70fcb0e2f (patch) | |
tree | bf556dc2c3bd9592f03f7eb9dc3ee5ede2bcd2a5 /src | |
parent | e2adaf166abcf828b11e11a2a03e9bd79e610196 (diff) |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/SDL_compat.c | 4 | ||||
-rw-r--r-- | src/events/SDL_events.c | 168 | ||||
-rw-r--r-- | src/events/SDL_events_c.h | 3 | ||||
-rw-r--r-- | src/events/SDL_keyboard.c | 8 | ||||
-rw-r--r-- | src/events/SDL_mouse.c | 10 | ||||
-rw-r--r-- | src/events/SDL_quit.c | 2 | ||||
-rw-r--r-- | src/events/SDL_windowevents.c | 2 | ||||
-rw-r--r-- | src/joystick/SDL_joystick.c | 10 | ||||
-rw-r--r-- | src/video/win32/SDL_win32events.c | 2 | ||||
-rw-r--r-- | src/video/x11/SDL_x11events.c | 2 |
10 files changed, 138 insertions, 73 deletions
diff --git a/src/SDL_compat.c b/src/SDL_compat.c index 0319581e..a985dc35 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 7e5b1670..c361ccb6 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 33bffb6f..2f48e061 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 973f9de9..a975ae09 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 19ebadae..c9e22965 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 f92665ce..ba4c7b49 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 54fa922a..2a7a7c7d 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 d6f6090b..6a99c4bf 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 58033c39..df4a3b72 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 211aa936..598093fe 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); |