summaryrefslogtreecommitdiff
path: root/Source/Core/Common/WindowsDevice.cpp
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2025-12-23 17:01:44 -0500
committerGitHub <noreply@github.com>2025-12-23 17:01:44 -0500
commit4b086b1256855be85873b9cee5b2bdd4efb91caf (patch)
tree00157dd8667f75efccb627aa8f001998c508d70a /Source/Core/Common/WindowsDevice.cpp
parent0a3aac6d85d1e276755e4f1a4215eef567c1c85c (diff)
parentfc4cbf9c6fa76862b153d72baddde11edb8a3958 (diff)
Merge pull request #14223 from jordan-woyak/wmreal-windows-device-enumeration
HW/WiimoteReal: Cache the enumerated Wii remote HID interface list between calls to FindWiimoteHIDDevices.
Diffstat (limited to 'Source/Core/Common/WindowsDevice.cpp')
-rw-r--r--Source/Core/Common/WindowsDevice.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/Source/Core/Common/WindowsDevice.cpp b/Source/Core/Common/WindowsDevice.cpp
index 4bbd213774..34a540ed7b 100644
--- a/Source/Core/Common/WindowsDevice.cpp
+++ b/Source/Core/Common/WindowsDevice.cpp
@@ -90,6 +90,65 @@ NullTerminatedStringList<WCHAR> GetDeviceInterfaceList(LPGUID iface_class_guid,
}
}
+static __callback DWORD OnDevicesChanged(_In_ HCMNOTIFICATION notify_handle, _In_opt_ PVOID context,
+ _In_ CM_NOTIFY_ACTION action,
+ _In_reads_bytes_(event_data_size)
+ PCM_NOTIFY_EVENT_DATA event_data,
+ _In_ DWORD event_data_size)
+{
+ auto& callback = *static_cast<DeviceChangeNotification::CallbackType*>(context);
+ switch (action)
+ {
+ case CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL:
+ callback(DeviceChangeNotification::EventType::Arrival);
+ break;
+ case CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL:
+ callback(DeviceChangeNotification::EventType::Removal);
+ break;
+ default:
+ break;
+ }
+ return ERROR_SUCCESS;
+}
+
+DeviceChangeNotification::DeviceChangeNotification() = default;
+
+DeviceChangeNotification::~DeviceChangeNotification()
+{
+ Unregister();
+}
+
+void DeviceChangeNotification::Register(CallbackType callback)
+{
+ Unregister();
+ m_callback = std::move(callback);
+
+ CM_NOTIFY_FILTER notify_filter{
+ .cbSize = sizeof(notify_filter),
+ .FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE,
+ .u{.DeviceInterface{.ClassGuid = GUID_DEVINTERFACE_HID}},
+ };
+ const CONFIGRET cfg_rv =
+ CM_Register_Notification(&notify_filter, &m_callback, OnDevicesChanged, &m_notify_handle);
+ if (cfg_rv != CR_SUCCESS)
+ {
+ ERROR_LOG_FMT(COMMON, "CM_Register_Notification failed: {:x}", cfg_rv);
+ }
+}
+
+void DeviceChangeNotification::Unregister()
+{
+ if (m_notify_handle == nullptr)
+ return;
+
+ const CONFIGRET cfg_rv = CM_Unregister_Notification(m_notify_handle);
+ if (cfg_rv != CR_SUCCESS)
+ {
+ ERROR_LOG_FMT(COMMON, "CM_Unregister_Notification failed: {:x}", cfg_rv);
+ }
+ m_notify_handle = nullptr;
+}
+
} // namespace Common
#endif