summaryrefslogtreecommitdiff
path: root/common/utility-rawinput.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/utility-rawinput.hpp')
-rw-r--r--common/utility-rawinput.hpp78
1 files changed, 46 insertions, 32 deletions
diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp
index 3c44068..c43084b 100644
--- a/common/utility-rawinput.hpp
+++ b/common/utility-rawinput.hpp
@@ -2,7 +2,6 @@
#pragma comment(lib, "cfgmgr32.lib")
-#include <iostream>
#include <string>
#include <system_error>
#include <vector>
@@ -12,9 +11,40 @@
#include <initguid.h> // needed for devpkey.h to parse properly
#include <devpkey.h>
-// 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& dev_id, DWORD input_type = RIM_TYPEMOUSE) {
+std::wstring dev_prop_wstr_from_interface(const WCHAR* interface_name, const DEVPROPKEY* key) {
+ ULONG size = 0;
+ DEVPROPTYPE type;
+ CONFIGRET cm_res;
+
+ cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key,
+ &type, NULL, &size, 0);
+
+ if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) {
+ throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
+ std::to_string(cm_res) + ')');
+ }
+
+ std::wstring prop((size + 1) / 2, L'\0');
+
+ cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key,
+ &type, reinterpret_cast<PBYTE>(&prop[0]), &size, 0);
+
+ if (cm_res != CR_SUCCESS) {
+ throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
+ std::to_string(cm_res) + ')');
+ }
+
+ return prop;
+}
+
+std::wstring dev_id_from_interface(const WCHAR* interface_name) {
+ auto id = dev_prop_wstr_from_interface(interface_name, &DEVPKEY_Device_InstanceId);
+ id.resize(id.find_last_of('\\'));
+ return id;
+}
+
+template <typename Func>
+void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) {
const UINT RI_ERROR = -1;
UINT num_devs = 0;
@@ -28,8 +58,6 @@ std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& dev_id, DWO
if (GetRawInputDeviceList(&devs[0], &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) {
throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed");
}
-
- std::vector<HANDLE> handles;
for (auto&& dev : devs) {
if (dev.dwType != input_type) continue;
@@ -41,34 +69,20 @@ std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& dev_id, DWO
throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceInfoW failed");
}
- ULONG id_size = 0;
- DEVPROPTYPE type;
- CONFIGRET cm_res;
-
- cm_res = CM_Get_Device_Interface_PropertyW(name, &DEVPKEY_Device_InstanceId,
- &type, NULL, &id_size, 0);
-
- if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) {
- throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
- std::to_string(cm_res) + ')');
- }
-
- std::wstring id((static_cast<size_t>(id_size) + 1) / 2, '\0');
-
- cm_res = CM_Get_Device_Interface_PropertyW(name, &DEVPKEY_Device_InstanceId,
- &type, reinterpret_cast<PBYTE>(&id[0]), &id_size, 0);
-
- if (cm_res != CR_SUCCESS) {
- throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
- std::to_string(cm_res) + ')');
- }
+ fn(dev, name);
+ }
+}
- // remove instance id
- id.resize(id.find_last_of('\\'));
+// 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) {
+ std::vector<HANDLE> handles;
- if (id == dev_id) handles.push_back(dev.hDevice);
- }
+ rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) {
+ if (device_id == dev_id_from_interface(name)) {
+ handles.push_back(dev.hDevice);
+ }
+ }, input_type);
return handles;
}
-