From 1c865c460b348e9085d84a48d5f4aca9fdfe5b71 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 27 Nov 2020 18:57:36 -0800 Subject: [PATCH] Load the raw input device list at init time so it's available when DirectInput is doing device detection --- src/joystick/windows/SDL_rawinputjoystick.c | 155 +++++++++++--------- 1 file changed, 86 insertions(+), 69 deletions(-) diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index b9d63b780..b85c9cade 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -68,6 +68,7 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState; #endif /*#define DEBUG_RAWINPUT*/ +#define DEBUG_RAWINPUT #ifndef RIDEV_EXINPUTSINK #define RIDEV_EXINPUTSINK 0x00001000 @@ -624,31 +625,6 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) #endif /* SDL_JOYSTICK_RAWINPUT_WGI */ -static int -RAWINPUT_JoystickInit(void) -{ - SDL_assert(!SDL_RAWINPUT_inited); - - if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) { - return -1; - } - - if (WIN_LoadHIDDLL() < 0) { - return -1; - } - - SDL_RAWINPUT_mutex = SDL_CreateMutex(); - SDL_RAWINPUT_inited = SDL_TRUE; - - return 0; -} - -static int -RAWINPUT_JoystickGetCount(void) -{ - return SDL_RAWINPUT_numjoysticks; -} - static SDL_RAWINPUT_Device * RAWINPUT_AcquireDevice(SDL_RAWINPUT_Device *device) { @@ -826,6 +802,91 @@ RAWINPUT_DelDevice(SDL_RAWINPUT_Device *device, SDL_bool send_event) } } +static int +RAWINPUT_JoystickInit(void) +{ + UINT device_count = 0; + + SDL_assert(!SDL_RAWINPUT_inited); + + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) { + return -1; + } + + if (WIN_LoadHIDDLL() < 0) { + return -1; + } + + SDL_RAWINPUT_mutex = SDL_CreateMutex(); + SDL_RAWINPUT_inited = SDL_TRUE; + + if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) && device_count > 0) { + PRAWINPUTDEVICELIST devices = NULL; + UINT i; + + devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count); + if (devices) { + if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) { + for (i = 0; i < device_count; ++i) { + RAWINPUT_AddDevice(devices[i].hDevice); + } + } + SDL_free(devices); + } + } + + return 0; +} + +static int +RAWINPUT_JoystickGetCount(void) +{ + return SDL_RAWINPUT_numjoysticks; +} + +SDL_bool +RAWINPUT_IsEnabled() +{ + return SDL_RAWINPUT_inited; +} + +SDL_bool +RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + SDL_RAWINPUT_Device *device; + + /* If we're being asked about a device, that means another API just detected one, so rescan */ +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + xinput_device_change = SDL_TRUE; +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + wgi_state.need_device_list_update = SDL_TRUE; +#endif + + device = SDL_RAWINPUT_devices; + while (device) { + if (vendor_id == device->vendor_id && product_id == device->product_id ) { + return SDL_TRUE; + } + + /* The Xbox 360 wireless controller shows up as product 0 in WGI */ + if (vendor_id == device->vendor_id && product_id == 0 && + name && SDL_strstr(device->name, name) != NULL) { + return SDL_TRUE; + } + + /* The Xbox One controller shows up as a hardcoded raw input VID/PID */ + if (name && SDL_strcmp(name, "Xbox One Game Controller") == 0 && + device->vendor_id == USB_VENDOR_MICROSOFT && + device->product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER) { + return SDL_TRUE; + } + + device = device->next; + } + return SDL_FALSE; +} + static void RAWINPUT_PostUpdate(void) { @@ -885,49 +946,6 @@ RAWINPUT_PostUpdate(void) #endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */ } -SDL_bool -RAWINPUT_IsEnabled() -{ - return SDL_RAWINPUT_inited; -} - -SDL_bool -RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) -{ - SDL_RAWINPUT_Device *device; - - /* If we're being asked about a device, that means another API just detected one, so rescan */ -#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT - xinput_device_change = SDL_TRUE; -#endif -#ifdef SDL_JOYSTICK_RAWINPUT_WGI - wgi_state.need_device_list_update = SDL_TRUE; -#endif - - device = SDL_RAWINPUT_devices; - while (device) { - if (vendor_id == device->vendor_id && product_id == device->product_id ) { - return SDL_TRUE; - } - - /* The Xbox 360 wireless controller shows up as product 0 in WGI */ - if (vendor_id == device->vendor_id && product_id == 0 && - name && SDL_strstr(device->name, name) != NULL) { - return SDL_TRUE; - } - - /* The Xbox One controller shows up as a hardcoded raw input VID/PID */ - if (name && SDL_strcmp(name, "Xbox One Game Controller") == 0 && - device->vendor_id == USB_VENDOR_MICROSOFT && - device->product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER) { - return SDL_TRUE; - } - - device = device->next; - } - return SDL_FALSE; -} - static void RAWINPUT_JoystickDetect(void) { @@ -1842,7 +1860,6 @@ RAWINPUT_JoystickQuit(void) SDL_UnlockMutex(SDL_RAWINPUT_mutex); SDL_DestroyMutex(SDL_RAWINPUT_mutex); SDL_RAWINPUT_mutex = NULL; - } static SDL_bool