win32 raw api: user-friendly names for devices

Issue #664
This commit is contained in:
flyinghead 2022-06-10 17:20:29 +02:00
parent d78bb9ed3f
commit 3780299803
2 changed files with 58 additions and 10 deletions

View File

@ -1443,7 +1443,7 @@ if(NOT LIBRETRO)
set_target_properties(${PROJECT_NAME} PROPERTIES RESOURCE "${ResourceFiles}")
else()
target_sources(${PROJECT_NAME} PRIVATE shell/windows/flycast.rc)
target_link_libraries(${PROJECT_NAME} PRIVATE dsound opengl32 winmm ws2_32 wsock32 xinput9_1_0)
target_link_libraries(${PROJECT_NAME} PRIVATE dsound opengl32 winmm ws2_32 wsock32 xinput9_1_0 cfgmgr32)
endif()
endif()
endif()

View File

@ -20,6 +20,9 @@
#ifndef TARGET_UWP
#include <hidusage.h>
#include <map>
#include <cfgmgr32.h>
#include <initguid.h>
#include <devpkey.h>
#include "hw/maple/maple_devs.h"
#ifndef CALLBACK
@ -324,6 +327,14 @@ static void destroyWindow()
UnregisterClassA("flycastRawInput", nullptr);
}
extern "C" CMAPI CONFIGRET CM_Get_Device_Interface_PropertyW(
LPCWSTR pszDeviceInterface,
const DEVPROPKEY *PropertyKey,
DEVPROPTYPE *PropertyType,
PBYTE PropertyBuffer,
PULONG PropertyBufferSize,
ULONG ulFlags);
static void findDevices()
{
u32 numDevices;
@ -338,10 +349,10 @@ static void findDevices()
RAWINPUTDEVICELIST& device = deviceList[i];
if (device.dwType == RIM_TYPEMOUSE || device.dwType == RIM_TYPEKEYBOARD)
{
// Get the device name
// Get the device interface instance id
std::string name;
std::string uniqueId;
u32 size;
u32 size = 0;
GetRawInputDeviceInfo(device.hDevice, RIDI_DEVICENAME, nullptr, &size);
if (size > 0)
{
@ -349,13 +360,50 @@ static void findDevices()
u32 res = GetRawInputDeviceInfo(device.hDevice, RIDI_DEVICENAME, &deviceNameData[0], &size);
if (res != (u32)-1)
{
std::string deviceName(&deviceNameData[0], std::strlen(&deviceNameData[0]));
if (deviceName.substr(0, 8) == "\\\\?\\HID#")
deviceName = deviceName.substr(8);
uniqueId = (device.dwType == RIM_TYPEMOUSE ? "raw_mouse_" : "raw_keyboard_") + deviceName;
if (deviceName.length() > 17 && deviceName.substr(0, 4) == "VID_" && deviceName.substr(8, 5) == "&PID_")
deviceName = deviceName.substr(0, 17);
name = (device.dwType == RIM_TYPEMOUSE ? "Mouse " : "Keyboard ") + deviceName;
std::string deviceId(&deviceNameData[0], std::strlen(&deviceNameData[0]));
// Now get the device instance id from the interface instance
nowide::wstackstring wname;
if (wname.convert(deviceId.c_str()))
{
DEVPROPTYPE propType;
ULONG bufSize = 0;
if (CM_Get_Device_Interface_PropertyW(wname.c_str(), &DEVPKEY_Device_InstanceId, &propType, nullptr, &bufSize, 0) == CR_BUFFER_SMALL)
{
std::vector<wchar_t> buf;
buf.resize(bufSize / sizeof(wchar_t));
if (CM_Get_Device_Interface_PropertyW(wname.c_str(), &DEVPKEY_Device_InstanceId, &propType, (PBYTE)buf.data(), &bufSize, 0) == CR_SUCCESS)
{
// Locate the device using the device instance id
DEVINST devInst;
if (CM_Locate_DevNodeW(&devInst, &buf[0], CM_LOCATE_DEVNODE_NORMAL) == CR_SUCCESS)
{
// Finally, get the "friendly" device name
bufSize = 0;
if (CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_NAME, &propType, nullptr, &bufSize, 0) == CR_BUFFER_SMALL)
{
buf.resize(bufSize / sizeof(wchar_t));
if (CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_NAME, &propType, (PBYTE)buf.data(), &bufSize, 0) == CR_SUCCESS)
{
nowide::stackstring nwname;
if (nwname.convert(&buf[0]))
name = nwname.c_str();
}
}
}
}
}
}
if (deviceId.substr(0, 8) == "\\\\?\\HID#")
deviceId = deviceId.substr(8);
uniqueId = (device.dwType == RIM_TYPEMOUSE ? "raw_mouse_" : "raw_keyboard_") + deviceId;
if (name.empty())
{
name = deviceId;
if (name.length() > 17 && name.substr(0, 4) == "VID_" && name.substr(8, 5) == "&PID_")
name = name.substr(0, 17);
name = (device.dwType == RIM_TYPEMOUSE ? "Mouse " : "Keyboard ") + name;
}
}
}
uintptr_t handle = (uintptr_t)device.hDevice;