summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authora1xd <[email protected]>2021-04-26 22:00:51 -0400
committera1xd <[email protected]>2021-04-26 22:00:51 -0400
commit8de054735f51c6b933f4fadf7e7aa63c11971a68 (patch)
tree08e8670d7da12ba24e4dda191df11096e09d83ab /common
parentignore GetRawInputDeviceInfo errors (diff)
downloadrawaccel-8de054735f51c6b933f4fadf7e7aa63c11971a68.tar.xz
rawaccel-8de054735f51c6b933f4fadf7e7aa63c11971a68.zip
refactor rawinput util
some generalizations here don't make sense now that we're ignoring errors
Diffstat (limited to 'common')
-rw-r--r--common/utility-rawinput.hpp103
1 files changed, 56 insertions, 47 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;
+}