1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 12:12:50 +01:00

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 # miniupnp
/3rdparty/miniupnp/x64/* /3rdparty/miniupnp/x64/*
# opencv
/3rdparty/opencv/*
# llvm # llvm
/3rdparty/llvm/llvm_build /3rdparty/llvm/llvm_build

View File

@ -42,13 +42,16 @@ KeyboardHandlerBase::KeyboardHandlerBase(utils::serial* ar)
return; 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(); auto lk = init.init();
}); });
} }
@ -56,9 +59,20 @@ KeyboardHandlerBase::KeyboardHandlerBase(utils::serial* ar)
void KeyboardHandlerBase::save(utils::serial& ar) void KeyboardHandlerBase::save(utils::serial& ar)
{ {
u32 max_connect = 0;
const auto inited = init.access(); 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) 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); 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; return CELL_OK;
} }
@ -95,6 +111,11 @@ error_code cellKbEnd(ppu_thread& ppu)
if (!init) if (!init)
return CELL_KB_ERROR_UNINITIALIZED; return CELL_KB_ERROR_UNINITIALIZED;
{
std::lock_guard<std::mutex> lock(handler.m_mutex);
handler.RemoveConsumer(keyboard_consumer::identifier::cellKb);
}
// TODO // TODO
sys_config_stop(ppu); sys_config_stop(ppu);
return CELL_OK; return CELL_OK;
@ -116,12 +137,13 @@ error_code cellKbClearBuf(u32 port_no)
std::lock_guard<std::mutex> lock(handler.m_mutex); 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); 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.len = 0;
current_data.led = 0; current_data.led = 0;
current_data.mkey = 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::memset(info.get_ptr(), 0, info.size());
std::lock_guard<std::mutex> lock(handler.m_mutex); 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->max_connect = current_info.max_connect;
info->now_connect = current_info.now_connect; info->now_connect = current_info.now_connect;
info->info = current_info.info; 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; return CELL_KB_ERROR_INVALID_PARAMETER;
std::lock_guard<std::mutex> lock(handler.m_mutex); 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 >= consumer.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
if (port_no >= handler.GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
return not_an_error(CELL_KB_ERROR_NO_DEVICE); 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()) 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; 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. // 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. // 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) if (port_no >= CELL_KB_MAX_KEYBOARDS || type > CELL_KB_CODETYPE_ASCII)
return CELL_KB_ERROR_INVALID_PARAMETER; 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; return CELL_OK;
std::lock_guard<std::mutex> lock(handler.m_mutex); KbConfig& current_config = consumer.GetConfig(port_no);
KbConfig& current_config = handler.GetConfig(port_no);
current_config.code_type = type; current_config.code_type = type;
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED // can also return CELL_KB_ERROR_SYS_SETTING_FAILED
@ -413,12 +437,13 @@ error_code cellKbSetLEDStatus(u32 port_no, u8 led)
if (led > 7) if (led > 7)
return CELL_KB_ERROR_SYS_SETTING_FAILED; 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; return CELL_KB_ERROR_FATAL;
std::lock_guard<std::mutex> lock(handler.m_mutex); KbData& current_data = consumer.GetData(port_no);
KbData& current_data = handler.GetData(port_no);
current_data.led = static_cast<u32>(led); current_data.led = static_cast<u32>(led);
return CELL_OK; 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) if (port_no >= CELL_KB_MAX_KEYBOARDS || rmode > CELL_KB_RMODE_PACKET)
return CELL_KB_ERROR_INVALID_PARAMETER; 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; return CELL_OK;
std::lock_guard<std::mutex> lock(handler.m_mutex); KbConfig& current_config = consumer.GetConfig(port_no);
KbConfig& current_config = handler.GetConfig(port_no);
current_config.read_mode = rmode; current_config.read_mode = rmode;
// Key repeat must be disabled in packet mode. But let's just always enable it otherwise. // 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; keyboard.m_key_repeat = rmode != CELL_KB_RMODE_PACKET;
// can also return CELL_KB_ERROR_SYS_SETTING_FAILED // 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); 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); return not_an_error(CELL_KB_ERROR_NO_DEVICE);
// tests show that config is checked only after the device's status // tests show that config is checked only after the device's status
if (!config) if (!config)
return CELL_KB_ERROR_INVALID_PARAMETER; 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->arrange = current_config.arrange;
config->read_mode = current_config.read_mode; config->read_mode = current_config.read_mode;
config->code_type = current_config.code_type; config->code_type = current_config.code_type;

View File

@ -2,6 +2,8 @@
#include "KeyboardHandler.h" #include "KeyboardHandler.h"
#include "Utilities/StrUtil.h" #include "Utilities/StrUtil.h"
LOG_CHANNEL(input_log, "Input");
template <> template <>
void fmt_class_string<CellKbMappingType>::format(std::string& out, u64 arg) 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); 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) for (Keyboard& keyboard : m_keyboards)
{ {
if (is_auto_repeat && !keyboard.m_key_repeat)
{
continue;
}
consumed = true;
KbData& data = keyboard.m_data; KbData& data = keyboard.m_data;
const KbConfig& config = keyboard.m_config; 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 return code == Key_Control
|| code == Key_Shift || code == Key_Shift
@ -178,6 +255,14 @@ void KeyboardHandlerBase::SetIntercepted(bool intercepted)
{ {
std::lock_guard<std::mutex> lock(m_mutex); 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; m_info.info = intercepted ? CELL_KB_INFO_INTERCEPTED : 0;
if (intercepted) if (intercepted)
@ -196,17 +281,25 @@ void KeyboardHandlerBase::SetIntercepted(bool intercepted)
} }
void KeyboardHandlerBase::ReleaseAllKeys() void KeyboardHandlerBase::ReleaseAllKeys()
{
for (auto& [id, consumer] : m_consumers)
{
consumer.ReleaseAllKeys();
}
}
void keyboard_consumer::ReleaseAllKeys()
{ {
for (Keyboard& keyboard : m_keyboards) for (Keyboard& keyboard : m_keyboards)
{ {
for (const auto& [key_code, button] : keyboard.m_keys) 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) 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(); keyboard.m_extra_data.pressed_keys.clear();

View File

@ -75,21 +75,20 @@ struct Keyboard
std::unordered_map<u32, KbButton> m_keys; std::unordered_map<u32, KbButton> m_keys;
}; };
class KeyboardHandlerBase class keyboard_consumer
{ {
public: 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; bool ConsumeKey(u32 code, bool pressed, bool is_auto_repeat, const std::u32string& key);
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);
void SetIntercepted(bool intercepted); void SetIntercepted(bool intercepted);
static bool IsMetaKey(u32 code); static bool IsMetaKey(u32 code);
@ -99,12 +98,41 @@ public:
KbData& GetData(const u32 keyboard) { return m_keyboards[keyboard].m_data; } KbData& GetData(const u32 keyboard) { return m_keyboards[keyboard].m_data; }
KbExtraData& GetExtraData(const u32 keyboard) { return m_keyboards[keyboard].m_extra_data; } KbExtraData& GetExtraData(const u32 keyboard) { return m_keyboards[keyboard].m_extra_data; }
KbConfig& GetConfig(const u32 keyboard) { return m_keyboards[keyboard].m_config; } 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; stx::init_mutex init;
protected: protected:
void ReleaseAllKeys(); void ReleaseAllKeys();
KbInfo m_info{}; std::unordered_map<keyboard_consumer::identifier, keyboard_consumer> m_consumers;
std::vector<Keyboard> m_keyboards;
}; };

View File

@ -7,15 +7,18 @@ class NullKeyboardHandler final : public KeyboardHandlerBase
using KeyboardHandlerBase::KeyboardHandlerBase; using KeyboardHandlerBase::KeyboardHandlerBase;
public: public:
void Init(const u32 max_connect) override void Init(keyboard_consumer& consumer, const u32 max_connect) override
{ {
m_info = {}; KbInfo& info = consumer.GetInfo();
m_info.max_connect = max_connect; std::vector<Keyboard>& keyboards = consumer.GetKeyboards();
m_info.is_null_handler = true;
m_keyboards.clear(); info = {};
info.max_connect = max_connect;
info.is_null_handler = true;
keyboards.clear();
for (u32 i = 0; i < max_connect; i++) 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. // 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) if (m_keyboard_input_enabled && !m_keyboard_pad_handler_active && input::g_keyboards_intercepted)
{ {
auto& handler = g_fxo->get<KeyboardHandlerBase>(); auto& kb_handler = g_fxo->get<KeyboardHandlerBase>();
std::lock_guard<std::mutex> lock(handler.m_mutex); 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); KbData& current_data = kb_consumer.GetData(0);
KbExtraData& extra_data = handler.GetExtraData(0); KbExtraData& extra_data = kb_consumer.GetExtraData(0);
if (current_data.len > 0 || !extra_data.pressed_keys.empty()) if (current_data.len > 0 || !extra_data.pressed_keys.empty())
{ {
@ -185,16 +189,6 @@ namespace rsx
continue; 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 // Get gamepad input
@ -202,14 +196,9 @@ namespace rsx
const auto handler = pad::get_current_handler(); const auto handler = pad::get_current_handler();
const PadInfo& rinfo = handler->GetInfo(); const PadInfo& rinfo = handler->GetInfo();
if (!rinfo.now_connect || !input::g_pads_intercepted) const bool ignore_gamepad_input = (!rinfo.now_connect || !input::g_pads_intercepted);
{
m_keyboard_pad_handler_active = false;
refresh();
continue;
}
bool keyboard_pad_handler_active = false; m_keyboard_pad_handler_active = false;
int pad_index = -1; int pad_index = -1;
for (const auto& pad : handler->GetPads()) for (const auto& pad : handler->GetPads())
@ -244,6 +233,16 @@ namespace rsx
m_keyboard_pad_handler_active = true; 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) for (const Button& button : pad->m_buttons)
{ {
pad_button button_id = pad_button::pad_button_max_enum; 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(); 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. // 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. // Non-interactive user intefaces handle this in close in order to prevent a g_pad_mutex deadlock.
if (m_stop_pad_interception) if (m_stop_pad_interception)

View File

@ -11,26 +11,34 @@
LOG_CHANNEL(input_log, "Input"); 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(); KbInfo& info = consumer.GetInfo();
m_info = {}; std::vector<Keyboard>& keyboards = consumer.GetKeyboards();
info = {};
keyboards.clear();
for (u32 i = 0; i < max_connect; i++) for (u32 i = 0; i < max_connect; i++)
{ {
Keyboard kb{}; Keyboard kb{};
kb.m_config.arrange = g_cfg.sys.keyboard_type; 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(); info.max_connect = max_connect;
info.now_connect = std::min(::size32(keyboards), max_connect);
m_info.max_connect = max_connect; info.info = input::g_keyboards_intercepted ? CELL_KB_INFO_INTERCEPTED : 0; // Ownership of keyboard data: 0=Application, 1=System
m_info.now_connect = std::min(::size32(m_keyboards), max_connect); info.status[0] = CELL_KB_STATUS_CONNECTED; // (TODO: Support for more keyboards)
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)
} }
/* Sets the target window for the event handler, and also installs an event filter on the target. */ /* 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; return;
} }
if (m_keyboards.empty() || (keyEvent->isAutoRepeat() && !m_keyboards[0].m_key_repeat)) if (m_consumers.empty())
{ {
keyEvent->ignore(); keyEvent->ignore();
return; return;
@ -102,9 +110,9 @@ void basic_keyboard_handler::keyPressEvent(QKeyEvent* keyEvent)
const int key = getUnmodifiedKey(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; return;
} }
if (m_keyboards.empty() || (keyEvent->isAutoRepeat() && !m_keyboards[0].m_key_repeat)) if (m_consumers.empty())
{ {
keyEvent->ignore(); keyEvent->ignore();
return; return;
@ -123,9 +131,9 @@ void basic_keyboard_handler::keyReleaseEvent(QKeyEvent* keyEvent)
const int key = getUnmodifiedKey(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); 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; std::vector<KbButton> buttons;
// Meta Keys // Meta Keys
@ -194,7 +195,7 @@ void basic_keyboard_handler::LoadSettings()
//buttons.emplace_back(, CELL_KEYC_E_UNDEF); //buttons.emplace_back(, CELL_KEYC_E_UNDEF);
buttons.emplace_back(Qt::Key_Escape, CELL_KEYC_ESCAPE); buttons.emplace_back(Qt::Key_Escape, CELL_KEYC_ESCAPE);
buttons.emplace_back(Qt::Key_Kanji, CELL_KEYC_106_KANJI); 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_F1, CELL_KEYC_F1);
buttons.emplace_back(Qt::Key_F2, CELL_KEYC_F2); buttons.emplace_back(Qt::Key_F2, CELL_KEYC_F2);
buttons.emplace_back(Qt::Key_F3, CELL_KEYC_F3); 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_Down, CELL_KEYC_DOWN_ARROW);
buttons.emplace_back(Qt::Key_Up, CELL_KEYC_UP_ARROW); buttons.emplace_back(Qt::Key_Up, CELL_KEYC_UP_ARROW);
//buttons.emplace_back(WXK_NUMLOCK, CELL_KEYC_NUM_LOCK); //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_Kana_Shift, CELL_KEYC_KANA); // maybe Key_Kana_Lock
buttons.emplace_back(Qt::Key_Henkan, CELL_KEYC_HENKAN); buttons.emplace_back(Qt::Key_Henkan, CELL_KEYC_HENKAN);
buttons.emplace_back(Qt::Key_Muhenkan, CELL_KEYC_MUHENKAN); 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; using KeyboardHandlerBase::KeyboardHandlerBase;
public: public:
void Init(const u32 max_connect) override; void Init(keyboard_consumer& consumer, const u32 max_connect) override;
void SetTargetWindow(QWindow* target); void SetTargetWindow(QWindow* target);
bool eventFilter(QObject* watched, QEvent* event) override; bool eventFilter(QObject* watched, QEvent* event) override;
void keyPressEvent(QKeyEvent* event); void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event);
static s32 getUnmodifiedKey(QKeyEvent* event); static s32 getUnmodifiedKey(QKeyEvent* event);
void LoadSettings();
private: private:
void LoadSettings(Keyboard& keyboard);
QWindow* m_target = nullptr; QWindow* m_target = nullptr;
}; };