Allow libudev for HIDAPI joystick to be disabled at runtime

As already explained in the previous commit "joystick: Allow libudev to
be disabled at runtime" (13e7d1a9), libudev can fail in a container.

To make it easier to experiment with, we add a new environment variable
"SDL_HIDAPI_JOYSTICK_DISABLE_UDEV" that disables udev and let it
fallback to the device enumeration using polling.

Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
This commit is contained in:
Ludovico de Nittis 2021-02-16 11:50:20 +01:00 committed by Sam Lantinga
parent 0052339b66
commit b17242bf98

View File

@ -28,6 +28,7 @@
#include "SDL_thread.h" #include "SDL_thread.h"
#include "SDL_timer.h" #include "SDL_timer.h"
#include "SDL_joystick.h" #include "SDL_joystick.h"
#include "SDL_log.h"
#include "../SDL_sysjoystick.h" #include "../SDL_sysjoystick.h"
#include "SDL_hidapijoystick_c.h" #include "SDL_hidapijoystick_c.h"
#include "SDL_hidapi_rumble.h" #include "SDL_hidapi_rumble.h"
@ -53,6 +54,15 @@
#endif #endif
#endif #endif
typedef enum
{
ENUMERATION_UNSET,
ENUMERATION_LIBUDEV,
ENUMERATION_FALLBACK
} LinuxEnumerationMethod;
static LinuxEnumerationMethod linux_enumeration_method = ENUMERATION_UNSET;
struct joystick_hwdata struct joystick_hwdata
{ {
SDL_HIDAPI_Device *device; SDL_HIDAPI_Device *device;
@ -273,6 +283,7 @@ HIDAPI_InitializeDiscovery()
#endif // __MACOSX__ #endif // __MACOSX__
#if defined(SDL_USE_LIBUDEV) #if defined(SDL_USE_LIBUDEV)
if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
SDL_HIDAPI_discovery.m_pUdev = NULL; SDL_HIDAPI_discovery.m_pUdev = NULL;
SDL_HIDAPI_discovery.m_pUdevMonitor = NULL; SDL_HIDAPI_discovery.m_pUdevMonitor = NULL;
SDL_HIDAPI_discovery.m_nUdevFd = -1; SDL_HIDAPI_discovery.m_nUdevFd = -1;
@ -289,7 +300,7 @@ HIDAPI_InitializeDiscovery()
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE; SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
} }
} }
}
#endif /* SDL_USE_LIBUDEV */ #endif /* SDL_USE_LIBUDEV */
} }
@ -331,6 +342,7 @@ HIDAPI_UpdateDiscovery()
#endif #endif
#if defined(SDL_USE_LIBUDEV) #if defined(SDL_USE_LIBUDEV)
if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) { if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) {
/* Drain all notification events. /* Drain all notification events.
* We don't expect a lot of device notifications so just * We don't expect a lot of device notifications so just
@ -355,7 +367,8 @@ HIDAPI_UpdateDiscovery()
} }
} }
} }
#endif }
#endif /* SDL_USE_LIBUDEV */
} }
static void static void
@ -379,7 +392,8 @@ HIDAPI_ShutdownDiscovery()
#endif #endif
#if defined(SDL_USE_LIBUDEV) #if defined(SDL_USE_LIBUDEV)
if (usyms) { if (linux_enumeration_method == ENUMERATION_LIBUDEV &&
usyms) {
if (SDL_HIDAPI_discovery.m_pUdevMonitor) { if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor); usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
} }
@ -600,6 +614,20 @@ HIDAPI_JoystickInit(void)
return 0; return 0;
} }
#if defined(SDL_USE_LIBUDEV)
if (linux_enumeration_method == ENUMERATION_UNSET) {
if (SDL_getenv("SDL_HIDAPI_JOYSTICK_DISABLE_UDEV") != NULL) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"udev disabled by SDL_HIDAPI_JOYSTICK_DISABLE_UDEV");
linux_enumeration_method = ENUMERATION_FALLBACK;
} else {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Using udev for HIDAPI joystick device discovery");
linux_enumeration_method = ENUMERATION_LIBUDEV;
}
}
#endif
#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__) #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)
/* The hidapi framwork is weak-linked on Apple platforms */ /* The hidapi framwork is weak-linked on Apple platforms */
int HID_API_EXPORT HID_API_CALL hid_init(void) __attribute__((weak_import)); int HID_API_EXPORT HID_API_CALL hid_init(void) __attribute__((weak_import));