From f90d851e2519d46f62e2037896053bc546e7133b Mon Sep 17 00:00:00 2001 From: Filoppi Date: Sat, 15 May 2021 11:32:00 +0300 Subject: ControllerInterface: mixed comments --- .../InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index ebe2e84286..bc1820b8ad 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -91,6 +91,11 @@ KeyboardMouse::~KeyboardMouse() { s_keyboard_mouse_exists = false; + // Independently of the order in which we do these, if we put a breakpoint on Unacquire() (or in + // any place in the call stack before this), when refreshing devices from the UI, on the second + // attempt, it will get stuck in an infinite (while) loop inside dinput8.dll. Given that it can't + // be otherwise be reproduced (not even with sleeps), we can just ignore the problem. + // kb m_kb_device->Unacquire(); m_kb_device->Release(); -- cgit v1.2.3 From dcc345400e38e54ac84819e5cbcdf65c9cd95f96 Mon Sep 17 00:00:00 2001 From: Filoppi Date: Sat, 15 May 2021 12:14:11 +0300 Subject: ControllerInterface: devices population is now async so implement devices sorting priority This helps us keeping the most important devices (e.g. Mouse and Keyboard) on the top of the list of devices (they still are on all OSes supported by dolphin and to make hotplug devices like DSU appear at the bottom. --- .../InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index bc1820b8ad..0da09ad6e0 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -230,6 +230,12 @@ std::string KeyboardMouse::GetSource() const return DINPUT_SOURCE_NAME; } +// Give this device a higher priority to make sure it shows first +int KeyboardMouse::GetSortPriority() const +{ + return 5; +} + // names std::string KeyboardMouse::Key::GetName() const { -- cgit v1.2.3 From a0ecca1a84afb61809aa848405f119a9a7fff965 Mon Sep 17 00:00:00 2001 From: Filoppi Date: Sat, 15 May 2021 12:20:20 +0300 Subject: ControllerInterface: Implement ChangeWindow on DInput without recreating the devices Also polished DInput code in general to try and mitigate issue 11702. Added a lot of logging and comments. --- .../DInput/DInputKeyboardMouse.cpp | 39 ++++++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index 0da09ad6e0..e952da6660 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -6,7 +6,8 @@ #include -#include +#include "Common/Logging/Log.h" +#include "Core/Core.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/ControllerInterface/DInput/DInput.h" @@ -54,15 +55,18 @@ static const struct #include "InputCommon/ControllerInterface/DInput/NamedKeys.h" // NOLINT }; -// Prevent duplicate keyboard/mouse devices. -static bool s_keyboard_mouse_exists = false; +// Prevent duplicate keyboard/mouse devices. Modified by more threads. +static bool s_keyboard_mouse_exists; +static HWND s_hwnd; void InitKeyboardMouse(IDirectInput8* const idi8, HWND hwnd) { if (s_keyboard_mouse_exists) return; - // mouse and keyboard are a combined device, to allow shift+click and stuff + s_hwnd = hwnd; + + // Mouse and keyboard are a combined device, to allow shift+click and stuff // if that's dumb, I will make a VirtualDevice class that just uses ranges of inputs/outputs from // other devices // so there can be a separated Keyboard and mouse, as well as combined KeyboardMouse @@ -70,6 +74,8 @@ void InitKeyboardMouse(IDirectInput8* const idi8, HWND hwnd) LPDIRECTINPUTDEVICE8 kb_device = nullptr; LPDIRECTINPUTDEVICE8 mo_device = nullptr; + // These are "virtual" system devices, so they are always there even if we have no physical + // mouse and keyboard plugged into the computer if (SUCCEEDED(idi8->CreateDevice(GUID_SysKeyboard, &kb_device, nullptr)) && SUCCEEDED(kb_device->SetDataFormat(&c_dfDIKeyboard)) && SUCCEEDED(kb_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)) && @@ -77,16 +83,23 @@ void InitKeyboardMouse(IDirectInput8* const idi8, HWND hwnd) SUCCEEDED(mo_device->SetDataFormat(&c_dfDIMouse2)) && SUCCEEDED(mo_device->SetCooperativeLevel(nullptr, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) { - g_controller_interface.AddDevice(std::make_shared(kb_device, mo_device, hwnd)); + g_controller_interface.AddDevice(std::make_shared(kb_device, mo_device)); return; } + ERROR_LOG_FMT(CONTROLLERINTERFACE, "KeyboardMouse device failed to be created"); + if (kb_device) kb_device->Release(); if (mo_device) mo_device->Release(); } +void SetKeyboardMouseWindow(HWND hwnd) +{ + s_hwnd = hwnd; +} + KeyboardMouse::~KeyboardMouse() { s_keyboard_mouse_exists = false; @@ -105,9 +118,8 @@ KeyboardMouse::~KeyboardMouse() } KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, - const LPDIRECTINPUTDEVICE8 mo_device, HWND hwnd) - : m_kb_device(kb_device), m_mo_device(mo_device), m_hwnd(hwnd), m_last_update(GetTickCount()), - m_state_in() + const LPDIRECTINPUTDEVICE8 mo_device) + : m_kb_device(kb_device), m_mo_device(mo_device), m_last_update(GetTickCount()), m_state_in() { s_keyboard_mouse_exists = true; @@ -160,11 +172,11 @@ void KeyboardMouse::UpdateCursorInput() // Get the cursor position relative to the upper left corner of the current window // (separate or render to main) - ScreenToClient(m_hwnd, &point); + ScreenToClient(s_hwnd, &point); - // Get the size of the current window. (In my case Rect.top and Rect.left was zero.) + // Get the size of the current window (in my case Rect.top and Rect.left was zero). RECT rect; - GetClientRect(m_hwnd, &rect); + GetClientRect(s_hwnd, &rect); // Width and height are the size of the rendering window. They could be 0 const auto win_width = std::max(rect.right - rect.left, 1l); @@ -236,6 +248,11 @@ int KeyboardMouse::GetSortPriority() const return 5; } +bool KeyboardMouse::IsVirtualDevice() const +{ + return true; +} + // names std::string KeyboardMouse::Key::GetName() const { -- cgit v1.2.3 From 8b53af9cbc8aabdd5db349c17a8912c0fec723a8 Mon Sep 17 00:00:00 2001 From: Filoppi Date: Sat, 15 May 2021 12:21:43 +0300 Subject: ControllerInterface: polish DInput Keyboard and Mouse (add comments and logs) Also fix the cursor axis not being updated when the mouse device had failed aquiring, despite them being completely unrelated --- .../DInput/DInputKeyboardMouse.cpp | 32 ++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp') diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp index e952da6660..aaa723849e 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInputKeyboardMouse.cpp @@ -123,8 +123,10 @@ KeyboardMouse::KeyboardMouse(const LPDIRECTINPUTDEVICE8 kb_device, { s_keyboard_mouse_exists = true; - m_kb_device->Acquire(); - m_mo_device->Acquire(); + if (FAILED(m_kb_device->Acquire())) + WARN_LOG_FMT(CONTROLLERINTERFACE, "Keyboard device failed to acquire. We'll retry later"); + if (FAILED(m_mo_device->Acquire())) + WARN_LOG_FMT(CONTROLLERINTERFACE, "Mouse device failed to acquire. We'll retry later"); // KEYBOARD // add keys @@ -191,6 +193,8 @@ void KeyboardMouse::UpdateCursorInput() void KeyboardMouse::UpdateInput() { + UpdateCursorInput(); + DIMOUSESTATE2 tmp_mouse; // if mouse position hasn't been updated in a short while, skip a dev state @@ -207,16 +211,14 @@ void KeyboardMouse::UpdateInput() m_last_update = cur_time; - HRESULT kb_hr = m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard); HRESULT mo_hr = m_mo_device->GetDeviceState(sizeof(tmp_mouse), &tmp_mouse); - - if (DIERR_INPUTLOST == kb_hr || DIERR_NOTACQUIRED == kb_hr) - m_kb_device->Acquire(); - if (DIERR_INPUTLOST == mo_hr || DIERR_NOTACQUIRED == mo_hr) - m_mo_device->Acquire(); - - if (SUCCEEDED(mo_hr)) + { + INFO_LOG_FMT(CONTROLLERINTERFACE, "Mouse device failed to get state"); + if (FAILED(m_mo_device->Acquire())) + INFO_LOG_FMT(CONTROLLERINTERFACE, "Mouse device failed to re-acquire, we'll retry later"); + } + else if (SUCCEEDED(mo_hr)) { m_state_in.relative_mouse.Move({tmp_mouse.lX, tmp_mouse.lY, tmp_mouse.lZ}); m_state_in.relative_mouse.Update(); @@ -227,8 +229,16 @@ void KeyboardMouse::UpdateInput() // copy over the buttons std::copy_n(tmp_mouse.rgbButtons, std::size(tmp_mouse.rgbButtons), m_state_in.mouse.rgbButtons); + } - UpdateCursorInput(); + HRESULT kb_hr = m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard); + if (kb_hr == DIERR_INPUTLOST || kb_hr == DIERR_NOTACQUIRED) + { + INFO_LOG_FMT(CONTROLLERINTERFACE, "Keyboard device failed to get state"); + if (SUCCEEDED(m_kb_device->Acquire())) + m_kb_device->GetDeviceState(sizeof(m_state_in.keyboard), &m_state_in.keyboard); + else + INFO_LOG_FMT(CONTROLLERINTERFACE, "Keyboard device failed to re-acquire, we'll retry later"); } } -- cgit v1.2.3