summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Lantinga <slouken@libsdl.org>2010-03-25 01:08:26 -0700
committerSam Lantinga <slouken@libsdl.org>2010-03-25 01:08:26 -0700
commit1fb2a69487ef045a584046a0f21d0ef70fcb0e2f (patch)
treebf556dc2c3bd9592f03f7eb9dc3ee5ede2bcd2a5 /src
parente2adaf166abcf828b11e11a2a03e9bd79e610196 (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.c4
-rw-r--r--src/events/SDL_events.c168
-rw-r--r--src/events/SDL_events_c.h3
-rw-r--r--src/events/SDL_keyboard.c8
-rw-r--r--src/events/SDL_mouse.c10
-rw-r--r--src/events/SDL_quit.c2
-rw-r--r--src/events/SDL_windowevents.c2
-rw-r--r--src/joystick/SDL_joystick.c10
-rw-r--r--src/video/win32/SDL_win32events.c2
-rw-r--r--src/video/x11/SDL_x11events.c2
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);