diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2025-06-12 04:50:13 -0500 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2025-06-12 04:50:13 -0500 |
| commit | 4f3e52718608ccddcb24d3b6c9c8bbd65462bee0 (patch) | |
| tree | 9393bb73cc596a569c8ef1f42ce7dbb948ad7963 /Source/Core/InputCommon/ControllerInterface | |
| parent | a16387741383ca00524f78f9854c55be7089cf93 (diff) | |
ControllerInterface/Xlib: Combine keycodes with the same name to fix non-working inputs.
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface')
| -rw-r--r-- | Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp | 55 | ||||
| -rw-r--r-- | Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h | 15 |
2 files changed, 50 insertions, 20 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index 6bed306dca..309ed701cb 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -4,16 +4,16 @@ #include "InputCommon/ControllerInterface/Xlib/XInput2.h" #include <X11/XKBlib.h> - #include <X11/extensions/XInput2.h> -#include <cmath> + +#include <algorithm> #include <cstdlib> #include <cstring> +#include <map> #include <fmt/format.h> #include "Common/Logging/Log.h" -#include "Common/StringUtil.h" #include "Core/Host.h" @@ -210,16 +210,24 @@ KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboar XISelectEvents(m_display, DefaultRootWindow(m_display), &mask, 1); } + // Temporary map to combine keycodes with the same name. + std::map<std::string, Key*> keys; + // Keyboard Keys - int min_keycode, max_keycode; + int min_keycode = 0; + int max_keycode = 0; XDisplayKeycodes(m_display, &min_keycode, &max_keycode); - for (int i = min_keycode; i <= max_keycode; ++i) + for (int keycode = min_keycode; keycode <= max_keycode; ++keycode) { - Key* const temp_key = new Key(m_display, i, m_state.keyboard.data()); - if (temp_key->m_keyname.length()) - AddInput(temp_key); + const auto* const keycode_name = Key::GetNameForKeyCode(m_display, keycode); + if (keycode_name == nullptr) + continue; + + auto& key_input = keys[keycode_name]; + if (key_input == nullptr) + AddInput(key_input = new Key(keycode_name, keycode, m_state.keyboard.data())); else - delete temp_key; + key_input->AddKeyCode(keycode); } // Add combined left/right modifiers with consistent naming across platforms. @@ -426,14 +434,18 @@ int KeyboardMouse::GetSortPriority() const return DEFAULT_DEVICE_SORT_PRIORITY; } -KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* keyboard) - : m_display(display), m_keyboard(keyboard), m_keycode(keycode) +KeyboardMouse::Key::Key(std::string key_name, KeyCode keycode, const char* keyboard) + : m_keyname{std::move(key_name)}, m_keyboard(keyboard), m_keycodes{keycode} +{ +} + +const char* KeyboardMouse::Key::GetNameForKeyCode(Display* const display, KeyCode keycode) { int i = 0; KeySym keysym = 0; do { - keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0); + keysym = XkbKeycodeToKeysym(display, keycode, i, 0); i++; } while (keysym == NoSymbol && i < 8); @@ -444,14 +456,25 @@ KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* key // 0x0110ffff is the top of the unicode character range according // to keysymdef.h although it is probably more than we need. if (keysym == NoSymbol || keysym > 0x0110ffff || XKeysymToString(keysym) == nullptr) - m_keyname = std::string(); - else - m_keyname = std::string(XKeysymToString(keysym)); + return nullptr; + + return XKeysymToString(keysym); } ControlState KeyboardMouse::Key::GetState() const { - return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; + return ControlState( + std::ranges::any_of(m_keycodes, std::bind_front(&Key::IsKeyCodePressed, this))); +} + +void KeyboardMouse::Key::AddKeyCode(KeyCode keycode) +{ + m_keycodes.emplace_back(keycode); +} + +bool KeyboardMouse::Key::IsKeyCodePressed(KeyCode keycode) const +{ + return (m_keyboard[keycode / 8] & (1 << (keycode % 8))) != 0; } KeyboardMouse::Button::Button(unsigned int index, u32* buttons) : m_buttons(buttons), m_index(index) diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h index f6fc108e10..414480584f 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h @@ -6,6 +6,8 @@ #pragma once #include <array> +#include <string> +#include <vector> extern "C" { #include <X11/Xlib.h> @@ -39,15 +41,20 @@ private: friend class KeyboardMouse; public: + Key(std::string name, KeyCode keycode, const char* keyboard); + std::string GetName() const override { return m_keyname; } - Key(Display* display, KeyCode keycode, const char* keyboard); ControlState GetState() const override; + static const char* GetNameForKeyCode(Display* display, KeyCode keycode); + private: - std::string m_keyname; - Display* const m_display; + void AddKeyCode(KeyCode); + bool IsKeyCodePressed(KeyCode) const; + + const std::string m_keyname; const char* const m_keyboard; - const KeyCode m_keycode; + std::vector<KeyCode> m_keycodes; }; class Button : public Input |
