Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/hidapi/SDL_hidapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

#ifdef __WEBOS__
#include "../joystick/webos/dev_presence.h"
#include "../joystick/webos/uevent_monitor.h"
#endif /* __WEBOS__ */

#include "../core/linux/SDL_udev.h"
Expand Down Expand Up @@ -84,6 +85,7 @@ typedef enum
ENUMERATION_FALLBACK,
#ifdef __WEBOS__
ENUMERATION_POLLING,
ENUMERATION_NETLINK,
#endif
} LinuxEnumerationMethod;

Expand Down Expand Up @@ -125,6 +127,7 @@ static struct
#endif
#ifdef __WEBOS__
Uint32 m_unPresenceFlags;
SDL_webOSUeventMonitor *m_pUeventMonitor;
#endif
} SDL_HIDAPI_discovery;

Expand Down Expand Up @@ -343,7 +346,13 @@ static void HIDAPI_InitializeDiscovery(void)
} else
#endif /* SDL_USE_LIBUDEV */
#ifdef __WEBOS__
if (linux_enumeration_method == ENUMERATION_POLLING) {
if (linux_enumeration_method == ENUMERATION_POLLING || linux_enumeration_method == ENUMERATION_NETLINK) {
/* Hidraw hotplug has its own monitor: netlink broadcasts a copy to
* every bound socket, but a single fd shared with the joystick
* backend would mean whichever drained first ate the other's
* events. Without one we keep the 3s presence poll below. */
SDL_HIDAPI_discovery.m_pUeventMonitor =
SDL_webOSUeventMonitorOpen(SDL_WEBOS_DEVICE_PRESENCE_CHECK_HIDRAW);
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
} else
#endif
Expand Down Expand Up @@ -454,7 +463,16 @@ static void HIDAPI_UpdateDiscovery(void)
} else
#endif /* SDL_USE_LIBUDEV */
#ifdef __WEBOS__
if (linux_enumeration_method == ENUMERATION_POLLING) {
if (SDL_HIDAPI_discovery.m_pUeventMonitor != NULL) {
SDL_webOSUevent event;

/* Every add or remove counts; the enumeration behind
* SDL_hid_device_change_count() re-reads /dev/hidraw* anyway, so the
* node itself doesn't matter here, only that something moved. */
while (SDL_webOSUeventMonitorPoll(SDL_HIDAPI_discovery.m_pUeventMonitor, &event)) {
++SDL_HIDAPI_discovery.m_unDeviceChangeCounter;
}
} else if (linux_enumeration_method == ENUMERATION_POLLING) {
const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */
Uint32 now = SDL_GetTicks();
Uint32 next_detect = SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS;
Expand Down Expand Up @@ -517,6 +535,11 @@ static void HIDAPI_ShutdownDiscovery(void)
return;
}

#ifdef __WEBOS__
SDL_webOSUeventMonitorClose(SDL_HIDAPI_discovery.m_pUeventMonitor);
SDL_HIDAPI_discovery.m_pUeventMonitor = NULL;
#endif

#if defined(__WIN32__) || defined(__WINGDK__)
if (SDL_HIDAPI_discovery.m_hNotify) {
UnregisterDeviceNotification(SDL_HIDAPI_discovery.m_hNotify);
Expand Down
44 changes: 43 additions & 1 deletion src/joystick/linux/SDL_sysjoystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
#include "../../events/SDL_events_c.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#ifdef __WEBOS__
#include "../webos/uevent_monitor.h"
#endif
#include "../steam/SDL_steamcontroller.h"
#include "SDL_sysjoystick_c.h"
#include "../hidapi/SDL_hidapijoystick_c.h"
Expand Down Expand Up @@ -147,6 +150,7 @@ typedef enum
ENUMERATION_FALLBACK,
#ifdef __WEBOS__
ENUMERATION_POLLING,
ENUMERATION_NETLINK,
#endif
} EnumerationMethod;

Expand Down Expand Up @@ -190,6 +194,9 @@ static SDL_joylist_item *SDL_joylist_tail SDL_GUARDED_BY(SDL_joystick_lock) = NU
static int numjoysticks SDL_GUARDED_BY(SDL_joystick_lock) = 0;
static SDL_sensorlist_item *SDL_sensorlist SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static int inotify_fd = -1;
#ifdef __WEBOS__
static SDL_webOSUeventMonitor *joystick_uevent_monitor = NULL;
#endif

static Uint32 last_joy_detect_time;
static time_t last_input_dir_mtime;
Expand Down Expand Up @@ -1034,8 +1041,32 @@ static void LINUX_FallbackJoystickDetect(void)
}
}

#ifdef __WEBOS__
/* The uevent stream is explicit and ordered, so a device that disconnects and
* reconnects on the same index between two ticks produces a remove and an add
* rather than an unchanged presence bitmask. Devices already attached at init
* arrive here as ordinary adds, so there's no separate startup scan. */
static void LINUX_NetlinkJoystickDetect(void)
{
SDL_webOSUevent event;

while (SDL_webOSUeventMonitorPoll(joystick_uevent_monitor, &event)) {
if (event.action == SDL_WEBOS_UEVENT_ACTION_ADD) {
MaybeAddDevice(event.devnode);
} else {
MaybeRemoveDevice(event.devnode);
}
}
}
#endif

static void LINUX_JoystickDetect(void)
{
#ifdef __WEBOS__
if (enumeration_method == ENUMERATION_NETLINK) {
LINUX_NetlinkJoystickDetect();
} else
#endif
#ifdef SDL_USE_LIBUDEV
if (enumeration_method == ENUMERATION_LIBUDEV) {
SDL_UDEV_Poll();
Expand Down Expand Up @@ -1103,7 +1134,13 @@ static int LINUX_JoystickInit(void)
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Container detected, disabling udev integration");
#ifdef __WEBOS__
enumeration_method = ENUMERATION_POLLING;
/* No libudev in the app jail, so hotplug comes from a netlink
* uevent socket. Polling is the fallback for a kernel that won't
* let us bind one. */
joystick_uevent_monitor = SDL_webOSUeventMonitorOpen(
SDL_classic_joysticks ? SDL_WEBOS_DEVICE_PRESENCE_CHECK_JS
: SDL_WEBOS_DEVICE_PRESENCE_CHECK_EVDEV);
enumeration_method = joystick_uevent_monitor ? ENUMERATION_NETLINK : ENUMERATION_POLLING;
#else
enumeration_method = ENUMERATION_FALLBACK;
#endif
Expand Down Expand Up @@ -2315,6 +2352,11 @@ static void LINUX_JoystickQuit(void)
inotify_fd = -1;
}

#ifdef __WEBOS__
SDL_webOSUeventMonitorClose(joystick_uevent_monitor);
joystick_uevent_monitor = NULL;
#endif

for (item = SDL_joylist; item; item = next) {
next = item->next;
FreeJoylistItem(item);
Expand Down
Loading
Loading