From 76cc24e34a6436a71f1fd410de33dfe128e8705b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 14 Nov 2023 10:28:19 -0800 Subject: [PATCH] Added SDL_HINT_JOYSTICK_IOKIT and SDL_HINT_JOYSTICK_MFI to control whether the IOKit and GCController drivers should be used for joystick support. This can be used to work around issues where the Apple GCController driver doesn't work for some controllers but there's no way to know which GCController maps to which IOKit device. (cherry picked from commit 708f18d49ef6975769865d247e2ce4da6ce8da76) --- include/SDL_hints.h | 18 ++++++++++++++++++ src/joystick/darwin/SDL_iokitjoystick.c | 14 ++++++++------ src/joystick/iphoneos/SDL_mfijoystick.m | 8 ++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 00beef51e..8a1c433e0 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -965,6 +965,24 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED "SDL_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED" +/** + * A variable controlling whether IOKit should be used for controller handling. + * + * This variable can be set to the following values: + * "0" - IOKit is not used + * "1" - IOKit is used (the default) + */ +#define SDL_HINT_JOYSTICK_IOKIT "SDL_JOYSTICK_IOKIT" + +/** + * A variable controlling whether GCController should be used for controller handling. + * + * This variable can be set to the following values: + * "0" - GCController is not used + * "1" - GCController is used (the default) + */ +#define SDL_HINT_JOYSTICK_MFI "SDL_JOYSTICK_MFI" + /** * \brief A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInput-capable devices. * diff --git a/src/joystick/darwin/SDL_iokitjoystick.c b/src/joystick/darwin/SDL_iokitjoystick.c index f5cd7151e..e68adc720 100644 --- a/src/joystick/darwin/SDL_iokitjoystick.c +++ b/src/joystick/darwin/SDL_iokitjoystick.c @@ -657,8 +657,8 @@ static SDL_bool CreateHIDManager(void) static int DARWIN_JoystickInit(void) { - if (gpDeviceList) { - return SDL_SetError("Joystick: Device list already inited."); + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_IOKIT, SDL_TRUE)) { + return 0; } if (!CreateHIDManager()) { @@ -694,10 +694,12 @@ static void DARWIN_JoystickDetect(void) } } - /* run this after the checks above so we don't set device->removed and delete the device before - DARWIN_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device */ - while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { - /* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */ + if (hidman) { + /* run this after the checks above so we don't set device->removed and delete the device before + DARWIN_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device */ + while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { + /* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */ + } } } diff --git a/src/joystick/iphoneos/SDL_mfijoystick.m b/src/joystick/iphoneos/SDL_mfijoystick.m index b9aeed703..9e5c98975 100644 --- a/src/joystick/iphoneos/SDL_mfijoystick.m +++ b/src/joystick/iphoneos/SDL_mfijoystick.m @@ -663,6 +663,10 @@ static void SDLCALL SDL_AppleTVRemoteRotationHintChanged(void *udata, const char static int IOS_JoystickInit(void) { + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_MFI, SDL_TRUE)) { + return 0; + } + #if defined(__MACOSX__) #if _SDL_HAS_BUILTIN(__builtin_available) if (@available(macOS 10.16, *)) { @@ -1680,6 +1684,10 @@ static SDL_bool IOS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMappi #if defined(SDL_JOYSTICK_MFI) && defined(__MACOSX__) SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device) { + if (!connectObserver) { + return SDL_FALSE; + } + if (@available(macOS 10.16, *)) { const int MAX_ATTEMPTS = 3; for (int attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {