mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
input: use keyboard consumers to seperate cell and overlay logic
This commit is contained in:
parent
6fc7fa3b13
commit
fcba193a3c
3
.gitignore
vendored
3
.gitignore
vendored
@ -130,6 +130,9 @@ yaml-cpp.pc
|
||||
# miniupnp
|
||||
/3rdparty/miniupnp/x64/*
|
||||
|
||||
# opencv
|
||||
/3rdparty/opencv/*
|
||||
|
||||
# llvm
|
||||
/3rdparty/llvm/llvm_build
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
LoadSettings(kb);
|
||||
|
||||
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)
|
||||
keyboards.emplace_back(kb);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user