input: use keyboard consumers to seperate cell and overlay logic

This commit is contained in:
Megamouse 2024-04-25 23:17:27 +02:00
parent 6fc7fa3b13
commit fcba193a3c
8 changed files with 269 additions and 107 deletions

3
.gitignore vendored
View file

@ -130,6 +130,9 @@ yaml-cpp.pc
# miniupnp
/3rdparty/miniupnp/x64/*
# opencv
/3rdparty/opencv/*
# llvm
/3rdparty/llvm/llvm_build

View file

@ -42,13 +42,16 @@ KeyboardHandlerBase::KeyboardHandlerBase(utils::serial* ar)
return;
}
(*ar)(m_info.max_connect);
u32 max_connect = 0;
if (m_info.max_connect)
(*ar)(max_connect);
if (max_connect)
{
Emu.PostponeInitCode([this]()
Emu.PostponeInitCode([this, max_connect]()
{
Init(m_info.max_connect);
std::lock_guard<std::mutex> lock(m_mutex);
AddConsumer(keyboard_consumer::identifier::cellKb, max_connect);
auto lk = init.init();
});
}
@ -56,9 +59,20 @@ KeyboardHandlerBase::KeyboardHandlerBase(utils::serial* ar)
void KeyboardHandlerBase::save(utils::serial& ar)
{
u32 max_connect = 0;
const auto inited = init.access();
ar(inited ? m_info.max_connect : 0);
if (inited)
{
std::lock_guard<std::mutex> lock(m_mutex);
if (auto it = m_consumers.find(keyboard_consumer::identifier::cellKb); it != m_consumers.end())
{
max_connect = it->second.GetInfo().max_connect;
}
}
ar(max_connect);
}
error_code cellKbInit(ppu_thread& ppu, u32 max_connect)
@ -79,7 +93,9 @@ error_code cellKbInit(ppu_thread& ppu, u32 max_connect)
}
sys_config_start(ppu);
handler.Init(std::min(max_connect, 7u));
std::lock_guard<std::mutex> lock(handler.m_mutex);
handler.AddConsumer(keyboard_consumer::identifier::cellKb, std::min(max_connect, 7u));
return CELL_OK;
}
@ -95,6 +111,11 @@ error_code cellKbEnd(ppu_thread& ppu)
if (!init)
return CELL_KB_ERROR_UNINITIALIZED;
{
std::lock_guard<std::mutex> lock(handler.m_mutex);
handler.RemoveConsumer(keyboard_consumer::identifier::cellKb);
}
// TODO
sys_config_stop(ppu);
return CELL_OK;
@ -116,12 +137,13 @@ error_code cellKbClearBuf(u32 port_no)
std::lock_guard<std::mutex> lock(handler.m_mutex);
const KbInfo& current_info = handler.GetInfo();
keyboard_consumer& consumer = handler.GetConsumer(keyboard_consumer::identifier::cellKb);
const KbInfo& current_info = consumer.GetInfo();
if (port_no >= handler.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
if (port_no >= consumer.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
return not_an_error(CELL_KB_ERROR_NO_DEVICE);
KbData& current_data = handler.GetData(port_no);
KbData& current_data = consumer.GetData(port_no);
current_data.len = 0;
current_data.led = 0;
current_data.mkey = 0;
@ -298,8 +320,9 @@ error_code cellKbGetInfo(vm::ptr<CellKbInfo> info)
std::memset(info.get_ptr(), 0, info.size());
std::lock_guard<std::mutex> lock(handler.m_mutex);
keyboard_consumer& consumer = handler.GetConsumer(keyboard_consumer::identifier::cellKb);
const KbInfo& current_info = handler.GetInfo();
const KbInfo& current_info = consumer.GetInfo();
info->max_connect = current_info.max_connect;
info->now_connect = current_info.now_connect;
info->info = current_info.info;
@ -327,13 +350,13 @@ error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
return CELL_KB_ERROR_INVALID_PARAMETER;
std::lock_guard<std::mutex> lock(handler.m_mutex);
keyboard_consumer& consumer = handler.GetConsumer(keyboard_consumer::identifier::cellKb);
const KbInfo& current_info = consumer.GetInfo();
const KbInfo& current_info = handler.GetInfo();
if (port_no >= handler.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
if (port_no >= consumer.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
return not_an_error(CELL_KB_ERROR_NO_DEVICE);
KbData& current_data = handler.GetData(port_no);
KbData& current_data = consumer.GetData(port_no);
if (current_info.is_null_handler || (current_info.info & CELL_KB_INFO_INTERCEPTED) || !is_input_allowed())
{
@ -355,7 +378,7 @@ error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
data->keycode[i] = current_data.buttons[i].m_keyCode;
}
KbConfig& current_config = handler.GetConfig(port_no);
KbConfig& current_config = consumer.GetConfig(port_no);
// For single character mode to work properly we need to "flush" the buffer after reading or else we'll constantly get the same key presses with each call.
// Actual key repeats are handled by adding a new key code to the buffer periodically. Key releases are handled in a similar fashion.
@ -383,12 +406,13 @@ error_code cellKbSetCodeType(u32 port_no, u32 type)
if (port_no >= CELL_KB_MAX_KEYBOARDS || type > CELL_KB_CODETYPE_ASCII)
return CELL_KB_ERROR_INVALID_PARAMETER;
if (port_no >= handler.GetKeyboards().size())
std::lock_guard<std::mutex> lock(handler.m_mutex);
keyboard_consumer& consumer = handler.GetConsumer(keyboard_consumer::identifier::cellKb);
if (port_no >= consumer.GetKeyboards().size())
return CELL_OK;
std::lock_guard<std::mutex> lock(handler.m_mutex);
KbConfig& current_config = handler.GetConfig(port_no);
KbConfig& current_config = consumer.GetConfig(port_no);
current_config.code_type = type;
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
@ -413,12 +437,13 @@ error_code cellKbSetLEDStatus(u32 port_no, u8 led)
if (led > 7)
return CELL_KB_ERROR_SYS_SETTING_FAILED;
if (port_no >= handler.GetKeyboards().size() || handler.GetInfo().status[port_no] != CELL_KB_STATUS_CONNECTED)
std::lock_guard<std::mutex> lock(handler.m_mutex);
keyboard_consumer& consumer = handler.GetConsumer(keyboard_consumer::identifier::cellKb);
if (port_no >= consumer.GetKeyboards().size() || consumer.GetInfo().status[port_no] != CELL_KB_STATUS_CONNECTED)
return CELL_KB_ERROR_FATAL;
std::lock_guard<std::mutex> lock(handler.m_mutex);
KbData& current_data = handler.GetData(port_no);
KbData& current_data = consumer.GetData(port_no);
current_data.led = static_cast<u32>(led);
return CELL_OK;
@ -438,16 +463,17 @@ error_code cellKbSetReadMode(u32 port_no, u32 rmode)
if (port_no >= CELL_KB_MAX_KEYBOARDS || rmode > CELL_KB_RMODE_PACKET)
return CELL_KB_ERROR_INVALID_PARAMETER;
if (port_no >= handler.GetKeyboards().size())
std::lock_guard<std::mutex> lock(handler.m_mutex);
keyboard_consumer& consumer = handler.GetConsumer(keyboard_consumer::identifier::cellKb);
if (port_no >= consumer.GetKeyboards().size())
return CELL_OK;
std::lock_guard<std::mutex> lock(handler.m_mutex);
KbConfig& current_config = handler.GetConfig(port_no);
KbConfig& current_config = consumer.GetConfig(port_no);
current_config.read_mode = rmode;
// Key repeat must be disabled in packet mode. But let's just always enable it otherwise.
Keyboard& keyboard = handler.GetKeyboards()[port_no];
Keyboard& keyboard = consumer.GetKeyboards()[port_no];
keyboard.m_key_repeat = rmode != CELL_KB_RMODE_PACKET;
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED
@ -471,16 +497,18 @@ error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
std::lock_guard<std::mutex> lock(handler.m_mutex);
const KbInfo& current_info = handler.GetInfo();
keyboard_consumer& consumer = handler.GetConsumer(keyboard_consumer::identifier::cellKb);
if (port_no >= handler.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
const KbInfo& current_info = consumer.GetInfo();
if (port_no >= consumer.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
return not_an_error(CELL_KB_ERROR_NO_DEVICE);
// tests show that config is checked only after the device's status
if (!config)
return CELL_KB_ERROR_INVALID_PARAMETER;
const KbConfig& current_config = handler.GetConfig(port_no);
const KbConfig& current_config = consumer.GetConfig(port_no);
config->arrange = current_config.arrange;
config->read_mode = current_config.read_mode;
config->code_type = current_config.code_type;

View file

@ -2,6 +2,8 @@
#include "KeyboardHandler.h"
#include "Utilities/StrUtil.h"
LOG_CHANNEL(input_log, "Input");
template <>
void fmt_class_string<CellKbMappingType>::format(std::string& out, u64 arg)
{
@ -40,12 +42,85 @@ void fmt_class_string<CellKbMappingType>::format(std::string& out, u64 arg)
});
}
void KeyboardHandlerBase::Key(u32 code, bool pressed, const std::u32string& key)
template <>
void fmt_class_string<keyboard_consumer::identifier>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](keyboard_consumer::identifier value)
{
switch (value)
{
STR_CASE(keyboard_consumer::identifier::unknown);
STR_CASE(keyboard_consumer::identifier::overlays);
STR_CASE(keyboard_consumer::identifier::cellKb);
}
return unknown;
});
}
keyboard_consumer& KeyboardHandlerBase::AddConsumer(keyboard_consumer::identifier id, u32 max_connect)
{
auto it = m_consumers.find(id);
if (it == m_consumers.end())
{
input_log.notice("Adding keyboard consumer with id %s.", id);
keyboard_consumer& consumer = m_consumers[id];
consumer = keyboard_consumer(id);
Init(consumer, max_connect);
return consumer;
}
return it->second;
}
keyboard_consumer& KeyboardHandlerBase::GetConsumer(keyboard_consumer::identifier id)
{
auto it = m_consumers.find(id);
if (it == m_consumers.end())
{
fmt::throw_exception("No keyboard consumer with id %s", id);
}
return it->second;
}
void KeyboardHandlerBase::RemoveConsumer(keyboard_consumer::identifier id)
{
auto it = m_consumers.find(id);
if (it != m_consumers.end())
{
input_log.notice("Removing keyboard consumer with id %s.", id);
m_consumers.erase(id);
}
}
bool KeyboardHandlerBase::HandleKey(u32 code, bool pressed, bool is_auto_repeat, const std::u32string& key)
{
bool consumed = false;
std::lock_guard<std::mutex> lock(m_mutex);
for (auto& [id, consumer] : m_consumers)
{
consumed |= consumer.ConsumeKey(code, pressed, is_auto_repeat, key);
}
return consumed;
}
bool keyboard_consumer::ConsumeKey(u32 code, bool pressed, bool is_auto_repeat, const std::u32string& key)
{
bool consumed = false;
for (Keyboard& keyboard : m_keyboards)
{
if (is_auto_repeat && !keyboard.m_key_repeat)
{
continue;
}
consumed = true;
KbData& data = keyboard.m_data;
const KbConfig& config = keyboard.m_config;
@ -163,9 +238,11 @@ void KeyboardHandlerBase::Key(u32 code, bool pressed, const std::u32string& key)
}
}
}
return consumed;
}
bool KeyboardHandlerBase::IsMetaKey(u32 code)
bool keyboard_consumer::IsMetaKey(u32 code)
{
return code == Key_Control
|| code == Key_Shift
@ -178,6 +255,14 @@ void KeyboardHandlerBase::SetIntercepted(bool intercepted)
{
std::lock_guard<std::mutex> lock(m_mutex);
for (auto& [id, consumer] : m_consumers)
{
consumer.SetIntercepted(intercepted);
}
}
void keyboard_consumer::SetIntercepted(bool intercepted)
{
m_info.info = intercepted ? CELL_KB_INFO_INTERCEPTED : 0;
if (intercepted)
@ -196,17 +281,25 @@ void KeyboardHandlerBase::SetIntercepted(bool intercepted)
}
void KeyboardHandlerBase::ReleaseAllKeys()
{
for (auto& [id, consumer] : m_consumers)
{
consumer.ReleaseAllKeys();
}
}
void keyboard_consumer::ReleaseAllKeys()
{
for (Keyboard& keyboard : m_keyboards)
{
for (const auto& [key_code, button] : keyboard.m_keys)
{
Key(button.m_keyCode, false, {});
ConsumeKey(button.m_keyCode, false, false, {});
}
for (const std::u32string& key : keyboard.m_extra_data.pressed_keys)
{
Key(CELL_KEYC_NO_EVENT, false, key);
ConsumeKey(CELL_KEYC_NO_EVENT, false, false, key);
}
keyboard.m_extra_data.pressed_keys.clear();

View file

@ -75,21 +75,20 @@ struct Keyboard
std::unordered_map<u32, KbButton> m_keys;
};
class KeyboardHandlerBase
class keyboard_consumer
{
public:
std::mutex m_mutex;
enum class identifier
{
unknown,
overlays,
cellKb,
};
virtual void Init(const u32 max_connect) = 0;
keyboard_consumer() {}
keyboard_consumer(identifier id) : m_id(id) {}
virtual ~KeyboardHandlerBase() = default;
KeyboardHandlerBase(utils::serial* ar);
KeyboardHandlerBase(utils::serial& ar) : KeyboardHandlerBase(&ar) {}
void save(utils::serial& ar);
SAVESTATE_INIT_POS(19);
void Key(u32 code, bool pressed, const std::u32string& key);
bool ConsumeKey(u32 code, bool pressed, bool is_auto_repeat, const std::u32string& key);
void SetIntercepted(bool intercepted);
static bool IsMetaKey(u32 code);
@ -99,12 +98,41 @@ public:
KbData& GetData(const u32 keyboard) { return m_keyboards[keyboard].m_data; }
KbExtraData& GetExtraData(const u32 keyboard) { return m_keyboards[keyboard].m_extra_data; }
KbConfig& GetConfig(const u32 keyboard) { return m_keyboards[keyboard].m_config; }
identifier id() const { return m_id; }
void ReleaseAllKeys();
protected:
identifier m_id = identifier::unknown;
KbInfo m_info{};
std::vector<Keyboard> m_keyboards;
};
class KeyboardHandlerBase
{
public:
std::mutex m_mutex;
virtual void Init(keyboard_consumer& consumer, const u32 max_connect) = 0;
virtual ~KeyboardHandlerBase() = default;
KeyboardHandlerBase(utils::serial* ar);
KeyboardHandlerBase(utils::serial& ar) : KeyboardHandlerBase(&ar) {}
void save(utils::serial& ar);
SAVESTATE_INIT_POS(19);
keyboard_consumer& AddConsumer(keyboard_consumer::identifier id, u32 max_connect);
keyboard_consumer& GetConsumer(keyboard_consumer::identifier id);
void RemoveConsumer(keyboard_consumer::identifier id);
bool HandleKey(u32 code, bool pressed, bool is_auto_repeat, const std::u32string& key);
void SetIntercepted(bool intercepted);
stx::init_mutex init;
protected:
void ReleaseAllKeys();
KbInfo m_info{};
std::vector<Keyboard> m_keyboards;
std::unordered_map<keyboard_consumer::identifier, keyboard_consumer> m_consumers;
};

View file

@ -7,15 +7,18 @@ class NullKeyboardHandler final : public KeyboardHandlerBase
using KeyboardHandlerBase::KeyboardHandlerBase;
public:
void Init(const u32 max_connect) override
void Init(keyboard_consumer& consumer, const u32 max_connect) override
{
m_info = {};
m_info.max_connect = max_connect;
m_info.is_null_handler = true;
m_keyboards.clear();
KbInfo& info = consumer.GetInfo();
std::vector<Keyboard>& keyboards = consumer.GetKeyboards();
info = {};
info.max_connect = max_connect;
info.is_null_handler = true;
keyboards.clear();
for (u32 i = 0; i < max_connect; i++)
{
m_keyboards.emplace_back(Keyboard());
keyboards.emplace_back(Keyboard());
}
}
};

View file

@ -155,13 +155,17 @@ namespace rsx
// Ignored if a keyboard pad handler is active in order to prevent double input.
if (m_keyboard_input_enabled && !m_keyboard_pad_handler_active && input::g_keyboards_intercepted)
{
auto& handler = g_fxo->get<KeyboardHandlerBase>();
std::lock_guard<std::mutex> lock(handler.m_mutex);
auto& kb_handler = g_fxo->get<KeyboardHandlerBase>();
std::lock_guard<std::mutex> lock(kb_handler.m_mutex);
if (!handler.GetKeyboards().empty() && handler.GetInfo().status[0] == CELL_KB_STATUS_CONNECTED)
// Add and get consumer
keyboard_consumer& kb_consumer = kb_handler.AddConsumer(keyboard_consumer::identifier::overlays, 1);
std::vector<Keyboard>& keyboards = kb_consumer.GetKeyboards();
if (!keyboards.empty() && kb_consumer.GetInfo().status[0] == CELL_KB_STATUS_CONNECTED)
{
KbData& current_data = handler.GetData(0);
KbExtraData& extra_data = handler.GetExtraData(0);
KbData& current_data = kb_consumer.GetData(0);
KbExtraData& extra_data = kb_consumer.GetExtraData(0);
if (current_data.len > 0 || !extra_data.pressed_keys.empty())
{
@ -185,16 +189,6 @@ namespace rsx
continue;
}
}
else if (g_cfg.io.keyboard != keyboard_handler::null)
{
// Workaround if cellKb did not init the keyboard handler.
handler.Init(1);
// Enable key repeat
std::vector<Keyboard>& keyboards = handler.GetKeyboards();
ensure(!keyboards.empty());
::at32(keyboards, 0).m_key_repeat = true;
}
}
// Get gamepad input
@ -202,14 +196,9 @@ namespace rsx
const auto handler = pad::get_current_handler();
const PadInfo& rinfo = handler->GetInfo();
if (!rinfo.now_connect || !input::g_pads_intercepted)
{
m_keyboard_pad_handler_active = false;
refresh();
continue;
}
const bool ignore_gamepad_input = (!rinfo.now_connect || !input::g_pads_intercepted);
bool keyboard_pad_handler_active = false;
m_keyboard_pad_handler_active = false;
int pad_index = -1;
for (const auto& pad : handler->GetPads())
@ -244,6 +233,16 @@ namespace rsx
m_keyboard_pad_handler_active = true;
}
if (ignore_gamepad_input)
{
if (m_keyboard_pad_handler_active)
{
break;
}
continue;
}
for (const Button& button : pad->m_buttons)
{
pad_button button_id = pad_button::pad_button_max_enum;
@ -362,11 +361,16 @@ namespace rsx
}
}
m_keyboard_pad_handler_active = keyboard_pad_handler_active;
refresh();
}
// Remove keyboard consumer. We don't need it anymore.
{
auto& kb_handler = g_fxo->get<KeyboardHandlerBase>();
std::lock_guard<std::mutex> lock(kb_handler.m_mutex);
kb_handler.RemoveConsumer(keyboard_consumer::identifier::overlays);
}
// Disable pad interception since this user interface has to be interactive.
// Non-interactive user intefaces handle this in close in order to prevent a g_pad_mutex deadlock.
if (m_stop_pad_interception)

View file

@ -11,26 +11,34 @@
LOG_CHANNEL(input_log, "Input");
void basic_keyboard_handler::Init(const u32 max_connect)
void basic_keyboard_handler::Init(keyboard_consumer& consumer, const u32 max_connect)
{
m_keyboards.clear();
m_info = {};
KbInfo& info = consumer.GetInfo();
std::vector<Keyboard>& keyboards = consumer.GetKeyboards();
info = {};
keyboards.clear();
for (u32 i = 0; i < max_connect; i++)
{
Keyboard kb{};
kb.m_config.arrange = g_cfg.sys.keyboard_type;
m_keyboards.emplace_back(kb);
if (consumer.id() == keyboard_consumer::identifier::overlays)
{
// Enable key repeat
kb.m_key_repeat = true;
}
LoadSettings(kb);
keyboards.emplace_back(kb);
}
LoadSettings();
m_info.max_connect = max_connect;
m_info.now_connect = std::min(::size32(m_keyboards), max_connect);
m_info.info = input::g_keyboards_intercepted ? CELL_KB_INFO_INTERCEPTED : 0; // Ownership of keyboard data: 0=Application, 1=System
m_info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards)
info.max_connect = max_connect;
info.now_connect = std::min(::size32(keyboards), max_connect);
info.info = input::g_keyboards_intercepted ? CELL_KB_INFO_INTERCEPTED : 0; // Ownership of keyboard data: 0=Application, 1=System
info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards)
}
/* Sets the target window for the event handler, and also installs an event filter on the target. */
@ -94,7 +102,7 @@ void basic_keyboard_handler::keyPressEvent(QKeyEvent* keyEvent)
return;
}
if (m_keyboards.empty() || (keyEvent->isAutoRepeat() && !m_keyboards[0].m_key_repeat))
if (m_consumers.empty())
{
keyEvent->ignore();
return;
@ -102,9 +110,9 @@ void basic_keyboard_handler::keyPressEvent(QKeyEvent* keyEvent)
const int key = getUnmodifiedKey(keyEvent);
if (key >= 0)
if (key < 0 || !HandleKey(static_cast<u32>(key), true, keyEvent->isAutoRepeat(), keyEvent->text().toStdU32String()))
{
Key(static_cast<u32>(key), true, keyEvent->text().toStdU32String());
keyEvent->ignore();
}
}
@ -115,7 +123,7 @@ void basic_keyboard_handler::keyReleaseEvent(QKeyEvent* keyEvent)
return;
}
if (m_keyboards.empty() || (keyEvent->isAutoRepeat() && !m_keyboards[0].m_key_repeat))
if (m_consumers.empty())
{
keyEvent->ignore();
return;
@ -123,9 +131,9 @@ void basic_keyboard_handler::keyReleaseEvent(QKeyEvent* keyEvent)
const int key = getUnmodifiedKey(keyEvent);
if (key >= 0)
if (key < 0 || !HandleKey(static_cast<u32>(key), false, keyEvent->isAutoRepeat(), keyEvent->text().toStdU32String()))
{
Key(static_cast<u32>(key), false, keyEvent->text().toStdU32String());
keyEvent->ignore();
}
}
@ -166,15 +174,8 @@ s32 basic_keyboard_handler::getUnmodifiedKey(QKeyEvent* keyEvent)
return static_cast<s32>(raw_key);
}
void basic_keyboard_handler::LoadSettings()
void basic_keyboard_handler::LoadSettings(Keyboard& keyboard)
{
if (m_keyboards.empty())
{
return;
}
Keyboard& keyboard = m_keyboards[0];
std::vector<KbButton> buttons;
// Meta Keys
@ -194,7 +195,7 @@ void basic_keyboard_handler::LoadSettings()
//buttons.emplace_back(, CELL_KEYC_E_UNDEF);
buttons.emplace_back(Qt::Key_Escape, CELL_KEYC_ESCAPE);
buttons.emplace_back(Qt::Key_Kanji, CELL_KEYC_106_KANJI);
//buttons.emplace_back(Qt::Key_CapsLock, CELL_KEYC_CAPS_LOCK);
buttons.emplace_back(Qt::Key_CapsLock, CELL_KEYC_CAPS_LOCK);
buttons.emplace_back(Qt::Key_F1, CELL_KEYC_F1);
buttons.emplace_back(Qt::Key_F2, CELL_KEYC_F2);
buttons.emplace_back(Qt::Key_F3, CELL_KEYC_F3);
@ -221,7 +222,7 @@ void basic_keyboard_handler::LoadSettings()
buttons.emplace_back(Qt::Key_Down, CELL_KEYC_DOWN_ARROW);
buttons.emplace_back(Qt::Key_Up, CELL_KEYC_UP_ARROW);
//buttons.emplace_back(WXK_NUMLOCK, CELL_KEYC_NUM_LOCK);
//buttons.emplace_back(, CELL_KEYC_APPLICATION);
buttons.emplace_back(Qt::Key_Meta, CELL_KEYC_APPLICATION);
buttons.emplace_back(Qt::Key_Kana_Shift, CELL_KEYC_KANA); // maybe Key_Kana_Lock
buttons.emplace_back(Qt::Key_Henkan, CELL_KEYC_HENKAN);
buttons.emplace_back(Qt::Key_Muhenkan, CELL_KEYC_MUHENKAN);

View file

@ -11,14 +11,16 @@ class basic_keyboard_handler final : public KeyboardHandlerBase, public QObject
using KeyboardHandlerBase::KeyboardHandlerBase;
public:
void Init(const u32 max_connect) override;
void Init(keyboard_consumer& consumer, const u32 max_connect) override;
void SetTargetWindow(QWindow* target);
bool eventFilter(QObject* watched, QEvent* event) override;
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
static s32 getUnmodifiedKey(QKeyEvent* event);
void LoadSettings();
private:
void LoadSettings(Keyboard& keyboard);
QWindow* m_target = nullptr;
};