diff options
| author | a1xd <[email protected]> | 2021-04-26 22:00:51 -0400 |
|---|---|---|
| committer | a1xd <[email protected]> | 2021-04-26 22:00:51 -0400 |
| commit | 8de054735f51c6b933f4fadf7e7aa63c11971a68 (patch) | |
| tree | 08e8670d7da12ba24e4dda191df11096e09d83ab | |
| parent | ignore GetRawInputDeviceInfo errors (diff) | |
| download | rawaccel-8de054735f51c6b933f4fadf7e7aa63c11971a68.tar.xz rawaccel-8de054735f51c6b933f4fadf7e7aa63c11971a68.zip | |
refactor rawinput util
some generalizations here don't make sense now that we're ignoring errors
| -rw-r--r-- | common/utility-rawinput.hpp | 103 | ||||
| -rw-r--r-- | grapher/Models/Devices/DeviceIDManager.cs | 4 | ||||
| -rw-r--r-- | wrapper/wrapper.cpp | 41 |
3 files changed, 62 insertions, 86 deletions
diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp index 1167891..f20d594 100644 --- a/common/utility-rawinput.hpp +++ b/common/utility-rawinput.hpp @@ -2,6 +2,7 @@ #pragma comment(lib, "cfgmgr32.lib") +#include <algorithm> #include <string> #include <system_error> #include <vector> @@ -11,40 +12,12 @@ #include <initguid.h> // needed for devpkey.h to parse properly #include <devpkey.h> -// Returns an empty string on failure -// -// interface names from GetRawInputDeviceInfo are not guaranteed to be valid; -// CM_Get_Device_Interface_PropertyW can return CR_NO_SUCH_DEVICE_INTERFACE -std::wstring dev_id_from_interface(const WCHAR* interface_name) { - ULONG size = 0; - DEVPROPTYPE type; - CONFIGRET cm_res; - - cm_res = CM_Get_Device_Interface_PropertyW(interface_name, &DEVPKEY_Device_InstanceId, - &type, NULL, &size, 0); - - if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) return {}; - - std::wstring id((size + 1) / 2, L'\0'); - - cm_res = CM_Get_Device_Interface_PropertyW(interface_name, &DEVPKEY_Device_InstanceId, - &type, reinterpret_cast<PBYTE>(&id[0]), &size, 0); - - if (cm_res != CR_SUCCESS) return {}; - - auto instance_delim_pos = id.find_last_of('\\'); - - if (instance_delim_pos != std::string::npos) { - id.resize(instance_delim_pos); - } - - return id; -} - template <typename Func> -void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) { +void rawinput_foreach_dev_with_id(Func fn, bool with_instance_id = false, + DWORD input_type = RIM_TYPEMOUSE) +{ const UINT RI_ERROR = -1; - + UINT num_devs = 0; if (GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) { @@ -58,37 +31,73 @@ void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) } std::wstring name; - UINT len; + std::wstring id; + DEVPROPTYPE type; + CONFIGRET cm_res; for (auto&& dev : devs) { if (dev.dwType != input_type) continue; - // get required length - if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, NULL, &len) == RI_ERROR) { + // get interface name length + UINT name_len = 0; + if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, NULL, &name_len) == RI_ERROR) { continue; } - name.resize(len); + name.resize(name_len); - if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, &name[0], &len) == RI_ERROR) { + if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, &name[0], &name_len) == RI_ERROR) { continue; } - fn(dev, &name[0]); + // get sizeof dev instance id + ULONG id_size = 0; + cm_res = CM_Get_Device_Interface_PropertyW(&name[0], &DEVPKEY_Device_InstanceId, + &type, NULL, &id_size, 0); + + if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) continue; + + id.resize((id_size + 1) / 2); + + cm_res = CM_Get_Device_Interface_PropertyW(&name[0], &DEVPKEY_Device_InstanceId, + &type, reinterpret_cast<PBYTE>(&id[0]), &id_size, 0); + + if (cm_res != CR_SUCCESS) continue; + + if (!with_instance_id) { + auto instance_delim_pos = id.find_last_of('\\'); + if(instance_delim_pos != std::string::npos) id.resize(instance_delim_pos); + } + + fn(dev, id); } } -// returns device handles corresponding to a "device id" -// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-ids -std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& device_id, DWORD input_type = RIM_TYPEMOUSE) { +inline +std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& device_id, + bool with_instance_id = false, + DWORD input_type = RIM_TYPEMOUSE) +{ std::vector<HANDLE> handles; - rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) { - auto id = dev_id_from_interface(name); - if (!id.empty() && id == device_id) { - handles.push_back(dev.hDevice); - } - }, input_type); + rawinput_foreach_dev_with_id([&](const auto& dev, const std::wstring& id) { + if (id == device_id) handles.push_back(dev.hDevice); + }, with_instance_id, input_type); return handles; } + +inline +std::vector<std::wstring> rawinput_dev_id_list(bool with_instance_id = false, + DWORD input_type = RIM_TYPEMOUSE) +{ + std::vector<std::wstring> ids; + + rawinput_foreach_dev_with_id([&](const auto& dev, const std::wstring& id) { + ids.push_back(id); + }, with_instance_id, input_type); + + std::sort(ids.begin(), ids.end()); + ids.erase(std::unique(ids.begin(), ids.end()), ids.end()); + return ids; +} diff --git a/grapher/Models/Devices/DeviceIDManager.cs b/grapher/Models/Devices/DeviceIDManager.cs index 8592763..39856a1 100644 --- a/grapher/Models/Devices/DeviceIDManager.cs +++ b/grapher/Models/Devices/DeviceIDManager.cs @@ -46,9 +46,9 @@ namespace grapher.Models.Devices if (found) SetActive(anyDevice); - foreach (var (name, id) in RawInputInterop.GetDeviceIDs()) + foreach (string id in RawInputInterop.GetDeviceIDs()) { - var deviceItem = new DeviceIDItem(name, id, this); + var deviceItem = new DeviceIDItem(string.Empty, id, this); if (!found && deviceItem.ID.Equals(devID)) { SetActive(deviceItem); diff --git a/wrapper/wrapper.cpp b/wrapper/wrapper.cpp index 5f44859..50a3596 100644 --- a/wrapper/wrapper.cpp +++ b/wrapper/wrapper.cpp @@ -1,6 +1,5 @@ #pragma once -#include <algorithm> #include <type_traits> #include <msclr\marshal_cppstd.h> @@ -277,35 +276,6 @@ public: } }; -struct device_info { - std::wstring name; - std::wstring id; -}; - -std::vector<device_info> get_unique_device_info() { - std::vector<device_info> info; - - rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) { - auto id = dev_id_from_interface(name); - - if (!id.empty()) { - info.push_back({ - L"", // get_property_wstr(name, &DEVPKEY_Device_FriendlyName), /* doesn't work */ - id - }); - } - - }); - - std::sort(info.begin(), info.end(), - [](auto&& l, auto&& r) { return l.id < r.id; }); - auto last = std::unique(info.begin(), info.end(), - [](auto&& l, auto&& r) { return l.id == r.id; }); - info.erase(last, info.end()); - - return info; -} - public ref struct RawInputInterop { static void AddHandlesFromID(String^ deviceID, List<IntPtr>^ rawInputHandles) @@ -323,18 +293,15 @@ public ref struct RawInputInterop } } - static List<ValueTuple<String^, String^>>^ GetDeviceIDs() + static List<String^>^ GetDeviceIDs() { try { - auto managed = gcnew List<ValueTuple<String^, String^>>(); + auto managed = gcnew List<String^>(); - for (auto&& [name, id] : get_unique_device_info()) + for (auto&& id : rawinput_dev_id_list()) { - managed->Add( - ValueTuple<String^, String^>( - msclr::interop::marshal_as<String^>(name), - msclr::interop::marshal_as<String^>(id))); + managed->Add(msclr::interop::marshal_as<String^>(id)); } return managed; |