joystick: get HID top-level collection preparsed data directly from RawInput API.

This commit is contained in:
Dimitriy Ryazantcev 2021-12-22 18:27:10 +02:00 committed by Sam Lantinga
parent 8c1584e8e8
commit c39df2fb0c
3 changed files with 16 additions and 21 deletions

View File

@ -27,8 +27,6 @@
HidD_GetString_t SDL_HidD_GetManufacturerString; HidD_GetString_t SDL_HidD_GetManufacturerString;
HidD_GetString_t SDL_HidD_GetProductString; HidD_GetString_t SDL_HidD_GetProductString;
HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData;
HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData;
HidP_GetCaps_t SDL_HidP_GetCaps; HidP_GetCaps_t SDL_HidP_GetCaps;
HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps; HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps;
HidP_GetValueCaps_t SDL_HidP_GetValueCaps; HidP_GetValueCaps_t SDL_HidP_GetValueCaps;
@ -58,15 +56,13 @@ WIN_LoadHIDDLL(void)
SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString"); SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString");
SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString"); SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString");
SDL_HidD_GetPreparsedData = (HidD_GetPreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_GetPreparsedData");
SDL_HidD_FreePreparsedData = (HidD_FreePreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_FreePreparsedData");
SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps"); SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps");
SDL_HidP_GetButtonCaps = (HidP_GetButtonCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetButtonCaps"); SDL_HidP_GetButtonCaps = (HidP_GetButtonCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetButtonCaps");
SDL_HidP_GetValueCaps = (HidP_GetValueCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetValueCaps"); SDL_HidP_GetValueCaps = (HidP_GetValueCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetValueCaps");
SDL_HidP_MaxDataListLength = (HidP_MaxDataListLength_t)GetProcAddress(s_pHIDDLL, "HidP_MaxDataListLength"); SDL_HidP_MaxDataListLength = (HidP_MaxDataListLength_t)GetProcAddress(s_pHIDDLL, "HidP_MaxDataListLength");
SDL_HidP_GetData = (HidP_GetData_t)GetProcAddress(s_pHIDDLL, "HidP_GetData"); SDL_HidP_GetData = (HidP_GetData_t)GetProcAddress(s_pHIDDLL, "HidP_GetData");
if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString || !SDL_HidD_GetPreparsedData || if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString ||
!SDL_HidD_FreePreparsedData || !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps || !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps ||
!SDL_HidP_GetValueCaps || !SDL_HidP_MaxDataListLength || !SDL_HidP_GetData) { !SDL_HidP_GetValueCaps || !SDL_HidP_MaxDataListLength || !SDL_HidP_GetData) {
WIN_UnloadHIDDLL(); WIN_UnloadHIDDLL();
return -1; return -1;

View File

@ -183,8 +183,6 @@ extern int WIN_LoadHIDDLL(void);
extern void WIN_UnloadHIDDLL(void); extern void WIN_UnloadHIDDLL(void);
typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength); typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
typedef BOOLEAN (WINAPI *HidD_GetPreparsedData_t)(HANDLE HidDeviceObject, PHIDP_PREPARSED_DATA *PreparsedData);
typedef BOOLEAN (WINAPI *HidD_FreePreparsedData_t)(PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS (WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities); typedef NTSTATUS (WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities);
typedef NTSTATUS (WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData); typedef NTSTATUS (WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData); typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
@ -193,8 +191,6 @@ typedef NTSTATUS (WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DAT
extern HidD_GetString_t SDL_HidD_GetManufacturerString; extern HidD_GetString_t SDL_HidD_GetManufacturerString;
extern HidD_GetString_t SDL_HidD_GetProductString; extern HidD_GetString_t SDL_HidD_GetProductString;
extern HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData;
extern HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData;
extern HidP_GetCaps_t SDL_HidP_GetCaps; extern HidP_GetCaps_t SDL_HidP_GetCaps;
extern HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps; extern HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps;
extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps; extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps;

View File

@ -689,9 +689,7 @@ RAWINPUT_ReleaseDevice(SDL_RAWINPUT_Device *device)
#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ #endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */
if (SDL_AtomicDecRef(&device->refcount)) { if (SDL_AtomicDecRef(&device->refcount)) {
if (device->preparsed_data) { SDL_free(device->preparsed_data);
SDL_HidD_FreePreparsedData(device->preparsed_data);
}
SDL_free(device->name); SDL_free(device->name);
SDL_free(device); SDL_free(device);
} }
@ -716,9 +714,8 @@ RAWINPUT_AddDevice(HANDLE hDevice)
SDL_RAWINPUT_Device *device = NULL; SDL_RAWINPUT_Device *device = NULL;
SDL_RAWINPUT_Device *curr, *last; SDL_RAWINPUT_Device *curr, *last;
RID_DEVICE_INFO rdi; RID_DEVICE_INFO rdi;
UINT rdi_size = sizeof(rdi); UINT size;
char dev_name[MAX_PATH]; char dev_name[MAX_PATH];
UINT name_size = SDL_arraysize(dev_name);
HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hFile = INVALID_HANDLE_VALUE;
/* Make sure we're not trying to add the same device twice */ /* Make sure we're not trying to add the same device twice */
@ -727,11 +724,13 @@ RAWINPUT_AddDevice(HANDLE hDevice)
} }
/* Figure out what kind of device it is */ /* Figure out what kind of device it is */
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &rdi_size) != (UINT)-1); size = sizeof(rdi);
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &size) != (UINT)-1);
CHECK(rdi.dwType == RIM_TYPEHID); CHECK(rdi.dwType == RIM_TYPEHID);
/* Get the device "name" (HID Path) */ /* Get the device "name" (HID Path) */
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &name_size) != (UINT)-1); size = SDL_arraysize(dev_name);
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &size) != (UINT)-1);
/* Only take XInput-capable devices */ /* Only take XInput-capable devices */
CHECK(SDL_strstr(dev_name, "IG_") != NULL); CHECK(SDL_strstr(dev_name, "IG_") != NULL);
#ifdef SDL_JOYSTICK_HIDAPI #ifdef SDL_JOYSTICK_HIDAPI
@ -747,6 +746,12 @@ RAWINPUT_AddDevice(HANDLE hDevice)
device->is_xinput = SDL_TRUE; device->is_xinput = SDL_TRUE;
device->is_xboxone = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController; device->is_xboxone = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController;
/* Get HID Top-Level Collection Preparsed Data */
size = 0;
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, NULL, &size) != (UINT)-1);
CHECK(device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE)));
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, device->preparsed_data, &size) != (UINT)-1);
{ {
const Uint16 vendor = device->vendor_id; const Uint16 vendor = device->vendor_id;
const Uint16 product = device->product_id; const Uint16 product = device->product_id;
@ -792,8 +797,6 @@ RAWINPUT_AddDevice(HANDLE hDevice)
} }
} }
CHECK(SDL_HidD_GetPreparsedData(hFile, &device->preparsed_data));
CloseHandle(hFile); CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE; hFile = INVALID_HANDLE_VALUE;
@ -1312,7 +1315,7 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
{ {
#if defined(SDL_JOYSTICK_RAWINPUT_WGI) #if defined(SDL_JOYSTICK_RAWINPUT_WGI)
RAWINPUT_DeviceContext *ctx = joystick->hwdata; RAWINPUT_DeviceContext *ctx = joystick->hwdata;
if (ctx->wgi_correlated) { if (ctx->wgi_correlated) {
WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
HRESULT hr; HRESULT hr;
@ -1911,7 +1914,7 @@ RAWINPUT_UnregisterNotifications()
return; return;
} }
} }
LRESULT CALLBACK LRESULT CALLBACK
RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {