#pragma once #include "util/types.hpp" #include "util/atomic.hpp" #include "Emu/Io/pad_types.h" #include "Emu/Io/pad_config.h" #include "Emu/Io/pad_config_types.h" #include "util/Timer.h" #include "util/Thread.h" class PadHandlerBase; class gui_settings; class gui_pad_thread { public: gui_pad_thread(); virtual ~gui_pad_thread(); void update_settings(const std::shared_ptr& settings); static std::shared_ptr GetHandler(pad_handler type); static void InitPadConfig(cfg_pad& cfg, pad_handler type, std::shared_ptr& handler); static void reset() { m_reset = true; } protected: bool init(); void run(); void process_input(); enum class mouse_button { none, left, right, middle }; enum class mouse_wheel { none, vertical, horizontal }; void send_key_event(u32 key, bool pressed); void send_mouse_button_event(mouse_button btn, bool pressed); void send_mouse_wheel_event(mouse_wheel wheel, int delta); void send_mouse_move_event(int delta_x, int delta_y); #ifdef __linux__ int m_uinput_fd = -1; void emit_event(int type, int code, int val); #endif std::shared_ptr m_handler; std::shared_ptr m_pad; std::unique_ptr>> m_thread; atomic_t m_allow_global_input = false; static atomic_t m_reset; std::array(pad_button::pad_button_max_enum)> m_last_button_state{}; steady_clock::time_point m_timestamp; steady_clock::time_point m_initial_timestamp; Timer m_input_timer; static constexpr u64 auto_repeat_ms_interval_default = 200; pad_button m_last_auto_repeat_button = pad_button::pad_button_max_enum; std::map m_auto_repeat_buttons = { {pad_button::dpad_up, auto_repeat_ms_interval_default}, {pad_button::dpad_down, auto_repeat_ms_interval_default}, {pad_button::dpad_left, auto_repeat_ms_interval_default}, {pad_button::dpad_right, auto_repeat_ms_interval_default}, {pad_button::rs_up, 1}, // used for wheel scrolling by default {pad_button::rs_down, 1}, // used for wheel scrolling by default {pad_button::rs_left, 1}, // used for wheel scrolling by default {pad_button::rs_right, 1} // used for wheel scrolling by default }; // Mouse movement should just work without delays std::map m_mouse_move_buttons = { {pad_button::ls_up, 1}, {pad_button::ls_down, 1}, {pad_button::ls_left, 1}, {pad_button::ls_right, 1}}; pad_button m_mouse_boost_button = pad_button::L2; bool m_boost_mouse = false; float m_mouse_delta_x = 0.0f; float m_mouse_delta_y = 0.0f; #ifdef __APPLE__ float m_mouse_abs_x = 0.0f; float m_mouse_abs_y = 0.0f; #endif };