Added functions to watch events as they go through the event queue.
authorSam Lantinga <slouken@libsdl.org>
Tue, 01 Feb 2011 19:15:42 -0800
changeset 5146 3052772b59db
parent 5145 2f44e6969a59
child 5147 ad50b3db78bd
Added functions to watch events as they go through the event queue.
include/SDL_events.h
src/events/SDL_events.c
--- a/include/SDL_events.h	Tue Feb 01 15:02:21 2011 -0800
+++ b/include/SDL_events.h	Tue Feb 01 19:15:42 2011 -0800
@@ -581,6 +581,18 @@
                                                     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.
  */
--- a/src/events/SDL_events.c	Tue Feb 01 15:02:21 2011 -0800
+++ b/src/events/SDL_events.c	Tue Feb 01 19:15:42 2011 -0800
@@ -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_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 @@
 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 @@
     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)
 {