mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-10-20 15:09:10 +00:00
Merge pull request #13752 from jordan-woyak/xlib-duplicate-key-names
ControllerInterface/Xlib: Combine keycodes with the same name to fix non-working inputs.
This commit is contained in:
commit
c9c57f8ba4
2 changed files with 50 additions and 20 deletions
|
@ -4,16 +4,16 @@
|
||||||
#include "InputCommon/ControllerInterface/Xlib/XInput2.h"
|
#include "InputCommon/ControllerInterface/Xlib/XInput2.h"
|
||||||
|
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
|
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
#include <cmath>
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/StringUtil.h"
|
|
||||||
|
|
||||||
#include "Core/Host.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);
|
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
|
// Keyboard Keys
|
||||||
int min_keycode, max_keycode;
|
int min_keycode = 0;
|
||||||
|
int max_keycode = 0;
|
||||||
XDisplayKeycodes(m_display, &min_keycode, &max_keycode);
|
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());
|
const auto* const keycode_name = Key::GetNameForKeyCode(m_display, keycode);
|
||||||
if (temp_key->m_keyname.length())
|
if (keycode_name == nullptr)
|
||||||
AddInput(temp_key);
|
continue;
|
||||||
|
|
||||||
|
auto& key_input = keys[keycode_name];
|
||||||
|
if (key_input == nullptr)
|
||||||
|
AddInput(key_input = new Key(keycode_name, keycode, m_state.keyboard.data()));
|
||||||
else
|
else
|
||||||
delete temp_key;
|
key_input->AddKeyCode(keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add combined left/right modifiers with consistent naming across platforms.
|
// Add combined left/right modifiers with consistent naming across platforms.
|
||||||
|
@ -426,14 +434,18 @@ int KeyboardMouse::GetSortPriority() const
|
||||||
return DEFAULT_DEVICE_SORT_PRIORITY;
|
return DEFAULT_DEVICE_SORT_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* keyboard)
|
KeyboardMouse::Key::Key(std::string key_name, KeyCode keycode, const char* keyboard)
|
||||||
: m_display(display), m_keyboard(keyboard), m_keycode(keycode)
|
: 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;
|
int i = 0;
|
||||||
KeySym keysym = 0;
|
KeySym keysym = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
keysym = XkbKeycodeToKeysym(m_display, keycode, i, 0);
|
keysym = XkbKeycodeToKeysym(display, keycode, i, 0);
|
||||||
i++;
|
i++;
|
||||||
} while (keysym == NoSymbol && i < 8);
|
} 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
|
// 0x0110ffff is the top of the unicode character range according
|
||||||
// to keysymdef.h although it is probably more than we need.
|
// to keysymdef.h although it is probably more than we need.
|
||||||
if (keysym == NoSymbol || keysym > 0x0110ffff || XKeysymToString(keysym) == nullptr)
|
if (keysym == NoSymbol || keysym > 0x0110ffff || XKeysymToString(keysym) == nullptr)
|
||||||
m_keyname = std::string();
|
return nullptr;
|
||||||
else
|
|
||||||
m_keyname = std::string(XKeysymToString(keysym));
|
return XKeysymToString(keysym);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlState KeyboardMouse::Key::GetState() const
|
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)
|
KeyboardMouse::Button::Button(unsigned int index, u32* buttons) : m_buttons(buttons), m_index(index)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
@ -39,15 +41,20 @@ private:
|
||||||
friend class KeyboardMouse;
|
friend class KeyboardMouse;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Key(std::string name, KeyCode keycode, const char* keyboard);
|
||||||
|
|
||||||
std::string GetName() const override { return m_keyname; }
|
std::string GetName() const override { return m_keyname; }
|
||||||
Key(Display* display, KeyCode keycode, const char* keyboard);
|
|
||||||
ControlState GetState() const override;
|
ControlState GetState() const override;
|
||||||
|
|
||||||
|
static const char* GetNameForKeyCode(Display* display, KeyCode keycode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_keyname;
|
void AddKeyCode(KeyCode);
|
||||||
Display* const m_display;
|
bool IsKeyCodePressed(KeyCode) const;
|
||||||
|
|
||||||
|
const std::string m_keyname;
|
||||||
const char* const m_keyboard;
|
const char* const m_keyboard;
|
||||||
const KeyCode m_keycode;
|
std::vector<KeyCode> m_keycodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Button : public Input
|
class Button : public Input
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue