summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-06-07 12:15:15 +0200
committerGitHub <noreply@github.com>2021-06-07 12:15:15 +0200
commit8ca6ffd908aa95ffb5c7665083463c4ea1139b0d (patch)
tree5a058d8aa001d2577f7e65d5aa44ec86737c3386 /Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp
parentebe3fbe04c329f9bc100ded4dcf22720f375e2f4 (diff)
parent83ea16f40238fa82981221ba65061a7094b2a64b (diff)
Merge pull request #9702 from Filoppi/controller_interface_fixes
Controller Interface refactor
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp b/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp
index b7cf19a13d..066c50a693 100644
--- a/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/Win32/Win32.cpp
@@ -11,6 +11,7 @@
#include <thread>
#include "Common/Event.h"
+#include "Common/Flag.h"
#include "Common/Logging/Log.h"
#include "Common/ScopeGuard.h"
#include "Common/Thread.h"
@@ -19,20 +20,30 @@
constexpr UINT WM_DOLPHIN_STOP = WM_USER;
-static Common::Event s_done_populating;
-static std::atomic<HWND> s_hwnd;
+static Common::Event s_received_device_change_event;
+// Dolphin's render window
+static HWND s_hwnd;
+// Windows messaging window (hidden)
static HWND s_message_window;
static std::thread s_thread;
+static Common::Flag s_first_populate_devices_asked;
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_INPUT_DEVICE_CHANGE)
{
- g_controller_interface.PlatformPopulateDevices([] {
- ciface::DInput::PopulateDevices(s_hwnd);
- ciface::XInput::PopulateDevices();
- });
- s_done_populating.Set();
+ // Windows automatically sends this message before we ask for it and before we are "ready" to
+ // listen for it.
+ if (s_first_populate_devices_asked.IsSet())
+ {
+ s_received_device_change_event.Set();
+ // TODO: we could easily use the message passed alongside this event, which tells
+ // whether a device was added or removed, to avoid removing old, still connected, devices
+ g_controller_interface.PlatformPopulateDevices([] {
+ ciface::DInput::PopulateDevices(s_hwnd);
+ ciface::XInput::PopulateDevices();
+ });
+ }
}
return DefWindowProc(hwnd, message, wparam, lparam);
@@ -125,10 +136,14 @@ void ciface::Win32::PopulateDevices(void* hwnd)
if (s_thread.joinable())
{
s_hwnd = static_cast<HWND>(hwnd);
- s_done_populating.Reset();
+ s_first_populate_devices_asked.Set();
+ s_received_device_change_event.Reset();
+ // Do this forced devices refresh in the messaging thread so it won't cause any race conditions
PostMessage(s_message_window, WM_INPUT_DEVICE_CHANGE, 0, 0);
- if (!s_done_populating.WaitFor(std::chrono::seconds(10)))
- ERROR_LOG_FMT(CONTROLLERINTERFACE, "win32 timed out when trying to populate devices");
+ std::thread([] {
+ if (!s_received_device_change_event.WaitFor(std::chrono::seconds(5)))
+ ERROR_LOG_FMT(CONTROLLERINTERFACE, "win32 timed out when trying to populate devices");
+ }).detach();
}
else
{
@@ -137,6 +152,15 @@ void ciface::Win32::PopulateDevices(void* hwnd)
}
}
+void ciface::Win32::ChangeWindow(void* hwnd)
+{
+ if (s_thread.joinable()) // "Has init?"
+ {
+ s_hwnd = static_cast<HWND>(hwnd);
+ ciface::DInput::ChangeWindow(s_hwnd);
+ }
+}
+
void ciface::Win32::DeInit()
{
NOTICE_LOG_FMT(CONTROLLERINTERFACE, "win32 DeInit");
@@ -145,7 +169,11 @@ void ciface::Win32::DeInit()
PostMessage(s_message_window, WM_DOLPHIN_STOP, 0, 0);
s_thread.join();
s_message_window = nullptr;
+ s_received_device_change_event.Reset();
+ s_first_populate_devices_asked.Clear();
+ DInput::DeInit();
}
+ s_hwnd = nullptr;
XInput::DeInit();
}