From 84388cf9bd8d9446afddf9f5369ea49aa7cd2e9f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 1 Feb 2011 19:15:42 -0800 Subject: [PATCH] Added functions to watch events as they go through the event queue. --- include/SDL_events.h | 12 +++++++++ src/events/SDL_events.c | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/include/SDL_events.h b/include/SDL_events.h index dba6c2c1d..60e0dcc96 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -580,6 +580,18 @@ extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, void **userdata); +/** + * Add a function which is called when an event is added to the queue. + */ +extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, + void *userdata); + +/** + * Remove an event watch function added with SDL_AddEventWatch() + */ +extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, + void *userdata); + /** * Run the filter function on the current event queue, removing any * events for which the filter returns 0. diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index af4af7588..e197ca59a 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -38,6 +38,14 @@ SDL_EventFilter SDL_EventOK = NULL; void *SDL_EventOKParam; +typedef struct SDL_EventWatcher { + SDL_EventFilter callback; + void *userdata; + struct SDL_EventWatcher *next; +} SDL_EventWatcher; + +static SDL_EventWatcher *SDL_event_watchers = NULL; + typedef struct { Uint32 bits[8]; } SDL_DisabledEventBlock; @@ -96,6 +104,12 @@ SDL_StopEventLoop(void) SDL_disabled_events[i] = NULL; } } + + while (SDL_event_watchers) { + SDL_EventWatcher *tmp = SDL_event_watchers; + SDL_event_watchers = tmp->next; + SDL_free(tmp); + } } /* This function (and associated calls) may be called more than once */ @@ -340,9 +354,16 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout) int SDL_PushEvent(SDL_Event * event) { + SDL_EventWatcher *curr; + if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) { return 0; } + + for (curr = SDL_event_watchers; curr; curr = curr->next) { + curr->callback(curr->userdata, event); + } + if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) { return -1; } @@ -376,6 +397,43 @@ SDL_GetEventFilter(SDL_EventFilter * filter, void **userdata) return SDL_EventOK ? SDL_TRUE : SDL_FALSE; } +/* FIXME: This is not thread-safe yet */ +void +SDL_AddEventWatch(SDL_EventFilter filter, void *userdata) +{ + SDL_EventWatcher *watcher; + + watcher = (SDL_EventWatcher *)SDL_malloc(sizeof(*watcher)); + if (!watcher) { + /* Uh oh... */ + return; + } + watcher->callback = filter; + watcher->userdata = userdata; + watcher->next = SDL_event_watchers; + SDL_event_watchers = watcher; +} + +/* FIXME: This is not thread-safe yet */ +void +SDL_DelEventWatch(SDL_EventFilter filter, void *userdata) +{ + SDL_EventWatcher *prev = NULL; + SDL_EventWatcher *curr; + + for (curr = SDL_event_watchers; curr; prev = curr, curr = curr->next) { + if (curr->callback == filter && curr->userdata == userdata) { + if (prev) { + prev->next = curr->next; + } else { + SDL_event_watchers = curr->next; + } + SDL_free(curr); + break; + } + } +} + void SDL_FilterEvents(SDL_EventFilter filter, void *userdata) {