From b0550027c38818d2c232c739639f1de798c248c4 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 21 May 2024 23:51:55 +0200 Subject: [PATCH] input: implement raw mouse hot swap --- rpcs3/Input/raw_mouse_handler.cpp | 82 ++++++++++++++++++++++--------- rpcs3/Input/raw_mouse_handler.h | 7 ++- 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/rpcs3/Input/raw_mouse_handler.cpp b/rpcs3/Input/raw_mouse_handler.cpp index 42877391e1..5afbac3c29 100644 --- a/rpcs3/Input/raw_mouse_handler.cpp +++ b/rpcs3/Input/raw_mouse_handler.cpp @@ -219,6 +219,14 @@ raw_mouse_handler::raw_mouse_handler(bool ignore_config) raw_mouse_handler::~raw_mouse_handler() { + if (m_thread) + { + auto& thread = *m_thread; + thread = thread_state::aborting; + thread(); + m_thread.reset(); + } + if (!m_registered_raw_input_devices) { return; @@ -252,35 +260,20 @@ void raw_mouse_handler::Init(const u32 max_connect) input_log.notice("raw_mouse_handler: Could not load raw mouse config. Using defaults."); } - enumerate_devices(max_connect); - m_mice.clear(); + m_mice.resize(max_connect); // Get max device index - u32 now_connect = 0; std::set connected_mice{}; + const u32 now_connect = get_now_connect(connected_mice); - { - std::lock_guard lock(m_raw_mutex); - - for (const auto& [handle, mouse] : m_raw_mice) - { - now_connect = std::max(now_connect, mouse.index() + 1); - connected_mice.insert(mouse.index()); - } - } - - for (u32 i = 0; i < max_connect; i++) - { - m_mice.emplace_back(Mouse()); - } - + // Init mouse info m_info = {}; m_info.max_connect = max_connect; m_info.now_connect = std::min(now_connect, max_connect); m_info.info = input::g_mice_intercepted ? CELL_MOUSE_INFO_INTERCEPTED : 0; // Ownership of mouse data: 0=Application, 1=System - for (u32 i = 0; i < m_info.now_connect; i++) + for (u32 i = 0; i < m_info.max_connect; i++) { m_info.status[i] = connected_mice.contains(i) ? CELL_MOUSE_STATUS_CONNECTED : CELL_MOUSE_STATUS_DISCONNECTED; m_info.mode[i] = CELL_MOUSE_INFO_TABLET_MOUSE_MODE; @@ -289,11 +282,38 @@ void raw_mouse_handler::Init(const u32 max_connect) m_info.product_id[0] = 0x1234; } -#ifdef _WIN32 - register_raw_input_devices(); -#endif - type = mouse_handler::raw; + + m_thread = std::make_unique>>("Raw Mouse Thread", [this, max_connect]() + { + input_log.notice("raw_mouse_handler: thread started"); + + while (thread_ctrl::state() != thread_state::aborting) + { + enumerate_devices(max_connect); + + // Update mouse info + std::set connected_mice{}; + const u32 now_connect = get_now_connect(connected_mice); + { + std::lock_guard lock(mutex); + + m_info.now_connect = std::min(now_connect, max_connect); + + for (u32 i = 0; i < m_info.max_connect; i++) + { + m_info.status[i] = connected_mice.contains(i) ? CELL_MOUSE_STATUS_CONNECTED : CELL_MOUSE_STATUS_DISCONNECTED; + } + } + +#ifdef _WIN32 + register_raw_input_devices(); +#endif + thread_ctrl::wait_for(1'000'000); + } + + input_log.notice("raw_mouse_handler: thread stopped"); + }); } #ifdef _WIN32 @@ -334,6 +354,22 @@ void raw_mouse_handler::register_raw_input_devices() } #endif +u32 raw_mouse_handler::get_now_connect(std::set& connected_mice) +{ + u32 now_connect = 0; + connected_mice.clear(); + { + std::lock_guard lock(m_raw_mutex); + + for (const auto& [handle, mouse] : m_raw_mice) + { + now_connect = std::max(now_connect, mouse.index() + 1); + connected_mice.insert(mouse.index()); + } + } + return now_connect; +} + void raw_mouse_handler::enumerate_devices(u32 max_connect) { input_log.notice("raw_mouse_handler: enumerating devices (max_connect=%d)", max_connect); diff --git a/rpcs3/Input/raw_mouse_handler.h b/rpcs3/Input/raw_mouse_handler.h index 2aa11893d8..7f43d534c5 100644 --- a/rpcs3/Input/raw_mouse_handler.h +++ b/rpcs3/Input/raw_mouse_handler.h @@ -3,6 +3,8 @@ #include "Emu/Io/MouseHandler.h" #include "Emu/RSX/display.h" #include "Utilities/Config.h" +#include "Utilities/Mutex.h" +#include "Utilities/Thread.h" #ifdef _WIN32 #include @@ -87,6 +89,7 @@ public: #endif private: + u32 get_now_connect(std::set& connected_mice); void enumerate_devices(u32 max_connect); #ifdef _WIN32 @@ -95,7 +98,9 @@ private: #endif bool m_ignore_config = false; - std::mutex m_raw_mutex; + shared_mutex m_raw_mutex; std::map m_raw_mice; std::function m_mouse_press_callback; + + std::unique_ptr>> m_thread; };