mirror of
https://github.com/encounter/SDL.git
synced 2025-05-18 21:31:35 +00:00
Make sure we completely unlock joysticks when opening HIDAPI devices
Also lock the joysticks when adding and removing Android joysticks
This commit is contained in:
parent
47ba997f06
commit
333935ff3f
@ -168,10 +168,16 @@ SDL_UnlockJoysticks(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_bool
|
||||||
|
SDL_JoysticksLocked(void)
|
||||||
|
{
|
||||||
|
return (SDL_joysticks_locked > 0) ? SDL_TRUE : SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SDL_AssertJoysticksLocked(void)
|
SDL_AssertJoysticksLocked(void)
|
||||||
{
|
{
|
||||||
SDL_assert(SDL_joysticks_locked > 0);
|
SDL_assert(SDL_JoysticksLocked());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -45,6 +45,9 @@ extern SDL_bool SDL_JoysticksInitialized(void);
|
|||||||
/* Return whether the joystick system is shutting down */
|
/* Return whether the joystick system is shutting down */
|
||||||
extern SDL_bool SDL_JoysticksQuitting(void);
|
extern SDL_bool SDL_JoysticksQuitting(void);
|
||||||
|
|
||||||
|
/* Return whether the joysticks are currently locked */
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -317,23 +317,25 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
|
|||||||
SDL_JoystickGUID guid;
|
SDL_JoystickGUID guid;
|
||||||
int i;
|
int i;
|
||||||
int axis_mask;
|
int axis_mask;
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
|
||||||
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
|
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
|
||||||
/* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
|
/* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
|
||||||
if (naxes < 2 && nhats < 1) {
|
if (naxes < 2 && nhats < 1) {
|
||||||
return -1;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JoystickByDeviceId(device_id) != NULL || name == NULL) {
|
if (JoystickByDeviceId(device_id) != NULL || name == NULL) {
|
||||||
return -1;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDL_JOYSTICK_HIDAPI
|
#ifdef SDL_JOYSTICK_HIDAPI
|
||||||
if (HIDAPI_IsDevicePresent(vendor_id, product_id, 0, name)) {
|
if (HIDAPI_IsDevicePresent(vendor_id, product_id, 0, name)) {
|
||||||
/* The HIDAPI driver is taking care of this device */
|
/* The HIDAPI driver is taking care of this device */
|
||||||
return -1;
|
goto done;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -377,7 +379,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
|
|||||||
|
|
||||||
item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
|
item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
return -1;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_zerop(item);
|
SDL_zerop(item);
|
||||||
@ -385,8 +387,8 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
|
|||||||
item->device_id = device_id;
|
item->device_id = device_id;
|
||||||
item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name);
|
item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name);
|
||||||
if (item->name == NULL) {
|
if (item->name == NULL) {
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
return -1;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->is_accelerometer = is_accelerometer;
|
item->is_accelerometer = is_accelerometer;
|
||||||
@ -415,11 +417,16 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
|
|||||||
|
|
||||||
SDL_PrivateJoystickAdded(item->device_instance);
|
SDL_PrivateJoystickAdded(item->device_instance);
|
||||||
|
|
||||||
|
result = numjoysticks;
|
||||||
|
|
||||||
#ifdef DEBUG_JOYSTICK
|
#ifdef DEBUG_JOYSTICK
|
||||||
SDL_Log("Added joystick %s with device_id %d", item->name, device_id);
|
SDL_Log("Added joystick %s with device_id %d", item->name, device_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return numjoysticks;
|
done:
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -427,7 +434,10 @@ Android_RemoveJoystick(int device_id)
|
|||||||
{
|
{
|
||||||
SDL_joylist_item *item = SDL_joylist;
|
SDL_joylist_item *item = SDL_joylist;
|
||||||
SDL_joylist_item *prev = NULL;
|
SDL_joylist_item *prev = NULL;
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
|
||||||
/* Don't call JoystickByDeviceId here or there'll be an infinite loop! */
|
/* Don't call JoystickByDeviceId here or there'll be an infinite loop! */
|
||||||
while (item != NULL) {
|
while (item != NULL) {
|
||||||
if (item->device_id == device_id) {
|
if (item->device_id == device_id) {
|
||||||
@ -438,7 +448,7 @@ Android_RemoveJoystick(int device_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
return -1;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->joystick) {
|
if (item->joystick) {
|
||||||
@ -460,13 +470,19 @@ Android_RemoveJoystick(int device_id)
|
|||||||
|
|
||||||
SDL_PrivateJoystickRemoved(item->device_instance);
|
SDL_PrivateJoystickRemoved(item->device_instance);
|
||||||
|
|
||||||
|
result = numjoysticks;
|
||||||
|
|
||||||
#ifdef DEBUG_JOYSTICK
|
#ifdef DEBUG_JOYSTICK
|
||||||
SDL_Log("Removed joystick with device_id %d", device_id);
|
SDL_Log("Removed joystick with device_id %d", device_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_free(item->name);
|
SDL_free(item->name);
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
return numjoysticks;
|
|
||||||
|
done:
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -368,15 +368,21 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed)
|
|||||||
*
|
*
|
||||||
* See https://github.com/libsdl-org/SDL/issues/6347 for details
|
* See https://github.com/libsdl-org/SDL/issues/6347 for details
|
||||||
*/
|
*/
|
||||||
|
int lock_count = 0;
|
||||||
SDL_HIDAPI_Device *curr;
|
SDL_HIDAPI_Device *curr;
|
||||||
SDL_hid_device *dev;
|
SDL_hid_device *dev;
|
||||||
char *path;
|
char *path = SDL_strdup(device->path);
|
||||||
|
|
||||||
SDL_AssertJoysticksLocked();
|
SDL_AssertJoysticksLocked();
|
||||||
path = SDL_strdup(device->path);
|
while (SDL_JoysticksLocked()) {
|
||||||
SDL_UnlockJoysticks();
|
++lock_count;
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
}
|
||||||
dev = SDL_hid_open_path(path, 0);
|
dev = SDL_hid_open_path(path, 0);
|
||||||
SDL_LockJoysticks();
|
while (lock_count > 0) {
|
||||||
|
--lock_count;
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
}
|
||||||
SDL_free(path);
|
SDL_free(path);
|
||||||
|
|
||||||
/* Make sure the device didn't get removed while opening the HID path */
|
/* Make sure the device didn't get removed while opening the HID path */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user