mirror of https://github.com/libsdl-org/SDL.git
use hidapi to get mouse/keyboard string
This commit is contained in:
parent
7855842306
commit
3293eb1a16
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "SDL_hid.h"
|
||||
|
||||
HidD_GetAttributes_t SDL_HidD_GetAttributes;
|
||||
HidD_GetString_t SDL_HidD_GetManufacturerString;
|
||||
HidD_GetString_t SDL_HidD_GetProductString;
|
||||
HidP_GetCaps_t SDL_HidP_GetCaps;
|
||||
|
|
@ -50,6 +51,7 @@ bool WIN_LoadHIDDLL(void)
|
|||
SDL_assert(s_HIDDLLRefCount == 0);
|
||||
s_HIDDLLRefCount = 1;
|
||||
|
||||
SDL_HidD_GetAttributes = (HidD_GetAttributes_t)GetProcAddress(s_pHIDDLL, "HidD_GetAttributes");
|
||||
SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString");
|
||||
SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString");
|
||||
SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps");
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ typedef struct
|
|||
extern bool WIN_LoadHIDDLL(void);
|
||||
extern void WIN_UnloadHIDDLL(void);
|
||||
|
||||
typedef BOOLEAN (WINAPI *HidD_GetAttributes_t)(HANDLE HidDeviceObject, PHIDD_ATTRIBUTES Attributes);
|
||||
typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
|
||||
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);
|
||||
|
|
@ -198,6 +199,7 @@ typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHID
|
|||
typedef ULONG (WINAPI *HidP_MaxDataListLength_t)(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS (WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DATA DataList, PULONG DataLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
|
||||
|
||||
extern HidD_GetAttributes_t SDL_HidD_GetAttributes;
|
||||
extern HidD_GetString_t SDL_HidD_GetManufacturerString;
|
||||
extern HidD_GetString_t SDL_HidD_GetProductString;
|
||||
extern HidP_GetCaps_t SDL_HidP_GetCaps;
|
||||
|
|
|
|||
|
|
@ -861,7 +861,7 @@ static bool HasDeviceID(Uint32 deviceID, const Uint32 *list, int count)
|
|||
}
|
||||
|
||||
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||
static void GetDeviceName(HDEVINFO devinfo, const char *instance, char *name, size_t len)
|
||||
static void GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instance, char *name, size_t len)
|
||||
{
|
||||
name[0] = '\0';
|
||||
|
||||
|
|
@ -883,9 +883,108 @@ static void GetDeviceName(HDEVINFO devinfo, const char *instance, char *name, si
|
|||
|
||||
if (SDL_strcasecmp(instance, DeviceInstanceId) == 0) {
|
||||
SetupDiGetDeviceRegistryPropertyA(devinfo, &data, SPDRP_DEVICEDESC, NULL, (PBYTE)name, (DWORD)len, NULL);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t desc_len = 0;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (name[i] == '\0') {
|
||||
desc_len = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char devName[MAX_PATH + 1];
|
||||
devName[MAX_PATH] = '\0';
|
||||
UINT devName_cap = MAX_PATH;
|
||||
UINT devName_len = GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, devName, &devName_cap);
|
||||
if (0 != ~devName_len) {
|
||||
devName[devName_len] = '\0';
|
||||
}
|
||||
|
||||
if (desc_len + 3 < len && WIN_LoadHIDDLL()) { // reference counted
|
||||
// important: for devices with exclusive access mode as per
|
||||
// https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections-opened-by-windows-for-system-use
|
||||
// they can only be opened with a desired access of none instead of generic read.
|
||||
HANDLE hFile = CreateFileA(devName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
HIDD_ATTRIBUTES attr;
|
||||
WCHAR vend[128], prod[128];
|
||||
attr.VendorID = 0;
|
||||
attr.ProductID = 0;
|
||||
attr.Size = sizeof(attr);
|
||||
vend[0] = 0;
|
||||
prod[0] = 0;
|
||||
SDL_HidD_GetAttributes(hFile, &attr);
|
||||
SDL_HidD_GetManufacturerString(hFile, vend, sizeof(vend));
|
||||
SDL_HidD_GetProductString(hFile, prod, sizeof(prod));
|
||||
CloseHandle(hFile);
|
||||
|
||||
size_t vend_len, prod_len;
|
||||
for (vend_len = 0; vend_len < 128; vend_len++) {
|
||||
if (vend[vend_len] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (prod_len = 0; prod_len < 128; prod_len++) {
|
||||
if (prod[prod_len] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vend_len > 0 || prod_len > 0) {
|
||||
name[desc_len] = ' ';
|
||||
name[desc_len+1] = '(';
|
||||
size_t start = desc_len + 2;
|
||||
size_t n = start;
|
||||
for (size_t i = 0; i < vend_len; i++) {
|
||||
n = start + i;
|
||||
if (n < len) {
|
||||
name[n] = (char)(vend[i] & 0x7f); // TODO: do proper WCHAR conversion
|
||||
}
|
||||
}
|
||||
if (vend_len > 0) {
|
||||
n += 1;
|
||||
if (n < len) {
|
||||
name[n] = ' ';
|
||||
}
|
||||
n += 1;
|
||||
}
|
||||
size_t m = n;
|
||||
for (size_t i = 0; i < prod_len; i++) {
|
||||
m = n + i;
|
||||
if (m < len) {
|
||||
name[m] = (char)(prod[i] & 0x7f); // TODO: do proper WCHAR conversion
|
||||
}
|
||||
}
|
||||
{
|
||||
m += 1;
|
||||
if (m < len) {
|
||||
name[m] = ')';
|
||||
}
|
||||
m += 1;
|
||||
if (m < len) {
|
||||
name[m] = '\0';
|
||||
}
|
||||
}
|
||||
} else if (attr.VendorID && attr.ProductID) {
|
||||
char buf[17];
|
||||
int written = SDL_snprintf(buf, sizeof(buf), " (0x%.4x/0x%.4x)", attr.VendorID, attr.ProductID);
|
||||
buf[16] = '\0'; // just to be safe
|
||||
if (written > 0 && desc_len > 0) {
|
||||
for (size_t i = 0; i < sizeof(buf); i++) {
|
||||
size_t j = desc_len + i;
|
||||
if (j < len) {
|
||||
name[j] = buf[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WIN_UnloadHIDDLL();
|
||||
}
|
||||
|
||||
name[len-1] = '\0'; // just to be safe
|
||||
}
|
||||
|
||||
void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check)
|
||||
|
|
@ -938,7 +1037,7 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
|||
UINT nameSize = SDL_arraysize(devName);
|
||||
int vendor = 0, product = 0;
|
||||
DWORD dwType = raw_devices[i].dwType;
|
||||
char *instance, *ptr, name[64];
|
||||
char *instance, *ptr, name[256];
|
||||
|
||||
if (dwType != RIM_TYPEKEYBOARD && dwType != RIM_TYPEMOUSE) {
|
||||
continue;
|
||||
|
|
@ -976,7 +1075,7 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
|||
SDL_KeyboardID keyboardID = (Uint32)(uintptr_t)raw_devices[i].hDevice;
|
||||
AddDeviceID(keyboardID, &new_keyboards, &new_keyboard_count);
|
||||
if (!HasDeviceID(keyboardID, old_keyboards, old_keyboard_count)) {
|
||||
GetDeviceName(devinfo, instance, name, sizeof(name));
|
||||
GetDeviceName(raw_devices[i].hDevice, devinfo, instance, name, sizeof(name));
|
||||
SDL_AddKeyboard(keyboardID, name, send_event);
|
||||
}
|
||||
}
|
||||
|
|
@ -986,7 +1085,7 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
|||
SDL_MouseID mouseID = (Uint32)(uintptr_t)raw_devices[i].hDevice;
|
||||
AddDeviceID(mouseID, &new_mice, &new_mouse_count);
|
||||
if (!HasDeviceID(mouseID, old_mice, old_mouse_count)) {
|
||||
GetDeviceName(devinfo, instance, name, sizeof(name));
|
||||
GetDeviceName(raw_devices[i].hDevice, devinfo, instance, name, sizeof(name));
|
||||
SDL_AddMouse(mouseID, name, send_event);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue