InputCommon: Add Win32 InputBackend class.

This commit is contained in:
Jordan Woyak 2024-03-11 02:09:31 -05:00
parent 2ac59bf581
commit 341f99a3f1
5 changed files with 50 additions and 29 deletions

View File

@ -59,7 +59,7 @@ void ControllerInterface::Initialize(const WindowSystemInfo& wsi)
m_populating_devices_counter = 1; m_populating_devices_counter = 1;
#ifdef CIFACE_USE_WIN32 #ifdef CIFACE_USE_WIN32
ciface::Win32::Init(wsi.render_window); m_input_backends.emplace_back(ciface::Win32::CreateInputBackend(this));
#endif #endif
#ifdef CIFACE_USE_XLIB #ifdef CIFACE_USE_XLIB
m_input_backends.emplace_back(ciface::XInput2::CreateInputBackend(this)); m_input_backends.emplace_back(ciface::XInput2::CreateInputBackend(this));
@ -135,9 +135,8 @@ void ControllerInterface::RefreshDevices(RefreshReason reason)
{ {
m_populating_devices_counter.fetch_add(1); m_populating_devices_counter.fetch_add(1);
// No need to do anything else in this case. for (auto& backend : m_input_backends)
// Only (Win32) DInput needs the window handle to be updated. backend->HandleWindowChange();
ciface::Win32::ChangeWindow(m_wsi.render_window);
if (m_populating_devices_counter.fetch_sub(1) == 1) if (m_populating_devices_counter.fetch_sub(1) == 1)
InvokeDevicesChangedCallbacks(); InvokeDevicesChangedCallbacks();
@ -159,9 +158,6 @@ void ControllerInterface::RefreshDevices(RefreshReason reason)
// do it async, to not risk the emulated controllers default config loading not finding a default // do it async, to not risk the emulated controllers default config loading not finding a default
// device. // device.
#ifdef CIFACE_USE_WIN32
ciface::Win32::PopulateDevices(m_wsi.render_window);
#endif
#ifdef CIFACE_USE_ANDROID #ifdef CIFACE_USE_ANDROID
ciface::Android::PopulateDevices(); ciface::Android::PopulateDevices();
#endif #endif
@ -204,9 +200,6 @@ void ControllerInterface::Shutdown()
// Update control references so shared_ptr<Device>s are freed up BEFORE we shutdown the backends. // Update control references so shared_ptr<Device>s are freed up BEFORE we shutdown the backends.
ClearDevices(); ClearDevices();
#ifdef CIFACE_USE_WIN32
ciface::Win32::DeInit();
#endif
#ifdef CIFACE_USE_ANDROID #ifdef CIFACE_USE_ANDROID
ciface::Android::Shutdown(); ciface::Android::Shutdown();
#endif #endif

View File

@ -16,6 +16,10 @@ void InputBackend::UpdateInput(std::vector<std::weak_ptr<ciface::Core::Device>>&
{ {
} }
void InputBackend::HandleWindowChange()
{
}
ControllerInterface& InputBackend::GetControllerInterface() ControllerInterface& InputBackend::GetControllerInterface()
{ {
return m_controller_interface; return m_controller_interface;

View File

@ -28,6 +28,8 @@ public:
// just add them to the removal list if necessary. // just add them to the removal list if necessary.
virtual void UpdateInput(std::vector<std::weak_ptr<ciface::Core::Device>>& devices_to_remove); virtual void UpdateInput(std::vector<std::weak_ptr<ciface::Core::Device>>& devices_to_remove);
virtual void HandleWindowChange();
ControllerInterface& GetControllerInterface(); ControllerInterface& GetControllerInterface();
private: private:

View File

@ -20,13 +20,25 @@
#pragma comment(lib, "OneCoreUAP.Lib") #pragma comment(lib, "OneCoreUAP.Lib")
// Dolphin's render window
static HWND s_hwnd;
static std::mutex s_populate_mutex; static std::mutex s_populate_mutex;
// TODO is this really needed? // TODO is this really needed?
static Common::Flag s_first_populate_devices_asked; static Common::Flag s_first_populate_devices_asked;
static HCMNOTIFICATION s_notify_handle; static HCMNOTIFICATION s_notify_handle;
namespace ciface::Win32
{
class InputBackend final : public ciface::InputBackend
{
public:
InputBackend(ControllerInterface* controller_interface);
~InputBackend();
void PopulateDevices() override;
void HandleWindowChange() override;
HWND GetHWND();
};
} // namespace ciface::Win32
_Pre_satisfies_(EventDataSize >= sizeof(CM_NOTIFY_EVENT_DATA)) static DWORD CALLBACK _Pre_satisfies_(EventDataSize >= sizeof(CM_NOTIFY_EVENT_DATA)) static DWORD CALLBACK
OnDevicesChanged(_In_ HCMNOTIFICATION hNotify, _In_opt_ PVOID Context, OnDevicesChanged(_In_ HCMNOTIFICATION hNotify, _In_opt_ PVOID Context,
_In_ CM_NOTIFY_ACTION Action, _In_ CM_NOTIFY_ACTION Action,
@ -43,8 +55,9 @@ _Pre_satisfies_(EventDataSize >= sizeof(CM_NOTIFY_EVENT_DATA)) static DWORD CALL
std::lock_guard lk_population(s_populate_mutex); std::lock_guard lk_population(s_populate_mutex);
// TODO: we could easily use the message passed alongside this event, which tells // 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 // whether a device was added or removed, to avoid removing old, still connected, devices
g_controller_interface.PlatformPopulateDevices([] { g_controller_interface.PlatformPopulateDevices([&] {
ciface::DInput::PopulateDevices(s_hwnd); ciface::DInput::PopulateDevices(
static_cast<ciface::Win32::InputBackend*>(Context)->GetHWND());
ciface::XInput::PopulateDevices(); ciface::XInput::PopulateDevices();
}); });
} }
@ -52,10 +65,21 @@ _Pre_satisfies_(EventDataSize >= sizeof(CM_NOTIFY_EVENT_DATA)) static DWORD CALL
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
void ciface::Win32::Init(void* hwnd) namespace ciface::Win32
{ {
s_hwnd = static_cast<HWND>(hwnd); std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface)
{
return std::make_unique<InputBackend>(controller_interface);
}
HWND InputBackend::GetHWND()
{
return static_cast<HWND>(GetControllerInterface().GetWindowSystemInfo().render_window);
}
InputBackend::InputBackend(ControllerInterface* controller_interface)
: ciface::InputBackend(controller_interface)
{
XInput::Init(); XInput::Init();
WGInput::Init(); WGInput::Init();
@ -63,35 +87,32 @@ void ciface::Win32::Init(void* hwnd)
.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE, .FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE,
.u{.DeviceInterface{.ClassGuid = GUID_DEVINTERFACE_HID}}}; .u{.DeviceInterface{.ClassGuid = GUID_DEVINTERFACE_HID}}};
const CONFIGRET cfg_rv = const CONFIGRET cfg_rv =
CM_Register_Notification(&notify_filter, nullptr, OnDevicesChanged, &s_notify_handle); CM_Register_Notification(&notify_filter, this, OnDevicesChanged, &s_notify_handle);
if (cfg_rv != CR_SUCCESS) if (cfg_rv != CR_SUCCESS)
{ {
ERROR_LOG_FMT(CONTROLLERINTERFACE, "CM_Register_Notification failed: {:x}", cfg_rv); ERROR_LOG_FMT(CONTROLLERINTERFACE, "CM_Register_Notification failed: {:x}", cfg_rv);
} }
} }
void ciface::Win32::PopulateDevices(void* hwnd) void InputBackend::PopulateDevices()
{ {
s_hwnd = static_cast<HWND>(hwnd);
std::lock_guard lk_population(s_populate_mutex); std::lock_guard lk_population(s_populate_mutex);
s_first_populate_devices_asked.Set(); s_first_populate_devices_asked.Set();
ciface::DInput::PopulateDevices(s_hwnd); ciface::DInput::PopulateDevices(GetHWND());
ciface::XInput::PopulateDevices(); ciface::XInput::PopulateDevices();
ciface::WGInput::PopulateDevices(); ciface::WGInput::PopulateDevices();
} }
void ciface::Win32::ChangeWindow(void* hwnd) void InputBackend::HandleWindowChange()
{ {
s_hwnd = static_cast<HWND>(hwnd);
std::lock_guard lk_population(s_populate_mutex); std::lock_guard lk_population(s_populate_mutex);
ciface::DInput::ChangeWindow(s_hwnd); ciface::DInput::ChangeWindow(GetHWND());
} }
void ciface::Win32::DeInit() InputBackend::~InputBackend()
{ {
s_first_populate_devices_asked.Clear(); s_first_populate_devices_asked.Clear();
DInput::DeInit(); DInput::DeInit();
s_hwnd = nullptr;
if (s_notify_handle) if (s_notify_handle)
{ {
@ -106,3 +127,5 @@ void ciface::Win32::DeInit()
XInput::DeInit(); XInput::DeInit();
WGInput::DeInit(); WGInput::DeInit();
} }
} // namespace ciface::Win32

View File

@ -3,10 +3,9 @@
#pragma once #pragma once
#include "InputCommon/ControllerInterface/InputBackend.h"
namespace ciface::Win32 namespace ciface::Win32
{ {
void Init(void* hwnd); std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface);
void PopulateDevices(void* hwnd);
void ChangeWindow(void* hwnd);
void DeInit();
} // namespace ciface::Win32 } // namespace ciface::Win32