From 052698afa36238389804264e168280fbcebdd67e Mon Sep 17 00:00:00 2001 From: bicarus-dev <202771338+bicarus-dev@users.noreply.github.com> Date: Sun, 16 Nov 2025 00:08:30 -0800 Subject: [PATCH] rawinput: use UTF-8 for device descriptor (#422) ## Link to GitHub Issue, if one exists n/a ## Description of change For HID device descriptor, use the "W" version of Windows API, and make sure UTF-8 is being used throughout since that's the only format IMGUI supports. Before this change, non-Latin characters would have shown up as `HID ??? ?????` for a mouse, for example. Due to the way ImGui loads fonts, only the following languages are supported: * Simplified Chinese * Cyrillic * Japanese * Korean * Thai * Vietnamese ## Testing Tested various combination of Windows UI language and non-Unicode language. --- src/spice2x/rawinput/rawinput.cpp | 24 +++++++++++------------- src/spice2x/util/utils.h | 10 ++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/spice2x/rawinput/rawinput.cpp b/src/spice2x/rawinput/rawinput.cpp index 7d17041..d3fbd0a 100644 --- a/src/spice2x/rawinput/rawinput.cpp +++ b/src/spice2x/rawinput/rawinput.cpp @@ -347,40 +347,38 @@ void rawinput::RawInputManager::devices_scan_rawinput(RAWINPUTDEVICELIST *device if (hid_handle != INVALID_HANDLE_VALUE) { // check manufacturer string - std::wstring man_ws; + std::string man_ws; wchar_t man_str_buffer[256] {}; if (HidD_GetManufacturerString(hid_handle, man_str_buffer, sizeof(man_str_buffer))) { - man_ws = std::wstring(man_str_buffer); + man_ws = wchar_to_u8(man_str_buffer); } // get product string - std::wstring prod_ws; + std::string prod_ws; wchar_t prod_str_buffer[256] {}; if (HidD_GetProductString(hid_handle, prod_str_buffer, sizeof(prod_str_buffer))) { - prod_ws = std::wstring(prod_str_buffer); + prod_ws = wchar_to_u8(prod_str_buffer); } // For Bluetooth LE HID devices (e.g., newer Xbox controllers) HidD_GetProductString // and HidD_GetManufacturerString will return blank strings. // https://docs.microsoft.com/en-us/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html if (man_ws.empty() && prod_ws.empty()) { - prod_ws = s2ws(device_description); + prod_ws = device_description; } // build desc string - std::wstring desc_ws; + std::string desc_ws; if (string_begins_with(prod_ws, man_ws)) { desc_ws = prod_ws; } else { desc_ws = man_ws; if (!man_ws.empty() && !prod_ws.empty()) { - desc_ws += L" "; + desc_ws += " "; } desc_ws += prod_ws; } - - // convert to normal string - new_device.desc = ws2s(desc_ws); + new_device.desc = desc_ws; // get attributes if (!HidD_GetAttributes(hid_handle, &hid_attributes)) { @@ -1148,7 +1146,7 @@ std::string rawinput::RawInputManager::rawinput_get_device_description(const raw // get property DWORD desc_size = 0; - if (SetupDiGetDeviceRegistryProperty( + if (SetupDiGetDeviceRegistryPropertyW( devinfo, &devinfo_data, SPDRP_DEVICEDESC, nullptr, nullptr, 0, &desc_size)) { continue; @@ -1160,14 +1158,14 @@ std::string rawinput::RawInputManager::rawinput_get_device_description(const raw // allocate buffer auto desc_data = std::make_unique(desc_size); - if (!SetupDiGetDeviceRegistryProperty( + if (!SetupDiGetDeviceRegistryPropertyW( devinfo, &devinfo_data, SPDRP_DEVICEDESC, nullptr, desc_data.get(), desc_size, nullptr)) { continue; } // kthxbye - device_description = std::string(reinterpret_cast(desc_data.get())); + device_description = wchar_to_u8(reinterpret_cast(desc_data.get())); } } } diff --git a/src/spice2x/util/utils.h b/src/spice2x/util/utils.h index 52d1132..d656236 100644 --- a/src/spice2x/util/utils.h +++ b/src/spice2x/util/utils.h @@ -339,4 +339,14 @@ static inline bool parse_width_height(const std::string wh, std::pair