|
@@ -27,12 +27,12 @@ |
|
|
#include "SDL_events.h" |
|
|
#include "SDL_syswm.h" |
|
|
#include "SDL_thread.h" |
|
|
#include "SDL_sysevents.h" |
|
|
#include "SDL_events_c.h" |
|
|
#include "../timer/SDL_timer_c.h" |
|
|
#if !SDL_JOYSTICK_DISABLED |
|
|
#include "../joystick/SDL_joystick_c.h" |
|
|
#endif |
|
|
#include "../video/SDL_sysvideo.h" |
|
|
|
|
|
/* Public data -- the event filter */ |
|
|
SDL_EventFilter SDL_EventOK = NULL; |
|
@@ -58,36 +58,6 @@ static struct |
|
|
struct SDL_SysWMmsg wmmsg[MAXEVENTS]; |
|
|
} SDL_EventQ; |
|
|
|
|
|
/* Private data -- event locking structure */ |
|
|
static struct |
|
|
{ |
|
|
SDL_mutex *lock; |
|
|
int safe; |
|
|
} SDL_EventLock; |
|
|
|
|
|
/* Thread functions */ |
|
|
static SDL_Thread *SDL_EventThread = NULL; /* Thread handle */ |
|
|
static SDL_threadID event_thread; /* The event thread id */ |
|
|
|
|
|
void |
|
|
SDL_Lock_EventThread(void) |
|
|
{ |
|
|
if (SDL_EventThread && (SDL_ThreadID() != event_thread)) { |
|
|
/* Grab lock and spin until we're sure event thread stopped */ |
|
|
SDL_mutexP(SDL_EventLock.lock); |
|
|
while (!SDL_EventLock.safe) { |
|
|
SDL_Delay(1); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
void |
|
|
SDL_Unlock_EventThread(void) |
|
|
{ |
|
|
if (SDL_EventThread && (SDL_ThreadID() != event_thread)) { |
|
|
SDL_mutexV(SDL_EventLock.lock); |
|
|
} |
|
|
} |
|
|
|
|
|
static __inline__ SDL_bool |
|
|
SDL_ShouldPollJoystick() |
|
@@ -102,120 +72,17 @@ SDL_ShouldPollJoystick() |
|
|
return SDL_FALSE; |
|
|
} |
|
|
|
|
|
static int SDLCALL |
|
|
SDL_GobbleEvents(void *unused) |
|
|
{ |
|
|
event_thread = SDL_ThreadID(); |
|
|
|
|
|
while (SDL_EventQ.active) { |
|
|
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
|
|
|
|
|
/* Get events from the video subsystem */ |
|
|
if (_this) { |
|
|
_this->PumpEvents(_this); |
|
|
} |
|
|
#if !SDL_JOYSTICK_DISABLED |
|
|
/* Check for joystick state change */ |
|
|
if (SDL_ShouldPollJoystick()) { |
|
|
SDL_JoystickUpdate(); |
|
|
} |
|
|
#endif |
|
|
|
|
|
/* Give up the CPU for the rest of our timeslice */ |
|
|
SDL_EventLock.safe = 1; |
|
|
SDL_Delay(1); |
|
|
|
|
|
/* Check for event locking. |
|
|
On the P of the lock mutex, if the lock is held, this thread |
|
|
will wait until the lock is released before continuing. The |
|
|
safe flag will be set, meaning that the other thread can go |
|
|
about it's business. The safe flag is reset before the V, |
|
|
so as soon as the mutex is free, other threads can see that |
|
|
it's not safe to interfere with the event thread. |
|
|
*/ |
|
|
SDL_mutexP(SDL_EventLock.lock); |
|
|
SDL_EventLock.safe = 0; |
|
|
SDL_mutexV(SDL_EventLock.lock); |
|
|
} |
|
|
event_thread = 0; |
|
|
return (0); |
|
|
} |
|
|
|
|
|
static int |
|
|
SDL_StartEventThread(Uint32 flags) |
|
|
{ |
|
|
/* Reset everything to zero */ |
|
|
SDL_EventThread = NULL; |
|
|
SDL_memset(&SDL_EventLock, 0, sizeof(SDL_EventLock)); |
|
|
|
|
|
/* Create the lock and set ourselves active */ |
|
|
#if !SDL_THREADS_DISABLED |
|
|
SDL_EventQ.lock = SDL_CreateMutex(); |
|
|
if (SDL_EventQ.lock == NULL) { |
|
|
return (-1); |
|
|
} |
|
|
#endif /* !SDL_THREADS_DISABLED */ |
|
|
SDL_EventQ.active = 1; |
|
|
|
|
|
if ((flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD) { |
|
|
SDL_EventLock.lock = SDL_CreateMutex(); |
|
|
if (SDL_EventLock.lock == NULL) { |
|
|
return (-1); |
|
|
} |
|
|
SDL_EventLock.safe = 0; |
|
|
|
|
|
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC) |
|
|
#undef SDL_CreateThread |
|
|
SDL_EventThread = |
|
|
SDL_CreateThread(SDL_GobbleEvents, NULL, NULL, NULL); |
|
|
#else |
|
|
SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL); |
|
|
#endif |
|
|
if (SDL_EventThread == NULL) { |
|
|
return (-1); |
|
|
} |
|
|
} else { |
|
|
event_thread = 0; |
|
|
} |
|
|
return (0); |
|
|
} |
|
|
|
|
|
static void |
|
|
SDL_StopEventThread(void) |
|
|
{ |
|
|
SDL_EventQ.active = 0; |
|
|
if (SDL_EventThread) { |
|
|
SDL_WaitThread(SDL_EventThread, NULL); |
|
|
SDL_EventThread = NULL; |
|
|
SDL_DestroyMutex(SDL_EventLock.lock); |
|
|
SDL_EventLock.lock = NULL; |
|
|
} |
|
|
if (SDL_EventQ.lock) { |
|
|
SDL_DestroyMutex(SDL_EventQ.lock); |
|
|
SDL_EventQ.lock = NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
SDL_threadID |
|
|
SDL_EventThreadID(void) |
|
|
{ |
|
|
return (event_thread); |
|
|
} |
|
|
|
|
|
/* Public functions */ |
|
|
|
|
|
void |
|
|
SDL_StopEventLoop(void) |
|
|
{ |
|
|
int i; |
|
|
|
|
|
/* Halt the event thread, if running */ |
|
|
SDL_StopEventThread(); |
|
|
|
|
|
/* Shutdown event handlers */ |
|
|
SDL_KeyboardQuit(); |
|
|
SDL_MouseQuit(); |
|
|
SDL_QuitQuit(); |
|
|
if (SDL_EventQ.lock) { |
|
|
SDL_DestroyMutex(SDL_EventQ.lock); |
|
|
SDL_EventQ.lock = NULL; |
|
|
} |
|
|
|
|
|
/* Clean out EventQ */ |
|
|
SDL_EventQ.head = 0; |
|
@@ -233,35 +100,27 @@ SDL_StopEventLoop(void) |
|
|
|
|
|
/* This function (and associated calls) may be called more than once */ |
|
|
int |
|
|
SDL_StartEventLoop(Uint32 flags) |
|
|
SDL_StartEventLoop(void) |
|
|
{ |
|
|
int retcode; |
|
|
|
|
|
/* Clean out the event queue */ |
|
|
SDL_EventThread = NULL; |
|
|
SDL_EventQ.lock = NULL; |
|
|
SDL_StopEventLoop(); |
|
|
|
|
|
/* No filter to start with, process most event types */ |
|
|
SDL_EventOK = NULL; |
|
|
SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE); |
|
|
|
|
|
/* Initialize event handlers */ |
|
|
retcode = 0; |
|
|
retcode += SDL_KeyboardInit(); |
|
|
retcode += SDL_MouseInit(); |
|
|
retcode += SDL_TouchInit(); |
|
|
retcode += SDL_QuitInit(); |
|
|
if (retcode < 0) { |
|
|
/* We don't expect them to fail, but... */ |
|
|
/* Create the lock and set ourselves active */ |
|
|
#if !SDL_THREADS_DISABLED |
|
|
SDL_EventQ.lock = SDL_CreateMutex(); |
|
|
if (SDL_EventQ.lock == NULL) { |
|
|
return (-1); |
|
|
} |
|
|
#endif /* !SDL_THREADS_DISABLED */ |
|
|
SDL_EventQ.active = 1; |
|
|
|
|
|
/* Create the lock and event thread */ |
|
|
if (SDL_StartEventThread(flags) < 0) { |
|
|
SDL_StopEventLoop(); |
|
|
return (-1); |
|
|
} |
|
|
return (0); |
|
|
} |
|
|
|
|
@@ -420,20 +279,18 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType) |
|
|
void |
|
|
SDL_PumpEvents(void) |
|
|
{ |
|
|
if (!SDL_EventThread) { |
|
|
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
|
|
SDL_VideoDevice *_this = SDL_GetVideoDevice(); |
|
|
|
|
|
/* Get events from the video subsystem */ |
|
|
if (_this) { |
|
|
_this->PumpEvents(_this); |
|
|
} |
|
|
/* Get events from the video subsystem */ |
|
|
if (_this) { |
|
|
_this->PumpEvents(_this); |
|
|
} |
|
|
#if !SDL_JOYSTICK_DISABLED |
|
|
/* Check for joystick state change */ |
|
|
if (SDL_ShouldPollJoystick()) { |
|
|
SDL_JoystickUpdate(); |
|
|
} |
|
|
#endif |
|
|
/* Check for joystick state change */ |
|
|
if (SDL_ShouldPollJoystick()) { |
|
|
SDL_JoystickUpdate(); |
|
|
} |
|
|
#endif |
|
|
} |
|
|
|
|
|
/* Public functions */ |
|
|