mirror of
https://github.com/Ryujinx/SDL.git
synced 2025-01-22 14:01:02 +00:00
Added support for clang thread-safety analysis
The annotations have been added to SDL_mutex.h and have been made public so applications can enable this for their own code. Clang assumes that locking and unlocking can't fail, but SDL has the concept of a NULL mutex, so the mutex functions have been changed not to report errors if a mutex hasn't been initialized. We do have mutexes that might be accessed when they are NULL, notably in the event system, so this is an important change. This commit cleans up a bunch of rare race conditions in the joystick and game controller code so now everything should be completely protected by the joystick lock. To test this, change the compiler to "clang -Wthread-safety -Werror=thread-safety -DSDL_THREAD_SAFETY_ANALYSIS"
This commit is contained in:
parent
582fb3901a
commit
d59caffe2c
|
@ -44,6 +44,7 @@
|
||||||
#include "SDL_stdinc.h"
|
#include "SDL_stdinc.h"
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
#include "SDL_guid.h"
|
#include "SDL_guid.h"
|
||||||
|
#include "SDL_mutex.h"
|
||||||
|
|
||||||
#include "begin_code.h"
|
#include "begin_code.h"
|
||||||
/* Set up for C function definitions, even when using C++ */
|
/* Set up for C function definitions, even when using C++ */
|
||||||
|
@ -66,6 +67,9 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
* The joystick structure used to identify an SDL joystick
|
* The joystick structure used to identify an SDL joystick
|
||||||
*/
|
*/
|
||||||
|
#ifdef SDL_THREAD_SAFETY_ANALYSIS
|
||||||
|
extern SDL_mutex *SDL_joystick_lock;
|
||||||
|
#endif
|
||||||
struct _SDL_Joystick;
|
struct _SDL_Joystick;
|
||||||
typedef struct _SDL_Joystick SDL_Joystick;
|
typedef struct _SDL_Joystick SDL_Joystick;
|
||||||
|
|
||||||
|
@ -131,7 +135,7 @@ typedef enum
|
||||||
*
|
*
|
||||||
* \since This function is available since SDL 2.0.7.
|
* \since This function is available since SDL 2.0.7.
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC void SDLCALL SDL_LockJoysticks(void);
|
extern DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,7 +150,7 @@ extern DECLSPEC void SDLCALL SDL_LockJoysticks(void);
|
||||||
*
|
*
|
||||||
* \since This function is available since SDL 2.0.7.
|
* \since This function is available since SDL 2.0.7.
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void);
|
extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count the number of joysticks attached to the system.
|
* Count the number of joysticks attached to the system.
|
||||||
|
|
|
@ -31,6 +31,80 @@
|
||||||
#include "SDL_stdinc.h"
|
#include "SDL_stdinc.h"
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* Enable thread safety attributes only with clang.
|
||||||
|
* The attributes can be safely erased when compiling with other compilers.
|
||||||
|
*/
|
||||||
|
#if defined(SDL_THREAD_SAFETY_ANALYSIS) && \
|
||||||
|
defined(__clang__) && (!defined(SWIG))
|
||||||
|
#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
||||||
|
#else
|
||||||
|
#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SDL_CAPABILITY(x) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
|
||||||
|
|
||||||
|
#define SDL_SCOPED_CAPABILITY \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
|
||||||
|
|
||||||
|
#define SDL_GUARDED_BY(x) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
|
||||||
|
|
||||||
|
#define SDL_PT_GUARDED_BY(x) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
|
||||||
|
|
||||||
|
#define SDL_ACQUIRED_BEFORE(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_ACQUIRED_AFTER(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_REQUIRES(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_REQUIRES_SHARED(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_ACQUIRE(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_ACQUIRE_SHARED(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_RELEASE(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_RELEASE_SHARED(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_RELEASE_GENERIC(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_TRY_ACQUIRE(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_TRY_ACQUIRE_SHARED(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_EXCLUDES(...) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SDL_ASSERT_CAPABILITY(x) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
|
||||||
|
|
||||||
|
#define SDL_ASSERT_SHARED_CAPABILITY(x) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
|
||||||
|
|
||||||
|
#define SDL_RETURN_CAPABILITY(x) \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
|
||||||
|
|
||||||
|
#define SDL_NO_THREAD_SAFETY_ANALYSIS \
|
||||||
|
SDL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "begin_code.h"
|
#include "begin_code.h"
|
||||||
/* Set up for C function definitions, even when using C++ */
|
/* Set up for C function definitions, even when using C++ */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -96,7 +170,7 @@ extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void);
|
||||||
*
|
*
|
||||||
* \since This function is available since SDL 2.0.0.
|
* \since This function is available since SDL 2.0.0.
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex);
|
extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex) SDL_ACQUIRE(mutex);
|
||||||
#define SDL_mutexP(m) SDL_LockMutex(m)
|
#define SDL_mutexP(m) SDL_LockMutex(m)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,7 +193,7 @@ extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex);
|
||||||
* \sa SDL_LockMutex
|
* \sa SDL_LockMutex
|
||||||
* \sa SDL_UnlockMutex
|
* \sa SDL_UnlockMutex
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex);
|
extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex) SDL_TRY_ACQUIRE(0, mutex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlock the mutex.
|
* Unlock the mutex.
|
||||||
|
@ -138,7 +212,7 @@ extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex);
|
||||||
*
|
*
|
||||||
* \since This function is available since SDL 2.0.0.
|
* \since This function is available since SDL 2.0.0.
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex);
|
extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex) SDL_RELEASE(mutex);
|
||||||
#define SDL_mutexV(m) SDL_UnlockMutex(m)
|
#define SDL_mutexV(m) SDL_UnlockMutex(m)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -345,10 +345,8 @@ SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file,
|
||||||
}
|
}
|
||||||
SDL_AtomicUnlock(&spinlock);
|
SDL_AtomicUnlock(&spinlock);
|
||||||
|
|
||||||
if (SDL_LockMutex(assertion_mutex) < 0) {
|
SDL_LockMutex(assertion_mutex);
|
||||||
return SDL_ASSERTION_IGNORE; /* oh well, I guess. */
|
#endif /* !SDL_THREADS_DISABLED */
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* doing this because Visual C is upset over assigning in the macro. */
|
/* doing this because Visual C is upset over assigning in the macro. */
|
||||||
if (data->trigger_count == 0) {
|
if (data->trigger_count == 0) {
|
||||||
|
|
|
@ -336,15 +336,9 @@ void SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_function_mutex) {
|
|
||||||
SDL_LockMutex(log_function_mutex);
|
SDL_LockMutex(log_function_mutex);
|
||||||
}
|
|
||||||
|
|
||||||
SDL_log_function(SDL_log_userdata, category, priority, message);
|
SDL_log_function(SDL_log_userdata, category, priority, message);
|
||||||
|
|
||||||
if (log_function_mutex) {
|
|
||||||
SDL_UnlockMutex(log_function_mutex);
|
SDL_UnlockMutex(log_function_mutex);
|
||||||
}
|
|
||||||
|
|
||||||
/* Free only if dynamically allocated */
|
/* Free only if dynamically allocated */
|
||||||
if (message != stack_buf) {
|
if (message != stack_buf) {
|
||||||
|
|
|
@ -301,14 +301,14 @@ static SDL_INLINE SDL_bool is_in_audio_device_thread(SDL_AudioDevice *device)
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioLockDevice_Default(SDL_AudioDevice *device)
|
static void SDL_AudioLockDevice_Default(SDL_AudioDevice *device) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang assumes recursive locks */
|
||||||
{
|
{
|
||||||
if (!is_in_audio_device_thread(device)) {
|
if (!is_in_audio_device_thread(device)) {
|
||||||
SDL_LockMutex(device->mixer_lock);
|
SDL_LockMutex(device->mixer_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SDL_AudioUnlockDevice_Default(SDL_AudioDevice *device)
|
static void SDL_AudioUnlockDevice_Default(SDL_AudioDevice *device) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang assumes recursive locks */
|
||||||
{
|
{
|
||||||
if (!is_in_audio_device_thread(device)) {
|
if (!is_in_audio_device_thread(device)) {
|
||||||
SDL_UnlockMutex(device->mixer_lock);
|
SDL_UnlockMutex(device->mixer_lock);
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
#define SDL_DYNAMIC_API 0
|
#define SDL_DYNAMIC_API 0
|
||||||
#elif defined(__riscos__) && __riscos__ /* probably not useful on RISC OS, since dlopen() can't be used when using static linking. */
|
#elif defined(__riscos__) && __riscos__ /* probably not useful on RISC OS, since dlopen() can't be used when using static linking. */
|
||||||
#define SDL_DYNAMIC_API 0
|
#define SDL_DYNAMIC_API 0
|
||||||
#elif defined(__clang_analyzer__)
|
#elif defined(__clang_analyzer__) || defined(SDL_THREAD_SAFETY_ANALYSIS)
|
||||||
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
|
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
|
||||||
#elif defined(__VITA__)
|
#elif defined(__VITA__)
|
||||||
#define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */
|
#define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */
|
||||||
|
|
|
@ -546,9 +546,7 @@ void SDL_StopEventLoop(void)
|
||||||
SDL_EventEntry *entry;
|
SDL_EventEntry *entry;
|
||||||
SDL_SysWMEntry *wmmsg;
|
SDL_SysWMEntry *wmmsg;
|
||||||
|
|
||||||
if (SDL_EventQ.lock) {
|
|
||||||
SDL_LockMutex(SDL_EventQ.lock);
|
SDL_LockMutex(SDL_EventQ.lock);
|
||||||
}
|
|
||||||
|
|
||||||
SDL_EventQ.active = SDL_FALSE;
|
SDL_EventQ.active = SDL_FALSE;
|
||||||
|
|
||||||
|
@ -605,8 +603,9 @@ void SDL_StopEventLoop(void)
|
||||||
}
|
}
|
||||||
SDL_zero(SDL_EventOK);
|
SDL_zero(SDL_EventOK);
|
||||||
|
|
||||||
if (SDL_EventQ.lock) {
|
|
||||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||||
|
|
||||||
|
if (SDL_EventQ.lock) {
|
||||||
SDL_DestroyMutex(SDL_EventQ.lock);
|
SDL_DestroyMutex(SDL_EventQ.lock);
|
||||||
SDL_EventQ.lock = NULL;
|
SDL_EventQ.lock = NULL;
|
||||||
}
|
}
|
||||||
|
@ -650,9 +649,7 @@ int SDL_StartEventLoop(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_EventQ.active = SDL_TRUE;
|
SDL_EventQ.active = SDL_TRUE;
|
||||||
if (SDL_EventQ.lock) {
|
|
||||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,17 +743,18 @@ static int SDL_SendWakeupEvent()
|
||||||
if (_this == NULL || !_this->SendWakeupEvent) {
|
if (_this == NULL || !_this->SendWakeupEvent) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
|
|
||||||
|
SDL_LockMutex(_this->wakeup_lock);
|
||||||
|
{
|
||||||
if (_this->wakeup_window) {
|
if (_this->wakeup_window) {
|
||||||
_this->SendWakeupEvent(_this, _this->wakeup_window);
|
_this->SendWakeupEvent(_this, _this->wakeup_window);
|
||||||
|
|
||||||
/* No more wakeup events needed until we enter a new wait */
|
/* No more wakeup events needed until we enter a new wait */
|
||||||
_this->wakeup_window = NULL;
|
_this->wakeup_window = NULL;
|
||||||
}
|
}
|
||||||
if (_this->wakeup_lock) {
|
}
|
||||||
SDL_UnlockMutex(_this->wakeup_lock);
|
SDL_UnlockMutex(_this->wakeup_lock);
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,16 +766,16 @@ static int SDL_PeepEventsInternal(SDL_Event *events, int numevents, SDL_eventact
|
||||||
|
|
||||||
/* Lock the event queue */
|
/* Lock the event queue */
|
||||||
used = 0;
|
used = 0;
|
||||||
if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
|
|
||||||
|
SDL_LockMutex(SDL_EventQ.lock);
|
||||||
|
{
|
||||||
/* Don't look after we've quit */
|
/* Don't look after we've quit */
|
||||||
if (!SDL_EventQ.active) {
|
if (!SDL_EventQ.active) {
|
||||||
if (SDL_EventQ.lock) {
|
|
||||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
|
||||||
}
|
|
||||||
/* We get a few spurious events at shutdown, so don't warn then */
|
/* We get a few spurious events at shutdown, so don't warn then */
|
||||||
if (action == SDL_GETEVENT) {
|
if (action == SDL_GETEVENT) {
|
||||||
SDL_SetError("The event system has been shut down");
|
SDL_SetError("The event system has been shut down");
|
||||||
}
|
}
|
||||||
|
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (action == SDL_ADDEVENT) {
|
if (action == SDL_ADDEVENT) {
|
||||||
|
@ -846,12 +844,8 @@ static int SDL_PeepEventsInternal(SDL_Event *events, int numevents, SDL_eventact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SDL_EventQ.lock) {
|
}
|
||||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return SDL_SetError("Couldn't lock event queue");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (used > 0 && action == SDL_ADDEVENT) {
|
if (used > 0 && action == SDL_ADDEVENT) {
|
||||||
SDL_SendWakeupEvent();
|
SDL_SendWakeupEvent();
|
||||||
|
@ -865,14 +859,12 @@ int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action,
|
||||||
return SDL_PeepEventsInternal(events, numevents, action, minType, maxType, SDL_FALSE);
|
return SDL_PeepEventsInternal(events, numevents, action, minType, maxType, SDL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
SDL_bool SDL_HasEvent(Uint32 type)
|
||||||
SDL_HasEvent(Uint32 type)
|
|
||||||
{
|
{
|
||||||
return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0;
|
return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool
|
SDL_bool SDL_HasEvents(Uint32 minType, Uint32 maxType)
|
||||||
SDL_HasEvents(Uint32 minType, Uint32 maxType)
|
|
||||||
{
|
{
|
||||||
return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0;
|
return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0;
|
||||||
}
|
}
|
||||||
|
@ -899,12 +891,11 @@ void SDL_FlushEvents(Uint32 minType, Uint32 maxType)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Lock the event queue */
|
/* Lock the event queue */
|
||||||
if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
|
SDL_LockMutex(SDL_EventQ.lock);
|
||||||
|
{
|
||||||
/* Don't look after we've quit */
|
/* Don't look after we've quit */
|
||||||
if (!SDL_EventQ.active) {
|
if (!SDL_EventQ.active) {
|
||||||
if (SDL_EventQ.lock) {
|
|
||||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (entry = SDL_EventQ.head; entry; entry = next) {
|
for (entry = SDL_EventQ.head; entry; entry = next) {
|
||||||
|
@ -914,11 +905,9 @@ void SDL_FlushEvents(Uint32 minType, Uint32 maxType)
|
||||||
SDL_CutEvent(entry);
|
SDL_CutEvent(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SDL_EventQ.lock) {
|
}
|
||||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run the system dependent event loops */
|
/* Run the system dependent event loops */
|
||||||
static void SDL_PumpEventsInternal(SDL_bool push_sentinel)
|
static void SDL_PumpEventsInternal(SDL_bool push_sentinel)
|
||||||
|
@ -1002,20 +991,22 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve
|
||||||
/* We only want a single sentinel in the queue. We could get more than one if event is NULL,
|
/* We only want a single sentinel in the queue. We could get more than one if event is NULL,
|
||||||
* since the SDL_PeepEvents() call below won't remove it in that case.
|
* since the SDL_PeepEvents() call below won't remove it in that case.
|
||||||
*/
|
*/
|
||||||
|
int status;
|
||||||
SDL_bool add_sentinel = (SDL_AtomicGet(&SDL_sentinel_pending) == 0) ? SDL_TRUE : SDL_FALSE;
|
SDL_bool add_sentinel = (SDL_AtomicGet(&SDL_sentinel_pending) == 0) ? SDL_TRUE : SDL_FALSE;
|
||||||
SDL_PumpEventsInternal(add_sentinel);
|
SDL_PumpEventsInternal(add_sentinel);
|
||||||
|
|
||||||
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
|
SDL_LockMutex(_this->wakeup_lock);
|
||||||
int status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
|
{
|
||||||
|
status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
|
||||||
/* If status == 0 we are going to block so wakeup will be needed. */
|
/* If status == 0 we are going to block so wakeup will be needed. */
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
_this->wakeup_window = wakeup_window;
|
_this->wakeup_window = wakeup_window;
|
||||||
} else {
|
} else {
|
||||||
_this->wakeup_window = NULL;
|
_this->wakeup_window = NULL;
|
||||||
}
|
}
|
||||||
if (_this->wakeup_lock) {
|
|
||||||
SDL_UnlockMutex(_this->wakeup_lock);
|
|
||||||
}
|
}
|
||||||
|
SDL_UnlockMutex(_this->wakeup_lock);
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
/* Got an error: return */
|
/* Got an error: return */
|
||||||
break;
|
break;
|
||||||
|
@ -1054,7 +1045,6 @@ static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Eve
|
||||||
/* An event was found and pumped into the SDL events queue. Continue the loop
|
/* An event was found and pumped into the SDL events queue. Continue the loop
|
||||||
to let SDL_PeepEvents pick it up .*/
|
to let SDL_PeepEvents pick it up .*/
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1187,11 +1177,10 @@ int SDL_PushEvent(SDL_Event *event)
|
||||||
event->common.timestamp = SDL_GetTicks();
|
event->common.timestamp = SDL_GetTicks();
|
||||||
|
|
||||||
if (SDL_EventOK.callback || SDL_event_watchers_count > 0) {
|
if (SDL_EventOK.callback || SDL_event_watchers_count > 0) {
|
||||||
if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) {
|
SDL_LockMutex(SDL_event_watchers_lock);
|
||||||
|
{
|
||||||
if (SDL_EventOK.callback && !SDL_EventOK.callback(SDL_EventOK.userdata, event)) {
|
if (SDL_EventOK.callback && !SDL_EventOK.callback(SDL_EventOK.userdata, event)) {
|
||||||
if (SDL_event_watchers_lock) {
|
|
||||||
SDL_UnlockMutex(SDL_event_watchers_lock);
|
SDL_UnlockMutex(SDL_event_watchers_lock);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1219,12 +1208,9 @@ int SDL_PushEvent(SDL_Event *event)
|
||||||
SDL_event_watchers_removed = SDL_FALSE;
|
SDL_event_watchers_removed = SDL_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (SDL_event_watchers_lock) {
|
|
||||||
SDL_UnlockMutex(SDL_event_watchers_lock);
|
SDL_UnlockMutex(SDL_event_watchers_lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
|
if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1237,32 +1223,25 @@ int SDL_PushEvent(SDL_Event *event)
|
||||||
|
|
||||||
void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata)
|
void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata)
|
||||||
{
|
{
|
||||||
if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) {
|
SDL_LockMutex(SDL_event_watchers_lock);
|
||||||
|
{
|
||||||
/* Set filter and discard pending events */
|
/* Set filter and discard pending events */
|
||||||
SDL_EventOK.callback = filter;
|
SDL_EventOK.callback = filter;
|
||||||
SDL_EventOK.userdata = userdata;
|
SDL_EventOK.userdata = userdata;
|
||||||
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
|
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
|
||||||
|
}
|
||||||
if (SDL_event_watchers_lock) {
|
|
||||||
SDL_UnlockMutex(SDL_event_watchers_lock);
|
SDL_UnlockMutex(SDL_event_watchers_lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_bool
|
SDL_bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata)
|
||||||
SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata)
|
|
||||||
{
|
{
|
||||||
SDL_EventWatcher event_ok;
|
SDL_EventWatcher event_ok;
|
||||||
|
|
||||||
if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) {
|
SDL_LockMutex(SDL_event_watchers_lock);
|
||||||
|
{
|
||||||
event_ok = SDL_EventOK;
|
event_ok = SDL_EventOK;
|
||||||
|
}
|
||||||
if (SDL_event_watchers_lock) {
|
|
||||||
SDL_UnlockMutex(SDL_event_watchers_lock);
|
SDL_UnlockMutex(SDL_event_watchers_lock);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SDL_zero(event_ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
*filter = event_ok.callback;
|
*filter = event_ok.callback;
|
||||||
|
@ -1275,7 +1254,8 @@ SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata)
|
||||||
|
|
||||||
void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
|
void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
|
||||||
{
|
{
|
||||||
if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) {
|
SDL_LockMutex(SDL_event_watchers_lock);
|
||||||
|
{
|
||||||
SDL_EventWatcher *event_watchers;
|
SDL_EventWatcher *event_watchers;
|
||||||
|
|
||||||
event_watchers = SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(*event_watchers));
|
event_watchers = SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(*event_watchers));
|
||||||
|
@ -1289,16 +1269,14 @@ void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
|
||||||
watcher->removed = SDL_FALSE;
|
watcher->removed = SDL_FALSE;
|
||||||
++SDL_event_watchers_count;
|
++SDL_event_watchers_count;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (SDL_event_watchers_lock) {
|
|
||||||
SDL_UnlockMutex(SDL_event_watchers_lock);
|
SDL_UnlockMutex(SDL_event_watchers_lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata)
|
void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata)
|
||||||
{
|
{
|
||||||
if (SDL_event_watchers_lock == NULL || SDL_LockMutex(SDL_event_watchers_lock) == 0) {
|
SDL_LockMutex(SDL_event_watchers_lock);
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < SDL_event_watchers_count; ++i) {
|
for (i = 0; i < SDL_event_watchers_count; ++i) {
|
||||||
|
@ -1315,16 +1293,14 @@ void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (SDL_event_watchers_lock) {
|
|
||||||
SDL_UnlockMutex(SDL_event_watchers_lock);
|
SDL_UnlockMutex(SDL_event_watchers_lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
|
void SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
|
||||||
{
|
{
|
||||||
if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
|
SDL_LockMutex(SDL_EventQ.lock);
|
||||||
|
{
|
||||||
SDL_EventEntry *entry, *next;
|
SDL_EventEntry *entry, *next;
|
||||||
for (entry = SDL_EventQ.head; entry; entry = next) {
|
for (entry = SDL_EventQ.head; entry; entry = next) {
|
||||||
next = entry->next;
|
next = entry->next;
|
||||||
|
@ -1332,11 +1308,9 @@ void SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
|
||||||
SDL_CutEvent(entry);
|
SDL_CutEvent(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SDL_EventQ.lock) {
|
}
|
||||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint8 SDL_EventState(Uint32 type, int state)
|
Uint8 SDL_EventState(Uint32 type, int state)
|
||||||
{
|
{
|
||||||
|
@ -1384,8 +1358,7 @@ Uint8 SDL_EventState(Uint32 type, int state)
|
||||||
return current_state;
|
return current_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32
|
Uint32 SDL_RegisterEvents(int numevents)
|
||||||
SDL_RegisterEvents(int numevents)
|
|
||||||
{
|
{
|
||||||
Uint32 event_base;
|
Uint32 event_base;
|
||||||
|
|
||||||
|
|
|
@ -233,12 +233,17 @@ int SDL_JoystickIsHaptic(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
{
|
||||||
/* Must be a valid joystick */
|
/* Must be a valid joystick */
|
||||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = SDL_SYS_JoystickIsHaptic(joystick);
|
ret = SDL_SYS_JoystickIsHaptic(joystick);
|
||||||
|
}
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
|
@ -265,15 +270,19 @@ SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
{
|
||||||
/* Must be a valid joystick */
|
/* Must be a valid joystick */
|
||||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||||
SDL_SetError("Haptic: Joystick isn't valid.");
|
SDL_SetError("Haptic: Joystick isn't valid.");
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Joystick must be haptic */
|
/* Joystick must be haptic */
|
||||||
if (SDL_SYS_JoystickIsHaptic(joystick) <= 0) {
|
if (SDL_SYS_JoystickIsHaptic(joystick) <= 0) {
|
||||||
SDL_SetError("Haptic: Joystick isn't a haptic device.");
|
SDL_SetError("Haptic: Joystick isn't a haptic device.");
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,6 +292,7 @@ SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
|
||||||
if (SDL_SYS_JoystickSameHaptic(hapticlist, joystick)) {
|
if (SDL_SYS_JoystickSameHaptic(hapticlist, joystick)) {
|
||||||
haptic = hapticlist;
|
haptic = hapticlist;
|
||||||
++haptic->ref_count;
|
++haptic->ref_count;
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
return haptic;
|
return haptic;
|
||||||
}
|
}
|
||||||
hapticlist = hapticlist->next;
|
hapticlist = hapticlist->next;
|
||||||
|
@ -292,6 +302,7 @@ SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
|
||||||
haptic = (SDL_Haptic *)SDL_malloc((sizeof *haptic));
|
haptic = (SDL_Haptic *)SDL_malloc((sizeof *haptic));
|
||||||
if (haptic == NULL) {
|
if (haptic == NULL) {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,8 +312,11 @@ SDL_HapticOpenFromJoystick(SDL_Joystick *joystick)
|
||||||
if (SDL_SYS_HapticOpenFromJoystick(haptic, joystick) < 0) {
|
if (SDL_SYS_HapticOpenFromJoystick(haptic, joystick) < 0) {
|
||||||
SDL_SetError("Haptic: SDL_SYS_HapticOpenFromJoystick failed.");
|
SDL_SetError("Haptic: SDL_SYS_HapticOpenFromJoystick failed.");
|
||||||
SDL_free(haptic);
|
SDL_free(haptic);
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
/* Add haptic to list */
|
/* Add haptic to list */
|
||||||
++haptic->ref_count;
|
++haptic->ref_count;
|
||||||
|
|
|
@ -489,6 +489,8 @@ int SDL_SYS_HapticMouse(void)
|
||||||
int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
|
int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
#ifdef SDL_JOYSTICK_LINUX
|
#ifdef SDL_JOYSTICK_LINUX
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->driver != &SDL_LINUX_JoystickDriver) {
|
if (joystick->driver != &SDL_LINUX_JoystickDriver) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -505,6 +507,8 @@ int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
|
||||||
int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
|
int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
#ifdef SDL_JOYSTICK_LINUX
|
#ifdef SDL_JOYSTICK_LINUX
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->driver != &SDL_LINUX_JoystickDriver) {
|
if (joystick->driver != &SDL_LINUX_JoystickDriver) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -528,6 +532,8 @@ int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
|
||||||
int ret;
|
int ret;
|
||||||
SDL_hapticlist_item *item;
|
SDL_hapticlist_item *item;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->driver != &SDL_LINUX_JoystickDriver) {
|
if (joystick->driver != &SDL_LINUX_JoystickDriver) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -49,7 +49,7 @@ extern SDL_bool SDL_JoysticksQuitting(void);
|
||||||
extern SDL_bool SDL_JoysticksLocked(void);
|
extern SDL_bool SDL_JoysticksLocked(void);
|
||||||
|
|
||||||
/* Make sure we currently have the joysticks locked */
|
/* Make sure we currently have the joysticks locked */
|
||||||
extern void SDL_AssertJoysticksLocked(void);
|
extern void SDL_AssertJoysticksLocked(void) SDL_ASSERT_CAPABILITY(SDL_joystick_lock);
|
||||||
|
|
||||||
/* Function to get the next available joystick instance ID */
|
/* Function to get the next available joystick instance ID */
|
||||||
extern SDL_JoystickID SDL_GetNextJoystickInstanceID(void);
|
extern SDL_JoystickID SDL_GetNextJoystickInstanceID(void);
|
||||||
|
|
|
@ -67,68 +67,72 @@ typedef struct _SDL_JoystickSensorInfo
|
||||||
Uint64 timestamp_us;
|
Uint64 timestamp_us;
|
||||||
} SDL_JoystickSensorInfo;
|
} SDL_JoystickSensorInfo;
|
||||||
|
|
||||||
|
#define _guarded SDL_GUARDED_BY(SDL_joystick_lock)
|
||||||
|
|
||||||
struct _SDL_Joystick
|
struct _SDL_Joystick
|
||||||
{
|
{
|
||||||
const void *magic;
|
const void *magic _guarded;
|
||||||
|
|
||||||
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
|
SDL_JoystickID instance_id _guarded; /* Device instance, monotonically increasing from 0 */
|
||||||
char *name; /* Joystick name - system dependent */
|
char *name _guarded; /* Joystick name - system dependent */
|
||||||
char *path; /* Joystick path - system dependent */
|
char *path _guarded; /* Joystick path - system dependent */
|
||||||
char *serial; /* Joystick serial */
|
char *serial _guarded; /* Joystick serial */
|
||||||
SDL_JoystickGUID guid; /* Joystick guid */
|
SDL_JoystickGUID guid _guarded; /* Joystick guid */
|
||||||
Uint16 firmware_version; /* Firmware version, if available */
|
Uint16 firmware_version _guarded; /* Firmware version, if available */
|
||||||
|
|
||||||
int naxes; /* Number of axis controls on the joystick */
|
int naxes _guarded; /* Number of axis controls on the joystick */
|
||||||
SDL_JoystickAxisInfo *axes;
|
SDL_JoystickAxisInfo *axes _guarded;
|
||||||
|
|
||||||
int nhats; /* Number of hats on the joystick */
|
int nhats _guarded; /* Number of hats on the joystick */
|
||||||
Uint8 *hats; /* Current hat states */
|
Uint8 *hats _guarded; /* Current hat states */
|
||||||
|
|
||||||
int nballs; /* Number of trackballs on the joystick */
|
int nballs _guarded; /* Number of trackballs on the joystick */
|
||||||
struct balldelta
|
struct balldelta
|
||||||
{
|
{
|
||||||
int dx;
|
int dx;
|
||||||
int dy;
|
int dy;
|
||||||
} *balls; /* Current ball motion deltas */
|
} *balls _guarded; /* Current ball motion deltas */
|
||||||
|
|
||||||
int nbuttons; /* Number of buttons on the joystick */
|
int nbuttons _guarded; /* Number of buttons on the joystick */
|
||||||
Uint8 *buttons; /* Current button states */
|
Uint8 *buttons _guarded; /* Current button states */
|
||||||
|
|
||||||
int ntouchpads; /* Number of touchpads on the joystick */
|
int ntouchpads _guarded; /* Number of touchpads on the joystick */
|
||||||
SDL_JoystickTouchpadInfo *touchpads; /* Current touchpad states */
|
SDL_JoystickTouchpadInfo *touchpads _guarded; /* Current touchpad states */
|
||||||
|
|
||||||
int nsensors; /* Number of sensors on the joystick */
|
int nsensors _guarded; /* Number of sensors on the joystick */
|
||||||
int nsensors_enabled;
|
int nsensors_enabled _guarded;
|
||||||
SDL_JoystickSensorInfo *sensors;
|
SDL_JoystickSensorInfo *sensors _guarded;
|
||||||
|
|
||||||
Uint16 low_frequency_rumble;
|
Uint16 low_frequency_rumble _guarded;
|
||||||
Uint16 high_frequency_rumble;
|
Uint16 high_frequency_rumble _guarded;
|
||||||
Uint32 rumble_expiration;
|
Uint32 rumble_expiration _guarded;
|
||||||
Uint32 rumble_resend;
|
Uint32 rumble_resend _guarded;
|
||||||
|
|
||||||
Uint16 left_trigger_rumble;
|
Uint16 left_trigger_rumble _guarded;
|
||||||
Uint16 right_trigger_rumble;
|
Uint16 right_trigger_rumble _guarded;
|
||||||
Uint32 trigger_rumble_expiration;
|
Uint32 trigger_rumble_expiration _guarded;
|
||||||
|
|
||||||
Uint8 led_red;
|
Uint8 led_red _guarded;
|
||||||
Uint8 led_green;
|
Uint8 led_green _guarded;
|
||||||
Uint8 led_blue;
|
Uint8 led_blue _guarded;
|
||||||
Uint32 led_expiration;
|
Uint32 led_expiration _guarded;
|
||||||
|
|
||||||
SDL_bool attached;
|
SDL_bool attached _guarded;
|
||||||
SDL_bool is_game_controller;
|
SDL_bool is_game_controller _guarded;
|
||||||
SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */
|
SDL_bool delayed_guide_button _guarded; /* SDL_TRUE if this device has the guide button event delayed */
|
||||||
SDL_JoystickPowerLevel epowerlevel; /* power level of this joystick, SDL_JOYSTICK_POWER_UNKNOWN if not supported */
|
SDL_JoystickPowerLevel epowerlevel _guarded; /* power level of this joystick, SDL_JOYSTICK_POWER_UNKNOWN if not supported */
|
||||||
|
|
||||||
struct _SDL_JoystickDriver *driver;
|
struct _SDL_JoystickDriver *driver _guarded;
|
||||||
|
|
||||||
struct joystick_hwdata *hwdata; /* Driver dependent information */
|
struct joystick_hwdata *hwdata _guarded; /* Driver dependent information */
|
||||||
|
|
||||||
int ref_count; /* Reference count for multiple opens */
|
int ref_count _guarded; /* Reference count for multiple opens */
|
||||||
|
|
||||||
struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */
|
struct _SDL_Joystick *next _guarded; /* pointer to next joystick we have allocated */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef _guarded
|
||||||
|
|
||||||
/* Device bus definitions */
|
/* Device bus definitions */
|
||||||
#define SDL_HARDWARE_BUS_UNKNOWN 0x00
|
#define SDL_HARDWARE_BUS_UNKNOWN 0x00
|
||||||
#define SDL_HARDWARE_BUS_USB 0x03
|
#define SDL_HARDWARE_BUS_USB 0x03
|
||||||
|
|
|
@ -67,6 +67,8 @@ static SDL_bool HIDAPI_DriverCombined_OpenJoystick(SDL_HIDAPI_Device *device, SD
|
||||||
char *serial = NULL, *new_serial;
|
char *serial = NULL, *new_serial;
|
||||||
size_t serial_length = 0, new_length;
|
size_t serial_length = 0, new_length;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
for (i = 0; i < device->num_children; ++i) {
|
for (i = 0; i < device->num_children; ++i) {
|
||||||
SDL_HIDAPI_Device *child = device->children[i];
|
SDL_HIDAPI_Device *child = device->children[i];
|
||||||
if (!child->driver->OpenJoystick(child, joystick)) {
|
if (!child->driver->OpenJoystick(child, joystick)) {
|
||||||
|
|
|
@ -408,6 +408,9 @@ static SDL_bool HIDAPI_DriverGameCube_OpenJoystick(SDL_HIDAPI_Device *device, SD
|
||||||
{
|
{
|
||||||
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
||||||
Uint8 i;
|
Uint8 i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
|
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
|
||||||
if (joystick->instance_id == ctx->joysticks[i]) {
|
if (joystick->instance_id == ctx->joysticks[i]) {
|
||||||
joystick->nbuttons = 12;
|
joystick->nbuttons = 12;
|
||||||
|
@ -424,6 +427,8 @@ static int HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_J
|
||||||
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
||||||
Uint8 i, val;
|
Uint8 i, val;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (ctx->pc_mode) {
|
if (ctx->pc_mode) {
|
||||||
return SDL_Unsupported();
|
return SDL_Unsupported();
|
||||||
}
|
}
|
||||||
|
@ -469,6 +474,8 @@ static Uint32 HIDAPI_DriverGameCube_GetJoystickCapabilities(SDL_HIDAPI_Device *d
|
||||||
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
||||||
Uint32 result = 0;
|
Uint32 result = 0;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (!ctx->pc_mode) {
|
if (!ctx->pc_mode) {
|
||||||
Uint8 i;
|
Uint8 i;
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,8 @@ static SDL_bool HIDAPI_DriverLuna_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Jo
|
||||||
{
|
{
|
||||||
SDL_DriverLuna_Context *ctx = (SDL_DriverLuna_Context *)device->context;
|
SDL_DriverLuna_Context *ctx = (SDL_DriverLuna_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
SDL_zeroa(ctx->last_state);
|
SDL_zeroa(ctx->last_state);
|
||||||
|
|
||||||
/* Initialize the joystick capabilities */
|
/* Initialize the joystick capabilities */
|
||||||
|
|
|
@ -234,6 +234,8 @@ static SDL_bool HIDAPI_DriverPS3_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
|
||||||
{
|
{
|
||||||
SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context;
|
SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->joystick = joystick;
|
ctx->joystick = joystick;
|
||||||
ctx->effects_updated = SDL_FALSE;
|
ctx->effects_updated = SDL_FALSE;
|
||||||
ctx->rumble_left = 0;
|
ctx->rumble_left = 0;
|
||||||
|
@ -630,6 +632,8 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_OpenJoystick(SDL_HIDAPI_Device *devic
|
||||||
{
|
{
|
||||||
SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context;
|
SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->joystick = joystick;
|
ctx->joystick = joystick;
|
||||||
SDL_zeroa(ctx->last_state);
|
SDL_zeroa(ctx->last_state);
|
||||||
|
|
||||||
|
|
|
@ -668,6 +668,8 @@ static SDL_bool HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
|
||||||
{
|
{
|
||||||
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
|
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->joystick = joystick;
|
ctx->joystick = joystick;
|
||||||
ctx->last_packet = SDL_GetTicks();
|
ctx->last_packet = SDL_GetTicks();
|
||||||
ctx->report_sensors = SDL_FALSE;
|
ctx->report_sensors = SDL_FALSE;
|
||||||
|
|
|
@ -822,6 +822,8 @@ static SDL_bool HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
|
||||||
{
|
{
|
||||||
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
|
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->joystick = joystick;
|
ctx->joystick = joystick;
|
||||||
ctx->last_packet = SDL_GetTicks();
|
ctx->last_packet = SDL_GetTicks();
|
||||||
ctx->report_sensors = SDL_FALSE;
|
ctx->report_sensors = SDL_FALSE;
|
||||||
|
@ -961,7 +963,7 @@ static int HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Jo
|
||||||
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
|
SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
if (SDL_HIDAPI_LockRumble() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,13 +46,13 @@ typedef struct SDL_HIDAPI_RumbleContext
|
||||||
SDL_atomic_t initialized;
|
SDL_atomic_t initialized;
|
||||||
SDL_atomic_t running;
|
SDL_atomic_t running;
|
||||||
SDL_Thread *thread;
|
SDL_Thread *thread;
|
||||||
SDL_mutex *lock;
|
|
||||||
SDL_sem *request_sem;
|
SDL_sem *request_sem;
|
||||||
SDL_HIDAPI_RumbleRequest *requests_head;
|
SDL_HIDAPI_RumbleRequest *requests_head;
|
||||||
SDL_HIDAPI_RumbleRequest *requests_tail;
|
SDL_HIDAPI_RumbleRequest *requests_tail;
|
||||||
} SDL_HIDAPI_RumbleContext;
|
} SDL_HIDAPI_RumbleContext;
|
||||||
|
|
||||||
static SDL_HIDAPI_RumbleContext rumble_context;
|
SDL_mutex *SDL_HIDAPI_rumble_lock;
|
||||||
|
static SDL_HIDAPI_RumbleContext rumble_context SDL_GUARDED_BY(SDL_HIDAPI_rumble_lock);
|
||||||
|
|
||||||
static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
|
static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
|
||||||
{
|
{
|
||||||
|
@ -65,7 +65,7 @@ static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
|
||||||
|
|
||||||
SDL_SemWait(ctx->request_sem);
|
SDL_SemWait(ctx->request_sem);
|
||||||
|
|
||||||
SDL_LockMutex(ctx->lock);
|
SDL_LockMutex(SDL_HIDAPI_rumble_lock);
|
||||||
request = ctx->requests_tail;
|
request = ctx->requests_tail;
|
||||||
if (request) {
|
if (request) {
|
||||||
if (request == ctx->requests_head) {
|
if (request == ctx->requests_head) {
|
||||||
|
@ -73,7 +73,7 @@ static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
|
||||||
}
|
}
|
||||||
ctx->requests_tail = request->prev;
|
ctx->requests_tail = request->prev;
|
||||||
}
|
}
|
||||||
SDL_UnlockMutex(ctx->lock);
|
SDL_UnlockMutex(SDL_HIDAPI_rumble_lock);
|
||||||
|
|
||||||
if (request) {
|
if (request) {
|
||||||
SDL_LockMutex(request->device->dev_lock);
|
SDL_LockMutex(request->device->dev_lock);
|
||||||
|
@ -111,7 +111,7 @@ static void SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
|
||||||
ctx->thread = NULL;
|
ctx->thread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LockMutex(ctx->lock);
|
SDL_LockMutex(SDL_HIDAPI_rumble_lock);
|
||||||
while (ctx->requests_tail) {
|
while (ctx->requests_tail) {
|
||||||
request = ctx->requests_tail;
|
request = ctx->requests_tail;
|
||||||
if (request == ctx->requests_head) {
|
if (request == ctx->requests_head) {
|
||||||
|
@ -125,16 +125,16 @@ static void SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
|
||||||
(void)SDL_AtomicDecRef(&request->device->rumble_pending);
|
(void)SDL_AtomicDecRef(&request->device->rumble_pending);
|
||||||
SDL_free(request);
|
SDL_free(request);
|
||||||
}
|
}
|
||||||
SDL_UnlockMutex(ctx->lock);
|
SDL_UnlockMutex(SDL_HIDAPI_rumble_lock);
|
||||||
|
|
||||||
if (ctx->request_sem) {
|
if (ctx->request_sem) {
|
||||||
SDL_DestroySemaphore(ctx->request_sem);
|
SDL_DestroySemaphore(ctx->request_sem);
|
||||||
ctx->request_sem = NULL;
|
ctx->request_sem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->lock) {
|
if (SDL_HIDAPI_rumble_lock) {
|
||||||
SDL_DestroyMutex(ctx->lock);
|
SDL_DestroyMutex(SDL_HIDAPI_rumble_lock);
|
||||||
ctx->lock = NULL;
|
SDL_HIDAPI_rumble_lock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_AtomicSet(&ctx->initialized, SDL_FALSE);
|
SDL_AtomicSet(&ctx->initialized, SDL_FALSE);
|
||||||
|
@ -142,8 +142,8 @@ static void SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
|
||||||
|
|
||||||
static int SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
|
static int SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
|
||||||
{
|
{
|
||||||
ctx->lock = SDL_CreateMutex();
|
SDL_HIDAPI_rumble_lock = SDL_CreateMutex();
|
||||||
if (!ctx->lock) {
|
if (!SDL_HIDAPI_rumble_lock) {
|
||||||
SDL_HIDAPI_StopRumbleThread(ctx);
|
SDL_HIDAPI_StopRumbleThread(ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,8 @@ int SDL_HIDAPI_LockRumble(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_LockMutex(ctx->lock);
|
SDL_LockMutex(SDL_HIDAPI_rumble_lock);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size)
|
SDL_bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size)
|
||||||
|
@ -241,9 +242,7 @@ int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const
|
||||||
|
|
||||||
void SDL_HIDAPI_UnlockRumble(void)
|
void SDL_HIDAPI_UnlockRumble(void)
|
||||||
{
|
{
|
||||||
SDL_HIDAPI_RumbleContext *ctx = &rumble_context;
|
SDL_UnlockMutex(SDL_HIDAPI_rumble_lock);
|
||||||
|
|
||||||
SDL_UnlockMutex(ctx->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size)
|
int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size)
|
||||||
|
@ -256,7 +255,7 @@ int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size
|
||||||
return SDL_SetError("Tried to send rumble with invalid size");
|
return SDL_SetError("Tried to send rumble with invalid size");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
if (SDL_HIDAPI_LockRumble() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,15 @@
|
||||||
/* Handle rumble on a separate thread so it doesn't block the application */
|
/* Handle rumble on a separate thread so it doesn't block the application */
|
||||||
|
|
||||||
/* Advanced API */
|
/* Advanced API */
|
||||||
int SDL_HIDAPI_LockRumble(void);
|
#ifdef SDL_THREAD_SAFETY_ANALYSIS
|
||||||
|
extern SDL_mutex *SDL_HIDAPI_rumble_lock;
|
||||||
|
#endif
|
||||||
|
int SDL_HIDAPI_LockRumble(void) SDL_TRY_ACQUIRE(0, SDL_HIDAPI_rumble_lock);
|
||||||
SDL_bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size);
|
SDL_bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size);
|
||||||
int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size);
|
int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size) SDL_RELEASE(SDL_HIDAPI_rumble_lock);
|
||||||
typedef void (*SDL_HIDAPI_RumbleSentCallback)(void *userdata);
|
typedef void (*SDL_HIDAPI_RumbleSentCallback)(void *userdata);
|
||||||
int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size, SDL_HIDAPI_RumbleSentCallback callback, void *userdata);
|
int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size, SDL_HIDAPI_RumbleSentCallback callback, void *userdata) SDL_RELEASE(SDL_HIDAPI_rumble_lock);
|
||||||
void SDL_HIDAPI_UnlockRumble(void);
|
void SDL_HIDAPI_UnlockRumble(void) SDL_RELEASE(SDL_HIDAPI_rumble_lock);
|
||||||
|
|
||||||
/* Simple API, will replace any pending rumble with the new data */
|
/* Simple API, will replace any pending rumble with the new data */
|
||||||
int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size);
|
int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size);
|
||||||
|
|
|
@ -148,7 +148,7 @@ static int HIDAPI_DriverShield_SendCommand(SDL_HIDAPI_Device *device, Uint8 cmd,
|
||||||
return SDL_SetError("Command data exceeds HID report size");
|
return SDL_SetError("Command data exceeds HID report size");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
if (SDL_HIDAPI_LockRumble() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +175,8 @@ static SDL_bool HIDAPI_DriverShield_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
|
||||||
{
|
{
|
||||||
SDL_DriverShield_Context *ctx = (SDL_DriverShield_Context *)device->context;
|
SDL_DriverShield_Context *ctx = (SDL_DriverShield_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->rumble_report_pending = SDL_FALSE;
|
ctx->rumble_report_pending = SDL_FALSE;
|
||||||
ctx->rumble_update_pending = SDL_FALSE;
|
ctx->rumble_update_pending = SDL_FALSE;
|
||||||
ctx->left_motor_amplitude = 0;
|
ctx->left_motor_amplitude = 0;
|
||||||
|
|
|
@ -96,6 +96,8 @@ static SDL_bool HIDAPI_DriverStadia_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
|
||||||
{
|
{
|
||||||
SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context;
|
SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
SDL_zeroa(ctx->last_state);
|
SDL_zeroa(ctx->last_state);
|
||||||
|
|
||||||
/* Initialize the joystick capabilities */
|
/* Initialize the joystick capabilities */
|
||||||
|
|
|
@ -1012,6 +1012,8 @@ static SDL_bool HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_J
|
||||||
SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context;
|
SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context;
|
||||||
float update_rate_in_hz = 0.0f;
|
float update_rate_in_hz = 0.0f;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->report_sensors = SDL_FALSE;
|
ctx->report_sensors = SDL_FALSE;
|
||||||
SDL_zero(ctx->m_assembler);
|
SDL_zero(ctx->m_assembler);
|
||||||
SDL_zero(ctx->m_state);
|
SDL_zero(ctx->m_state);
|
||||||
|
|
|
@ -323,7 +323,7 @@ static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int siz
|
||||||
return SDL_hid_write(ctx->device->dev, data, size);
|
return SDL_hid_write(ctx->device->dev, data, size);
|
||||||
#else
|
#else
|
||||||
/* Use the rumble thread for general asynchronous writes */
|
/* Use the rumble thread for general asynchronous writes */
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
if (SDL_HIDAPI_LockRumble() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, data, size);
|
return SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, data, size);
|
||||||
|
@ -1253,6 +1253,8 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
|
||||||
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
|
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
|
||||||
Uint8 input_mode;
|
Uint8 input_mode;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->joystick = joystick;
|
ctx->joystick = joystick;
|
||||||
|
|
||||||
ctx->m_bSyncWrite = SDL_TRUE;
|
ctx->m_bSyncWrite = SDL_TRUE;
|
||||||
|
@ -1891,7 +1893,7 @@ static void HandleMiniControllerStateR(SDL_Joystick *joystick, SDL_DriverSwitch_
|
||||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
|
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet)
|
static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) SDL_NO_THREAD_SAFETY_ANALYSIS /* We unlock and lock the device lock to be able to change IMU state */
|
||||||
{
|
{
|
||||||
if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) {
|
if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) {
|
||||||
if (ctx->device->parent || ctx->m_bVerticalMode) {
|
if (ctx->device->parent || ctx->m_bVerticalMode) {
|
||||||
|
|
|
@ -221,7 +221,7 @@ static SDL_bool WriteOutput(SDL_DriverWii_Context *ctx, const Uint8 *data, int s
|
||||||
return SDL_hid_write(ctx->device->dev, data, size) >= 0;
|
return SDL_hid_write(ctx->device->dev, data, size) >= 0;
|
||||||
} else {
|
} else {
|
||||||
/* Use the rumble thread for general asynchronous writes */
|
/* Use the rumble thread for general asynchronous writes */
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
if (SDL_HIDAPI_LockRumble() != 0) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
return SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, data, size) >= 0;
|
return SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, data, size) >= 0;
|
||||||
|
@ -770,6 +770,8 @@ static SDL_bool HIDAPI_DriverWii_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
|
||||||
{
|
{
|
||||||
SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context;
|
SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->joystick = joystick;
|
ctx->joystick = joystick;
|
||||||
|
|
||||||
InitializeExtension(ctx);
|
InitializeExtension(ctx);
|
||||||
|
|
|
@ -176,6 +176,8 @@ static SDL_bool HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL
|
||||||
{
|
{
|
||||||
SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context;
|
SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->joystick = joystick;
|
ctx->joystick = joystick;
|
||||||
SDL_zeroa(ctx->last_state);
|
SDL_zeroa(ctx->last_state);
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,8 @@ static SDL_bool HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SD
|
||||||
{
|
{
|
||||||
SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context;
|
SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
SDL_zeroa(ctx->last_state);
|
SDL_zeroa(ctx->last_state);
|
||||||
|
|
||||||
/* Initialize player index (needed for setting LEDs) */
|
/* Initialize player index (needed for setting LEDs) */
|
||||||
|
|
|
@ -234,7 +234,7 @@ static void SendAckIfNeeded(SDL_HIDAPI_Device *device, const Uint8 *data, int si
|
||||||
#ifdef DEBUG_XBOX_PROTOCOL
|
#ifdef DEBUG_XBOX_PROTOCOL
|
||||||
HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet));
|
HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet));
|
||||||
#endif
|
#endif
|
||||||
if (SDL_HIDAPI_LockRumble() < 0 ||
|
if (SDL_HIDAPI_LockRumble() != 0 ||
|
||||||
SDL_HIDAPI_SendRumbleAndUnlock(device, ack_packet, sizeof(ack_packet)) != sizeof(ack_packet)) {
|
SDL_HIDAPI_SendRumbleAndUnlock(device, ack_packet, sizeof(ack_packet)) != sizeof(ack_packet)) {
|
||||||
SDL_SetError("Couldn't send ack packet");
|
SDL_SetError("Couldn't send ack packet");
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ static SDL_bool SendSerialRequest(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_C
|
||||||
* It will cancel the announce packet if sent before that, and will be
|
* It will cancel the announce packet if sent before that, and will be
|
||||||
* ignored if sent during the negotiation.
|
* ignored if sent during the negotiation.
|
||||||
*/
|
*/
|
||||||
if (SDL_HIDAPI_LockRumble() < 0 ||
|
if (SDL_HIDAPI_LockRumble() != 0 ||
|
||||||
SDL_HIDAPI_SendRumbleAndUnlock(device, serial_packet, sizeof(serial_packet)) != sizeof(serial_packet)) {
|
SDL_HIDAPI_SendRumbleAndUnlock(device, serial_packet, sizeof(serial_packet)) != sizeof(serial_packet)) {
|
||||||
SDL_SetError("Couldn't send serial packet");
|
SDL_SetError("Couldn't send serial packet");
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
|
@ -312,7 +312,7 @@ static SDL_bool SendControllerInit(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_
|
||||||
#endif
|
#endif
|
||||||
ctx->send_time = SDL_GetTicks();
|
ctx->send_time = SDL_GetTicks();
|
||||||
|
|
||||||
if (SDL_HIDAPI_LockRumble() < 0 ||
|
if (SDL_HIDAPI_LockRumble() != 0 ||
|
||||||
SDL_HIDAPI_SendRumbleAndUnlock(device, init_packet, packet->size) != packet->size) {
|
SDL_HIDAPI_SendRumbleAndUnlock(device, init_packet, packet->size) != packet->size) {
|
||||||
SDL_SetError("Couldn't write Xbox One initialization packet");
|
SDL_SetError("Couldn't write Xbox One initialization packet");
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
|
@ -415,6 +415,8 @@ static SDL_bool HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL
|
||||||
{
|
{
|
||||||
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
ctx->low_frequency_rumble = 0;
|
ctx->low_frequency_rumble = 0;
|
||||||
ctx->high_frequency_rumble = 0;
|
ctx->high_frequency_rumble = 0;
|
||||||
ctx->left_trigger_rumble = 0;
|
ctx->left_trigger_rumble = 0;
|
||||||
|
@ -478,7 +480,7 @@ static int HIDAPI_DriverXboxOne_UpdateRumble(SDL_HIDAPI_Device *device)
|
||||||
/* We're no longer pending, even if we fail to send the rumble below */
|
/* We're no longer pending, even if we fail to send the rumble below */
|
||||||
ctx->rumble_pending = SDL_FALSE;
|
ctx->rumble_pending = SDL_FALSE;
|
||||||
|
|
||||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
if (SDL_HIDAPI_LockRumble() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ static int SDL_HIDAPI_numdrivers = 0;
|
||||||
static SDL_SpinLock SDL_HIDAPI_spinlock;
|
static SDL_SpinLock SDL_HIDAPI_spinlock;
|
||||||
static SDL_bool SDL_HIDAPI_hints_changed = SDL_FALSE;
|
static SDL_bool SDL_HIDAPI_hints_changed = SDL_FALSE;
|
||||||
static Uint32 SDL_HIDAPI_change_count = 0;
|
static Uint32 SDL_HIDAPI_change_count = 0;
|
||||||
static SDL_HIDAPI_Device *SDL_HIDAPI_devices;
|
static SDL_HIDAPI_Device *SDL_HIDAPI_devices SDL_GUARDED_BY(SDL_joystick_lock);
|
||||||
static int SDL_HIDAPI_numjoysticks = 0;
|
static int SDL_HIDAPI_numjoysticks = 0;
|
||||||
static SDL_bool SDL_HIDAPI_combine_joycons = SDL_TRUE;
|
static SDL_bool SDL_HIDAPI_combine_joycons = SDL_TRUE;
|
||||||
static SDL_bool initialized = SDL_FALSE;
|
static SDL_bool initialized = SDL_FALSE;
|
||||||
|
@ -264,6 +264,8 @@ static SDL_HIDAPI_Device *HIDAPI_GetDeviceByIndex(int device_index, SDL_Joystick
|
||||||
{
|
{
|
||||||
SDL_HIDAPI_Device *device;
|
SDL_HIDAPI_Device *device;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
for (device = SDL_HIDAPI_devices; device; device = device->next) {
|
for (device = SDL_HIDAPI_devices; device; device = device->next) {
|
||||||
if (device->parent) {
|
if (device->parent) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -285,6 +287,8 @@ static SDL_HIDAPI_Device *HIDAPI_GetJoystickByInfo(const char *path, Uint16 vend
|
||||||
{
|
{
|
||||||
SDL_HIDAPI_Device *device;
|
SDL_HIDAPI_Device *device;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
for (device = SDL_HIDAPI_devices; device; device = device->next) {
|
for (device = SDL_HIDAPI_devices; device; device = device->next) {
|
||||||
if (device->vendor_id == vendor_id && device->product_id == product_id &&
|
if (device->vendor_id == vendor_id && device->product_id == product_id &&
|
||||||
SDL_strcmp(device->path, path) == 0) {
|
SDL_strcmp(device->path, path) == 0) {
|
||||||
|
@ -323,7 +327,7 @@ static void HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
|
||||||
SDL_UnlockMutex(device->dev_lock);
|
SDL_UnlockMutex(device->dev_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed)
|
static void HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed) SDL_NO_THREAD_SAFETY_ANALYSIS /* We unlock the joystick lock to be able to open the HID device on Android */
|
||||||
{
|
{
|
||||||
*removed = SDL_FALSE;
|
*removed = SDL_FALSE;
|
||||||
|
|
||||||
|
@ -426,6 +430,8 @@ static void SDL_HIDAPI_UpdateDrivers(void)
|
||||||
SDL_HIDAPI_Device *device;
|
SDL_HIDAPI_Device *device;
|
||||||
SDL_bool removed;
|
SDL_bool removed;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
SDL_HIDAPI_numdrivers = 0;
|
SDL_HIDAPI_numdrivers = 0;
|
||||||
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
|
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
|
||||||
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
|
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
|
||||||
|
@ -571,6 +577,8 @@ HIDAPI_HasConnectedUSBDevice(const char *serial)
|
||||||
{
|
{
|
||||||
SDL_HIDAPI_Device *device;
|
SDL_HIDAPI_Device *device;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (serial == NULL) {
|
if (serial == NULL) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -595,6 +603,8 @@ void HIDAPI_DisconnectBluetoothDevice(const char *serial)
|
||||||
{
|
{
|
||||||
SDL_HIDAPI_Device *device;
|
SDL_HIDAPI_Device *device;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (serial == NULL) {
|
if (serial == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -622,6 +632,8 @@ HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
|
||||||
int i, j;
|
int i, j;
|
||||||
SDL_JoystickID joystickID;
|
SDL_JoystickID joystickID;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
for (i = 0; i < device->num_children; ++i) {
|
for (i = 0; i < device->num_children; ++i) {
|
||||||
SDL_HIDAPI_Device *child = device->children[i];
|
SDL_HIDAPI_Device *child = device->children[i];
|
||||||
for (j = child->num_joysticks; j--;) {
|
for (j = child->num_joysticks; j--;) {
|
||||||
|
@ -717,6 +729,8 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
|
||||||
SDL_HIDAPI_Device *curr, *last = NULL;
|
SDL_HIDAPI_Device *curr, *last = NULL;
|
||||||
SDL_bool removed;
|
SDL_bool removed;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
for (curr = SDL_HIDAPI_devices, last = NULL; curr; last = curr, curr = curr->next) {
|
for (curr = SDL_HIDAPI_devices, last = NULL; curr; last = curr, curr = curr->next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,6 +824,8 @@ static void HIDAPI_DelDevice(SDL_HIDAPI_Device *device)
|
||||||
SDL_HIDAPI_Device *curr, *last;
|
SDL_HIDAPI_Device *curr, *last;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
#ifdef DEBUG_HIDAPI
|
#ifdef DEBUG_HIDAPI
|
||||||
SDL_Log("Removing HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, serial %s, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, device->serial ? device->serial : "NONE", device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, device->path, device->driver ? device->driver->name : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED");
|
SDL_Log("Removing HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, serial %s, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, device->serial ? device->serial : "NONE", device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, device->path, device->driver ? device->driver->name : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED");
|
||||||
#endif
|
#endif
|
||||||
|
@ -849,6 +865,8 @@ static SDL_bool HIDAPI_CreateCombinedJoyCons()
|
||||||
SDL_HIDAPI_Device *device, *combined;
|
SDL_HIDAPI_Device *device, *combined;
|
||||||
SDL_HIDAPI_Device *joycons[2] = { NULL, NULL };
|
SDL_HIDAPI_Device *joycons[2] = { NULL, NULL };
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (!SDL_HIDAPI_combine_joycons) {
|
if (!SDL_HIDAPI_combine_joycons) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1160,6 +1178,8 @@ void HIDAPI_UpdateDevices(void)
|
||||||
{
|
{
|
||||||
SDL_HIDAPI_Device *device;
|
SDL_HIDAPI_Device *device;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
/* Update the devices, which may change connected joysticks and send events */
|
/* Update the devices, which may change connected joysticks and send events */
|
||||||
|
|
||||||
/* Prepare the existing device list */
|
/* Prepare the existing device list */
|
||||||
|
@ -1262,6 +1282,8 @@ static int HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||||
SDL_HIDAPI_Device *device = HIDAPI_GetDeviceByIndex(device_index, &joystickID);
|
SDL_HIDAPI_Device *device = HIDAPI_GetDeviceByIndex(device_index, &joystickID);
|
||||||
struct joystick_hwdata *hwdata;
|
struct joystick_hwdata *hwdata;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (device == NULL || !device->driver) {
|
if (device == NULL || !device->driver) {
|
||||||
/* This should never happen - validated before being called */
|
/* This should never happen - validated before being called */
|
||||||
return SDL_SetError("Couldn't find HIDAPI device at index %d\n", device_index);
|
return SDL_SetError("Couldn't find HIDAPI device at index %d\n", device_index);
|
||||||
|
@ -1299,6 +1321,8 @@ static int HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_ru
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||||
|
|
||||||
|
@ -1314,6 +1338,8 @@ static int HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rum
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||||
|
|
||||||
|
@ -1329,6 +1355,8 @@ static Uint32 HIDAPI_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
Uint32 result = 0;
|
Uint32 result = 0;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||||
|
|
||||||
|
@ -1342,6 +1370,8 @@ static int HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green,
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||||
|
|
||||||
|
@ -1357,6 +1387,8 @@ static int HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, i
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||||
|
|
||||||
|
@ -1372,6 +1404,8 @@ static int HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool ena
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||||
|
|
||||||
|
@ -1388,8 +1422,10 @@ static void HIDAPI_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
/* This is handled in SDL_HIDAPI_UpdateDevices() */
|
/* This is handled in SDL_HIDAPI_UpdateDevices() */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HIDAPI_JoystickClose(SDL_Joystick *joystick)
|
static void HIDAPI_JoystickClose(SDL_Joystick *joystick) SDL_NO_THREAD_SAFETY_ANALYSIS /* We unlock the device lock so rumble can complete */
|
||||||
{
|
{
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||||
int i;
|
int i;
|
||||||
|
@ -1420,6 +1456,8 @@ static void HIDAPI_JoystickQuit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
shutting_down = SDL_TRUE;
|
shutting_down = SDL_TRUE;
|
||||||
|
|
||||||
SDL_HIDAPI_QuitRumble();
|
SDL_HIDAPI_QuitRumble();
|
||||||
|
|
|
@ -852,6 +852,8 @@ static int allocate_hatdata(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
joystick->hwdata->hats =
|
joystick->hwdata->hats =
|
||||||
(struct hwdata_hat *)SDL_malloc(joystick->nhats *
|
(struct hwdata_hat *)SDL_malloc(joystick->nhats *
|
||||||
sizeof(struct hwdata_hat));
|
sizeof(struct hwdata_hat));
|
||||||
|
@ -869,6 +871,8 @@ static int allocate_balldata(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
joystick->hwdata->balls =
|
joystick->hwdata->balls =
|
||||||
(struct hwdata_ball *)SDL_malloc(joystick->nballs *
|
(struct hwdata_ball *)SDL_malloc(joystick->nballs *
|
||||||
sizeof(struct hwdata_ball));
|
sizeof(struct hwdata_ball));
|
||||||
|
@ -925,6 +929,8 @@ static void ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE);
|
SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE);
|
||||||
SDL_bool use_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_HAT_DEADZONES, SDL_TRUE);
|
SDL_bool use_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_HAT_DEADZONES, SDL_TRUE);
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
/* See if this device uses the new unified event API */
|
/* See if this device uses the new unified event API */
|
||||||
if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
|
if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
|
||||||
(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
|
(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) &&
|
||||||
|
@ -1132,6 +1138,8 @@ static void ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||||
on error. Returns -1 on error, 0 on success. */
|
on error. Returns -1 on error, 0 on success. */
|
||||||
static int PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item)
|
static int PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item)
|
||||||
{
|
{
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
joystick->hwdata->item = item;
|
joystick->hwdata->item = item;
|
||||||
joystick->hwdata->guid = item->guid;
|
joystick->hwdata->guid = item->guid;
|
||||||
joystick->hwdata->effect.id = -1;
|
joystick->hwdata->effect.id = -1;
|
||||||
|
@ -1180,6 +1188,8 @@ static int LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||||
{
|
{
|
||||||
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
return SDL_SetError("No such device");
|
return SDL_SetError("No such device");
|
||||||
}
|
}
|
||||||
|
@ -1210,6 +1220,8 @@ static int LINUX_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rum
|
||||||
{
|
{
|
||||||
struct input_event event;
|
struct input_event event;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata->ff_rumble) {
|
if (joystick->hwdata->ff_rumble) {
|
||||||
struct ff_effect *effect = &joystick->hwdata->effect;
|
struct ff_effect *effect = &joystick->hwdata->effect;
|
||||||
|
|
||||||
|
@ -1256,6 +1268,8 @@ static Uint32 LINUX_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
Uint32 result = 0;
|
Uint32 result = 0;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) {
|
if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) {
|
||||||
result |= SDL_JOYCAP_RUMBLE;
|
result |= SDL_JOYCAP_RUMBLE;
|
||||||
}
|
}
|
||||||
|
@ -1280,7 +1294,7 @@ static int LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enab
|
||||||
|
|
||||||
static void HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value)
|
static void HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value)
|
||||||
{
|
{
|
||||||
const int hatnum = stick->hwdata->hats_indices[hatidx];
|
int hatnum;
|
||||||
struct hwdata_hat *the_hat;
|
struct hwdata_hat *the_hat;
|
||||||
struct hat_axis_correct *correct;
|
struct hat_axis_correct *correct;
|
||||||
const Uint8 position_map[3][3] = {
|
const Uint8 position_map[3][3] = {
|
||||||
|
@ -1289,6 +1303,9 @@ static void HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value)
|
||||||
{ SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
|
{ SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
|
hatnum = stick->hwdata->hats_indices[hatidx];
|
||||||
the_hat = &stick->hwdata->hats[hatnum];
|
the_hat = &stick->hwdata->hats[hatnum];
|
||||||
correct = &stick->hwdata->hat_correct[hatidx];
|
correct = &stick->hwdata->hat_correct[hatidx];
|
||||||
/* Hopefully we detected any analog axes and left them as is rather than trying
|
/* Hopefully we detected any analog axes and left them as is rather than trying
|
||||||
|
@ -1326,6 +1343,8 @@ static void HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value)
|
||||||
|
|
||||||
static void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
|
static void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
|
||||||
{
|
{
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
stick->hwdata->balls[ball].axis[axis] += value;
|
stick->hwdata->balls[ball].axis[axis] += value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1333,6 +1352,8 @@ static int AxisCorrect(SDL_Joystick *joystick, int which, int value)
|
||||||
{
|
{
|
||||||
struct axis_correct *correct;
|
struct axis_correct *correct;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
correct = &joystick->hwdata->abs_correct[which];
|
correct = &joystick->hwdata->abs_correct[which];
|
||||||
if (correct->minimum != correct->maximum) {
|
if (correct->minimum != correct->maximum) {
|
||||||
if (correct->use_deadzones) {
|
if (correct->use_deadzones) {
|
||||||
|
@ -1368,6 +1389,8 @@ static void PollAllValues(SDL_Joystick *joystick)
|
||||||
unsigned long keyinfo[NBITS(KEY_MAX)];
|
unsigned long keyinfo[NBITS(KEY_MAX)];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
/* Poll all axis */
|
/* Poll all axis */
|
||||||
for (i = ABS_X; i < ABS_MAX; i++) {
|
for (i = ABS_X; i < ABS_MAX; i++) {
|
||||||
/* We don't need to test for digital hats here, they won't have has_abs[] set */
|
/* We don't need to test for digital hats here, they won't have has_abs[] set */
|
||||||
|
@ -1424,6 +1447,8 @@ static void HandleInputEvents(SDL_Joystick *joystick)
|
||||||
struct input_event events[32];
|
struct input_event events[32];
|
||||||
int i, len, code, hat_index;
|
int i, len, code, hat_index;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata->fresh) {
|
if (joystick->hwdata->fresh) {
|
||||||
PollAllValues(joystick);
|
PollAllValues(joystick);
|
||||||
joystick->hwdata->fresh = SDL_FALSE;
|
joystick->hwdata->fresh = SDL_FALSE;
|
||||||
|
@ -1515,6 +1540,8 @@ static void HandleClassicEvents(SDL_Joystick *joystick)
|
||||||
struct js_event events[32];
|
struct js_event events[32];
|
||||||
int i, len, code, hat_index;
|
int i, len, code, hat_index;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
joystick->hwdata->fresh = SDL_FALSE;
|
joystick->hwdata->fresh = SDL_FALSE;
|
||||||
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
||||||
len /= sizeof(events[0]);
|
len /= sizeof(events[0]);
|
||||||
|
@ -1557,6 +1584,8 @@ static void LINUX_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata->m_bSteamController) {
|
if (joystick->hwdata->m_bSteamController) {
|
||||||
SDL_UpdateSteamController(joystick);
|
SDL_UpdateSteamController(joystick);
|
||||||
return;
|
return;
|
||||||
|
@ -1585,6 +1614,8 @@ static void LINUX_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
/* Function to close a joystick after use */
|
/* Function to close a joystick after use */
|
||||||
static void LINUX_JoystickClose(SDL_Joystick *joystick)
|
static void LINUX_JoystickClose(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
if (joystick->hwdata->effect.id >= 0) {
|
if (joystick->hwdata->effect.id >= 0) {
|
||||||
ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
|
ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id);
|
||||||
|
@ -1645,6 +1676,8 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
|
||||||
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
||||||
unsigned int mapped;
|
unsigned int mapped;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (item->checked_mapping) {
|
if (item->checked_mapping) {
|
||||||
if (item->mapping) {
|
if (item->mapping) {
|
||||||
SDL_memcpy(out, item->mapping, sizeof(*out));
|
SDL_memcpy(out, item->mapping, sizeof(*out));
|
||||||
|
|
|
@ -29,32 +29,36 @@
|
||||||
#include "../SDL_sysjoystick.h"
|
#include "../SDL_sysjoystick.h"
|
||||||
#include "../SDL_joystick_c.h"
|
#include "../SDL_joystick_c.h"
|
||||||
|
|
||||||
static joystick_hwdata *g_VJoys = NULL;
|
static joystick_hwdata *g_VJoys SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
|
|
||||||
static joystick_hwdata *VIRTUAL_HWDataForIndex(int device_index)
|
static joystick_hwdata *VIRTUAL_HWDataForIndex(int device_index)
|
||||||
{
|
{
|
||||||
joystick_hwdata *vjoy = g_VJoys;
|
joystick_hwdata *vjoy;
|
||||||
while (vjoy) {
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
|
for (vjoy = g_VJoys; vjoy; vjoy = vjoy->next) {
|
||||||
if (device_index == 0) {
|
if (device_index == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
--device_index;
|
--device_index;
|
||||||
vjoy = vjoy->next;
|
|
||||||
}
|
}
|
||||||
return vjoy;
|
return vjoy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
|
static void VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
|
||||||
{
|
{
|
||||||
joystick_hwdata *cur = g_VJoys;
|
joystick_hwdata *cur;
|
||||||
joystick_hwdata *prev = NULL;
|
joystick_hwdata *prev = NULL;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (hwdata == NULL) {
|
if (hwdata == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove hwdata from SDL-global list */
|
/* Remove hwdata from SDL-global list */
|
||||||
while (cur) {
|
for (cur = g_VJoys; cur; prev = cur, cur = cur->next) {
|
||||||
if (hwdata == cur) {
|
if (hwdata == cur) {
|
||||||
if (prev) {
|
if (prev) {
|
||||||
prev->next = cur->next;
|
prev->next = cur->next;
|
||||||
|
@ -63,8 +67,6 @@ static void VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prev = cur;
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hwdata->joystick) {
|
if (hwdata->joystick) {
|
||||||
|
@ -98,6 +100,8 @@ int SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
|
||||||
int axis_triggerleft = -1;
|
int axis_triggerleft = -1;
|
||||||
int axis_triggerright = -1;
|
int axis_triggerright = -1;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (desc == NULL) {
|
if (desc == NULL) {
|
||||||
return SDL_InvalidParamError("desc");
|
return SDL_InvalidParamError("desc");
|
||||||
}
|
}
|
||||||
|
@ -329,11 +333,13 @@ static int VIRTUAL_JoystickInit(void)
|
||||||
|
|
||||||
static int VIRTUAL_JoystickGetCount(void)
|
static int VIRTUAL_JoystickGetCount(void)
|
||||||
{
|
{
|
||||||
|
joystick_hwdata *cur;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
joystick_hwdata *cur = g_VJoys;
|
|
||||||
while (cur) {
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
|
for (cur = g_VJoys; cur; cur = cur->next) {
|
||||||
++count;
|
++count;
|
||||||
cur = cur->next;
|
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +398,11 @@ static SDL_JoystickID VIRTUAL_JoystickGetDeviceInstanceID(int device_index)
|
||||||
|
|
||||||
static int VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
static int VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||||
{
|
{
|
||||||
joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
|
joystick_hwdata *hwdata;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
|
hwdata = VIRTUAL_HWDataForIndex(device_index);
|
||||||
if (hwdata == NULL) {
|
if (hwdata == NULL) {
|
||||||
return SDL_SetError("No such device");
|
return SDL_SetError("No such device");
|
||||||
}
|
}
|
||||||
|
@ -409,6 +419,8 @@ static int VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_r
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
joystick_hwdata *hwdata = joystick->hwdata;
|
||||||
if (hwdata->desc.Rumble) {
|
if (hwdata->desc.Rumble) {
|
||||||
|
@ -427,6 +439,8 @@ static int VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_ru
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
joystick_hwdata *hwdata = joystick->hwdata;
|
||||||
if (hwdata->desc.RumbleTriggers) {
|
if (hwdata->desc.RumbleTriggers) {
|
||||||
|
@ -443,9 +457,12 @@ static int VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_ru
|
||||||
|
|
||||||
static Uint32 VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick)
|
static Uint32 VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
joystick_hwdata *hwdata;
|
||||||
Uint32 caps = 0;
|
Uint32 caps = 0;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
|
hwdata = joystick->hwdata;
|
||||||
if (hwdata) {
|
if (hwdata) {
|
||||||
if (hwdata->desc.Rumble) {
|
if (hwdata->desc.Rumble) {
|
||||||
caps |= SDL_JOYCAP_RUMBLE;
|
caps |= SDL_JOYCAP_RUMBLE;
|
||||||
|
@ -464,6 +481,8 @@ static int VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
joystick_hwdata *hwdata = joystick->hwdata;
|
||||||
if (hwdata->desc.SetLED) {
|
if (hwdata->desc.SetLED) {
|
||||||
|
@ -482,6 +501,8 @@ static int VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data,
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
joystick_hwdata *hwdata = joystick->hwdata;
|
||||||
if (hwdata->desc.SendEffect) {
|
if (hwdata->desc.SendEffect) {
|
||||||
|
@ -506,6 +527,8 @@ static void VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
joystick_hwdata *hwdata;
|
joystick_hwdata *hwdata;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick == NULL) {
|
if (joystick == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -532,6 +555,8 @@ static void VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
|
|
||||||
static void VIRTUAL_JoystickClose(SDL_Joystick *joystick)
|
static void VIRTUAL_JoystickClose(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
if (joystick->hwdata) {
|
if (joystick->hwdata) {
|
||||||
joystick_hwdata *hwdata = joystick->hwdata;
|
joystick_hwdata *hwdata = joystick->hwdata;
|
||||||
hwdata->joystick = NULL;
|
hwdata->joystick = NULL;
|
||||||
|
@ -541,6 +566,8 @@ static void VIRTUAL_JoystickClose(SDL_Joystick *joystick)
|
||||||
|
|
||||||
static void VIRTUAL_JoystickQuit(void)
|
static void VIRTUAL_JoystickQuit(void)
|
||||||
{
|
{
|
||||||
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
while (g_VJoys) {
|
while (g_VJoys) {
|
||||||
VIRTUAL_FreeHWData(g_VJoys);
|
VIRTUAL_FreeHWData(g_VJoys);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,24 +51,20 @@ static SDL_SensorDriver *SDL_sensor_drivers[] = {
|
||||||
&SDL_DUMMY_SensorDriver
|
&SDL_DUMMY_SensorDriver
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
static SDL_Sensor *SDL_sensors = NULL;
|
|
||||||
static SDL_bool SDL_updating_sensor = SDL_FALSE;
|
|
||||||
static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
|
static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
|
||||||
static SDL_atomic_t SDL_next_sensor_instance_id;
|
static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL;
|
||||||
|
static SDL_atomic_t SDL_next_sensor_instance_id SDL_GUARDED_BY(SDL_sensor_lock);
|
||||||
|
static SDL_bool SDL_updating_sensor SDL_GUARDED_BY(SDL_sensor_lock) = SDL_FALSE;
|
||||||
|
|
||||||
void SDL_LockSensors(void)
|
void SDL_LockSensors(void) SDL_ACQUIRE(SDL_sensor_lock)
|
||||||
{
|
{
|
||||||
if (SDL_sensor_lock) {
|
|
||||||
SDL_LockMutex(SDL_sensor_lock);
|
SDL_LockMutex(SDL_sensor_lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SDL_UnlockSensors(void)
|
void SDL_UnlockSensors(void) SDL_RELEASE(SDL_sensor_lock)
|
||||||
{
|
{
|
||||||
if (SDL_sensor_lock) {
|
|
||||||
SDL_UnlockMutex(SDL_sensor_lock);
|
SDL_UnlockMutex(SDL_sensor_lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int SDL_SensorInit(void)
|
int SDL_SensorInit(void)
|
||||||
{
|
{
|
||||||
|
@ -145,8 +141,7 @@ static SDL_bool SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver *
|
||||||
/*
|
/*
|
||||||
* Get the implementation dependent name of a sensor
|
* Get the implementation dependent name of a sensor
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *SDL_SensorGetDeviceName(int device_index)
|
||||||
SDL_SensorGetDeviceName(int device_index)
|
|
||||||
{
|
{
|
||||||
SDL_SensorDriver *driver;
|
SDL_SensorDriver *driver;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
|
@ -161,8 +156,7 @@ SDL_SensorGetDeviceName(int device_index)
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SensorType
|
SDL_SensorType SDL_SensorGetDeviceType(int device_index)
|
||||||
SDL_SensorGetDeviceType(int device_index)
|
|
||||||
{
|
{
|
||||||
SDL_SensorDriver *driver;
|
SDL_SensorDriver *driver;
|
||||||
SDL_SensorType type = SDL_SENSOR_INVALID;
|
SDL_SensorType type = SDL_SENSOR_INVALID;
|
||||||
|
@ -190,8 +184,7 @@ int SDL_SensorGetDeviceNonPortableType(int device_index)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SensorID
|
SDL_SensorID SDL_SensorGetDeviceInstanceID(int device_index)
|
||||||
SDL_SensorGetDeviceInstanceID(int device_index)
|
|
||||||
{
|
{
|
||||||
SDL_SensorDriver *driver;
|
SDL_SensorDriver *driver;
|
||||||
SDL_SensorID instance_id = -1;
|
SDL_SensorID instance_id = -1;
|
||||||
|
@ -212,8 +205,7 @@ SDL_SensorGetDeviceInstanceID(int device_index)
|
||||||
*
|
*
|
||||||
* This function returns a sensor identifier, or NULL if an error occurred.
|
* This function returns a sensor identifier, or NULL if an error occurred.
|
||||||
*/
|
*/
|
||||||
SDL_Sensor *
|
SDL_Sensor *SDL_SensorOpen(int device_index)
|
||||||
SDL_SensorOpen(int device_index)
|
|
||||||
{
|
{
|
||||||
SDL_SensorDriver *driver;
|
SDL_SensorDriver *driver;
|
||||||
SDL_SensorID instance_id;
|
SDL_SensorID instance_id;
|
||||||
|
@ -284,8 +276,7 @@ SDL_SensorOpen(int device_index)
|
||||||
/*
|
/*
|
||||||
* Find the SDL_Sensor that owns this instance id
|
* Find the SDL_Sensor that owns this instance id
|
||||||
*/
|
*/
|
||||||
SDL_Sensor *
|
SDL_Sensor *SDL_SensorFromInstanceID(SDL_SensorID instance_id)
|
||||||
SDL_SensorFromInstanceID(SDL_SensorID instance_id)
|
|
||||||
{
|
{
|
||||||
SDL_Sensor *sensor;
|
SDL_Sensor *sensor;
|
||||||
|
|
||||||
|
@ -319,8 +310,7 @@ static int SDL_PrivateSensorValid(SDL_Sensor *sensor)
|
||||||
/*
|
/*
|
||||||
* Get the friendly name of this sensor
|
* Get the friendly name of this sensor
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *SDL_SensorGetName(SDL_Sensor *sensor)
|
||||||
SDL_SensorGetName(SDL_Sensor *sensor)
|
|
||||||
{
|
{
|
||||||
if (!SDL_PrivateSensorValid(sensor)) {
|
if (!SDL_PrivateSensorValid(sensor)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -332,8 +322,7 @@ SDL_SensorGetName(SDL_Sensor *sensor)
|
||||||
/*
|
/*
|
||||||
* Get the type of this sensor
|
* Get the type of this sensor
|
||||||
*/
|
*/
|
||||||
SDL_SensorType
|
SDL_SensorType SDL_SensorGetType(SDL_Sensor *sensor)
|
||||||
SDL_SensorGetType(SDL_Sensor *sensor)
|
|
||||||
{
|
{
|
||||||
if (!SDL_PrivateSensorValid(sensor)) {
|
if (!SDL_PrivateSensorValid(sensor)) {
|
||||||
return SDL_SENSOR_INVALID;
|
return SDL_SENSOR_INVALID;
|
||||||
|
@ -357,8 +346,7 @@ int SDL_SensorGetNonPortableType(SDL_Sensor *sensor)
|
||||||
/*
|
/*
|
||||||
* Get the instance id for this opened sensor
|
* Get the instance id for this opened sensor
|
||||||
*/
|
*/
|
||||||
SDL_SensorID
|
SDL_SensorID SDL_SensorGetInstanceID(SDL_Sensor *sensor)
|
||||||
SDL_SensorGetInstanceID(SDL_Sensor *sensor)
|
|
||||||
{
|
{
|
||||||
if (!SDL_PrivateSensorValid(sensor)) {
|
if (!SDL_PrivateSensorValid(sensor)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -448,11 +436,11 @@ void SDL_SensorQuit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
SDL_LockSensors();
|
||||||
|
|
||||||
/* Make sure we're not getting called in the middle of updating sensors */
|
/* Make sure we're not getting called in the middle of updating sensors */
|
||||||
SDL_assert(!SDL_updating_sensor);
|
SDL_assert(!SDL_updating_sensor);
|
||||||
|
|
||||||
SDL_LockSensors();
|
|
||||||
|
|
||||||
/* Stop the event polling */
|
/* Stop the event polling */
|
||||||
while (SDL_sensors) {
|
while (SDL_sensors) {
|
||||||
SDL_sensors->ref_count = 1;
|
SDL_sensors->ref_count = 1;
|
||||||
|
@ -525,15 +513,10 @@ void SDL_SensorUpdate(void)
|
||||||
|
|
||||||
SDL_updating_sensor = SDL_TRUE;
|
SDL_updating_sensor = SDL_TRUE;
|
||||||
|
|
||||||
/* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
|
|
||||||
SDL_UnlockSensors();
|
|
||||||
|
|
||||||
for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
|
for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
|
||||||
sensor->driver->Update(sensor);
|
sensor->driver->Update(sensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LockSensors();
|
|
||||||
|
|
||||||
SDL_updating_sensor = SDL_FALSE;
|
SDL_updating_sensor = SDL_FALSE;
|
||||||
|
|
||||||
/* If any sensors were closed while updating, free them here */
|
/* If any sensors were closed while updating, free them here */
|
||||||
|
|
|
@ -71,7 +71,7 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the mutex */
|
/* Lock the mutex */
|
||||||
int SDL_LockMutex(SDL_mutex *mutex)
|
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
#if SDL_THREADS_DISABLED
|
#if SDL_THREADS_DISABLED
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -79,7 +79,7 @@ int SDL_LockMutex(SDL_mutex *mutex)
|
||||||
SDL_threadID this_thread;
|
SDL_threadID this_thread;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this_thread = SDL_ThreadID();
|
this_thread = SDL_ThreadID();
|
||||||
|
@ -109,7 +109,7 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
SDL_threadID this_thread;
|
SDL_threadID this_thread;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this_thread = SDL_ThreadID();
|
this_thread = SDL_ThreadID();
|
||||||
|
@ -132,13 +132,13 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
int SDL_mutexV(SDL_mutex *mutex)
|
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
#if SDL_THREADS_DISABLED
|
#if SDL_THREADS_DISABLED
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't own the mutex, we can't unlock it */
|
/* If we don't own the mutex, we can't unlock it */
|
||||||
|
|
|
@ -51,10 +51,10 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the mutex */
|
/* Lock the mutex */
|
||||||
int SDL_LockMutex(SDL_mutex *mutex)
|
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_SetError("Passed a NULL mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveLock_Lock(&mutex->lock);
|
RecursiveLock_Lock(&mutex->lock);
|
||||||
|
@ -66,17 +66,17 @@ int SDL_LockMutex(SDL_mutex *mutex)
|
||||||
int SDL_TryLockMutex(SDL_mutex *mutex)
|
int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_SetError("Passed a NULL mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RecursiveLock_TryLock(&mutex->lock);
|
return RecursiveLock_TryLock(&mutex->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
int SDL_mutexV(SDL_mutex *mutex)
|
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_SetError("Passed a NULL mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveLock_Unlock(&mutex->lock);
|
RecursiveLock_Unlock(&mutex->lock);
|
||||||
|
|
|
@ -68,27 +68,11 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to lock the mutex */
|
|
||||||
#if 0
|
|
||||||
int
|
|
||||||
SDL_TryLockMutex(SDL_mutex * mutex)
|
|
||||||
{
|
|
||||||
if (mutex == NULL)
|
|
||||||
{
|
|
||||||
SDL_SetError("Passed a NULL mutex.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not yet implemented.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Lock the mutex */
|
/* Lock the mutex */
|
||||||
int SDL_LockMutex(SDL_mutex *mutex)
|
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RMutex rmutex;
|
RMutex rmutex;
|
||||||
|
@ -98,11 +82,26 @@ int SDL_LockMutex(SDL_mutex *mutex)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try to lock the mutex */
|
||||||
|
#if 0
|
||||||
|
int
|
||||||
|
SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
|
{
|
||||||
|
if (mutex == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not yet implemented.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
int SDL_UnlockMutex(SDL_mutex *mutex)
|
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RMutex rmutex;
|
RMutex rmutex;
|
||||||
|
|
|
@ -67,13 +67,13 @@ SDL_DestroyMutex(SDL_mutex * mutex)
|
||||||
|
|
||||||
/* Lock the mutex */
|
/* Lock the mutex */
|
||||||
int
|
int
|
||||||
SDL_LockMutex(SDL_mutex * mutex)
|
SDL_LockMutex(SDL_mutex * mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMTX hMtx = (HMTX)mutex;
|
HMTX hMtx = (HMTX)mutex;
|
||||||
|
|
||||||
if (hMtx == NULLHANDLE)
|
if (hMtx == NULLHANDLE)
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
|
|
||||||
ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT);
|
ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT);
|
||||||
if (ulRC != NO_ERROR) {
|
if (ulRC != NO_ERROR) {
|
||||||
|
@ -92,7 +92,7 @@ SDL_TryLockMutex(SDL_mutex * mutex)
|
||||||
HMTX hMtx = (HMTX)mutex;
|
HMTX hMtx = (HMTX)mutex;
|
||||||
|
|
||||||
if (hMtx == NULLHANDLE)
|
if (hMtx == NULLHANDLE)
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
|
|
||||||
ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN);
|
ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN);
|
||||||
|
|
||||||
|
@ -109,13 +109,13 @@ SDL_TryLockMutex(SDL_mutex * mutex)
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
int
|
int
|
||||||
SDL_UnlockMutex(SDL_mutex * mutex)
|
SDL_UnlockMutex(SDL_mutex * mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
ULONG ulRC;
|
ULONG ulRC;
|
||||||
HMTX hMtx = (HMTX)mutex;
|
HMTX hMtx = (HMTX)mutex;
|
||||||
|
|
||||||
if (hMtx == NULLHANDLE)
|
if (hMtx == NULLHANDLE)
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
|
|
||||||
ulRC = DosReleaseMutexSem(hMtx);
|
ulRC = DosReleaseMutexSem(hMtx);
|
||||||
if (ulRC != NO_ERROR)
|
if (ulRC != NO_ERROR)
|
||||||
|
|
|
@ -73,6 +73,27 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lock the mutex */
|
||||||
|
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
|
{
|
||||||
|
#if SDL_THREADS_DISABLED
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
SceInt32 res = 0;
|
||||||
|
|
||||||
|
if (mutex == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
|
||||||
|
if (res != SCE_KERNEL_ERROR_OK) {
|
||||||
|
return SDL_SetError("Error trying to lock mutex: %lx", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif /* SDL_THREADS_DISABLED */
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to lock the mutex */
|
/* Try to lock the mutex */
|
||||||
int SDL_TryLockMutex(SDL_mutex *mutex)
|
int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
{
|
{
|
||||||
|
@ -80,8 +101,9 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
SceInt32 res = 0;
|
SceInt32 res = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = sceKernelTryLockLwMutex(&mutex->lock, 1);
|
res = sceKernelTryLockLwMutex(&mutex->lock, 1);
|
||||||
|
@ -101,28 +123,8 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
#endif /* SDL_THREADS_DISABLED */
|
#endif /* SDL_THREADS_DISABLED */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the mutex */
|
|
||||||
int SDL_mutexP(SDL_mutex *mutex)
|
|
||||||
{
|
|
||||||
#if SDL_THREADS_DISABLED
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
SceInt32 res = 0;
|
|
||||||
if (mutex == NULL) {
|
|
||||||
return SDL_InvalidParamError("mutex");
|
|
||||||
}
|
|
||||||
|
|
||||||
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
|
|
||||||
if (res != SCE_KERNEL_ERROR_OK) {
|
|
||||||
return SDL_SetError("Error trying to lock mutex: %lx", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif /* SDL_THREADS_DISABLED */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
int SDL_mutexV(SDL_mutex *mutex)
|
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
#if SDL_THREADS_DISABLED
|
#if SDL_THREADS_DISABLED
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -130,7 +132,7 @@ int SDL_mutexV(SDL_mutex *mutex)
|
||||||
SceInt32 res = 0;
|
SceInt32 res = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = sceKernelUnlockLwMutex(&mutex->lock, 1);
|
res = sceKernelUnlockLwMutex(&mutex->lock, 1);
|
||||||
|
@ -141,6 +143,7 @@ int SDL_mutexV(SDL_mutex *mutex)
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* SDL_THREADS_DISABLED */
|
#endif /* SDL_THREADS_DISABLED */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SDL_THREAD_PSP */
|
#endif /* SDL_THREAD_PSP */
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
|
@ -76,14 +76,14 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the mutex */
|
/* Lock the mutex */
|
||||||
int SDL_LockMutex(SDL_mutex *mutex)
|
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
#if FAKE_RECURSIVE_MUTEX
|
#if FAKE_RECURSIVE_MUTEX
|
||||||
pthread_t this_thread;
|
pthread_t this_thread;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FAKE_RECURSIVE_MUTEX
|
#if FAKE_RECURSIVE_MUTEX
|
||||||
|
@ -119,7 +119,7 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
@ -155,10 +155,10 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_UnlockMutex(SDL_mutex *mutex)
|
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FAKE_RECURSIVE_MUTEX
|
#if FAKE_RECURSIVE_MUTEX
|
||||||
|
|
|
@ -56,12 +56,12 @@ SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the semaphore */
|
/* Lock the mutex */
|
||||||
extern "C" int
|
extern "C" int
|
||||||
SDL_mutexP(SDL_mutex *mutex)
|
SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -76,8 +76,9 @@ SDL_mutexP(SDL_mutex *mutex)
|
||||||
int SDL_TryLockMutex(SDL_mutex *mutex)
|
int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex->cpp_mutex.try_lock() == false) {
|
if (mutex->cpp_mutex.try_lock() == false) {
|
||||||
|
@ -88,10 +89,10 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
extern "C" int
|
extern "C" int
|
||||||
SDL_mutexV(SDL_mutex *mutex)
|
SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex->cpp_mutex.unlock();
|
mutex->cpp_mutex.unlock();
|
||||||
|
|
|
@ -69,6 +69,27 @@ void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lock the mutex */
|
||||||
|
int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
|
{
|
||||||
|
#if SDL_THREADS_DISABLED
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
SceInt32 res = 0;
|
||||||
|
|
||||||
|
if (mutex == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
|
||||||
|
if (res != SCE_KERNEL_OK) {
|
||||||
|
return SDL_SetError("Error trying to lock mutex: %x", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif /* SDL_THREADS_DISABLED */
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to lock the mutex */
|
/* Try to lock the mutex */
|
||||||
int SDL_TryLockMutex(SDL_mutex *mutex)
|
int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
{
|
{
|
||||||
|
@ -76,8 +97,9 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
SceInt32 res = 0;
|
SceInt32 res = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = sceKernelTryLockLwMutex(&mutex->lock, 1);
|
res = sceKernelTryLockLwMutex(&mutex->lock, 1);
|
||||||
|
@ -97,28 +119,8 @@ int SDL_TryLockMutex(SDL_mutex *mutex)
|
||||||
#endif /* SDL_THREADS_DISABLED */
|
#endif /* SDL_THREADS_DISABLED */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the mutex */
|
|
||||||
int SDL_mutexP(SDL_mutex *mutex)
|
|
||||||
{
|
|
||||||
#if SDL_THREADS_DISABLED
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
SceInt32 res = 0;
|
|
||||||
if (mutex == NULL) {
|
|
||||||
return SDL_InvalidParamError("mutex");
|
|
||||||
}
|
|
||||||
|
|
||||||
res = sceKernelLockLwMutex(&mutex->lock, 1, NULL);
|
|
||||||
if (res != SCE_KERNEL_OK) {
|
|
||||||
return SDL_SetError("Error trying to lock mutex: %x", res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif /* SDL_THREADS_DISABLED */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
int SDL_mutexV(SDL_mutex *mutex)
|
int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
#if SDL_THREADS_DISABLED
|
#if SDL_THREADS_DISABLED
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -126,7 +128,7 @@ int SDL_mutexV(SDL_mutex *mutex)
|
||||||
SceInt32 res = 0;
|
SceInt32 res = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = sceKernelUnlockLwMutex(&mutex->lock, 1);
|
res = sceKernelUnlockLwMutex(&mutex->lock, 1);
|
||||||
|
|
|
@ -77,13 +77,13 @@ static void SDL_DestroyMutex_srw(SDL_mutex *mutex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SDL_LockMutex_srw(SDL_mutex *_mutex)
|
static int SDL_LockMutex_srw(SDL_mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
|
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
|
||||||
DWORD this_thread;
|
DWORD this_thread;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this_thread = GetCurrentThreadId();
|
this_thread = GetCurrentThreadId();
|
||||||
|
@ -109,7 +109,7 @@ static int SDL_TryLockMutex_srw(SDL_mutex *_mutex)
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this_thread = GetCurrentThreadId();
|
this_thread = GetCurrentThreadId();
|
||||||
|
@ -127,12 +127,12 @@ static int SDL_TryLockMutex_srw(SDL_mutex *_mutex)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SDL_UnlockMutex_srw(SDL_mutex *_mutex)
|
static int SDL_UnlockMutex_srw(SDL_mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
|
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
|
||||||
|
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mutex->owner == GetCurrentThreadId()) {
|
if (mutex->owner == GetCurrentThreadId()) {
|
||||||
|
@ -192,11 +192,11 @@ static void SDL_DestroyMutex_cs(SDL_mutex *mutex_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the mutex */
|
/* Lock the mutex */
|
||||||
static int SDL_LockMutex_cs(SDL_mutex *mutex_)
|
static int SDL_LockMutex_cs(SDL_mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
|
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterCriticalSection(&mutex->cs);
|
EnterCriticalSection(&mutex->cs);
|
||||||
|
@ -209,7 +209,7 @@ static int SDL_TryLockMutex_cs(SDL_mutex *mutex_)
|
||||||
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
|
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryEnterCriticalSection(&mutex->cs) == 0) {
|
if (TryEnterCriticalSection(&mutex->cs) == 0) {
|
||||||
|
@ -219,11 +219,11 @@ static int SDL_TryLockMutex_cs(SDL_mutex *mutex_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock the mutex */
|
/* Unlock the mutex */
|
||||||
static int SDL_UnlockMutex_cs(SDL_mutex *mutex_)
|
static int SDL_UnlockMutex_cs(SDL_mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
|
||||||
{
|
{
|
||||||
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
|
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
|
||||||
if (mutex == NULL) {
|
if (mutex == NULL) {
|
||||||
return SDL_InvalidParamError("mutex");
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&mutex->cs);
|
LeaveCriticalSection(&mutex->cs);
|
||||||
|
|
Loading…
Reference in a new issue