mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
overlays/osk: Implement fallback for unknown keys
Note that those keys won't be passed to the cellOsk event hook callback
This commit is contained in:
parent
c214f45e14
commit
ad340c3007
@ -40,12 +40,14 @@ void fmt_class_string<CellKbMappingType>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
void KeyboardHandlerBase::Key(u32 code, bool pressed)
|
||||
void KeyboardHandlerBase::Key(u32 code, bool pressed, const std::u32string& key)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
for (Keyboard& keyboard : m_keyboards)
|
||||
{
|
||||
bool found_key = false;
|
||||
|
||||
KbData& data = keyboard.m_data;
|
||||
KbConfig& config = keyboard.m_config;
|
||||
|
||||
@ -54,6 +56,8 @@ void KeyboardHandlerBase::Key(u32 code, bool pressed)
|
||||
if (button.m_keyCode != code)
|
||||
continue;
|
||||
|
||||
found_key = true;
|
||||
|
||||
u16 kcode = CELL_KEYC_NO_EVENT;
|
||||
bool is_meta_key = IsMetaKey(code);
|
||||
|
||||
@ -152,6 +156,18 @@ void KeyboardHandlerBase::Key(u32 code, bool pressed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_key && !key.empty())
|
||||
{
|
||||
if (pressed)
|
||||
{
|
||||
keyboard.m_extra_data.pressed_keys.insert(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard.m_extra_data.pressed_keys.erase(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,11 +203,18 @@ void KeyboardHandlerBase::SetIntercepted(bool intercepted)
|
||||
|
||||
void KeyboardHandlerBase::ReleaseAllKeys()
|
||||
{
|
||||
for (const Keyboard& keyboard : m_keyboards)
|
||||
for (Keyboard& keyboard : m_keyboards)
|
||||
{
|
||||
for (const KbButton& button : keyboard.m_buttons)
|
||||
{
|
||||
Key(button.m_keyCode, false);
|
||||
Key(button.m_keyCode, false, {});
|
||||
}
|
||||
|
||||
for (const std::u32string& key : keyboard.m_extra_data.pressed_keys)
|
||||
{
|
||||
Key(0, false, key);
|
||||
}
|
||||
|
||||
keyboard.m_extra_data.pressed_keys.clear();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "util/init_mutex.hpp"
|
||||
|
||||
@ -52,6 +53,11 @@ struct KbData
|
||||
std::array<KbButton, CELL_KB_MAX_KEYCODES> buttons{};
|
||||
};
|
||||
|
||||
struct KbExtraData
|
||||
{
|
||||
std::set<std::u32string> pressed_keys{};
|
||||
};
|
||||
|
||||
struct KbConfig
|
||||
{
|
||||
u32 arrange = CELL_KB_MAPPING_101;
|
||||
@ -63,6 +69,7 @@ struct Keyboard
|
||||
{
|
||||
bool m_key_repeat = false;
|
||||
KbData m_data{};
|
||||
KbExtraData m_extra_data{};
|
||||
KbConfig m_config{};
|
||||
std::vector<KbButton> m_buttons;
|
||||
};
|
||||
@ -81,7 +88,7 @@ public:
|
||||
|
||||
SAVESTATE_INIT_POS(19);
|
||||
|
||||
void Key(u32 code, bool pressed);
|
||||
void Key(u32 code, bool pressed, const std::u32string& key);
|
||||
void SetIntercepted(bool intercepted);
|
||||
|
||||
static bool IsMetaKey(u32 code);
|
||||
@ -90,6 +97,7 @@ public:
|
||||
std::vector<Keyboard>& GetKeyboards() { return m_keyboards; }
|
||||
std::vector<KbButton>& GetButtons(const u32 keyboard) { return m_keyboards[keyboard].m_buttons; }
|
||||
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; }
|
||||
|
||||
stx::init_mutex init;
|
||||
|
@ -586,98 +586,107 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
void osk_dialog::on_key_pressed(u32 led, u32 mkey, u32 key_code, u32 out_key_code, bool pressed)
|
||||
void osk_dialog::on_key_pressed(u32 led, u32 mkey, u32 key_code, u32 out_key_code, bool pressed, std::u32string key)
|
||||
{
|
||||
if (!pressed || !keyboard_input_enabled || ignore_input_events)
|
||||
return;
|
||||
|
||||
osk.notice("osk_dialog::on_key_pressed(led=%d, mkey=%d, key_code=%d, out_key_code=%d, pressed=%d)", led, mkey, key_code, out_key_code, pressed);
|
||||
const bool use_key_string_fallback = !key.empty();
|
||||
|
||||
// Get keyboard layout
|
||||
u32 kb_mapping = CELL_KB_MAPPING_101;
|
||||
u32 osk_panel_mode = CELL_OSKDIALOG_PANELMODE_DEFAULT;
|
||||
for (usz i = 0; i < m_panels.size(); ++i)
|
||||
osk.notice("osk_dialog::on_key_pressed(led=%d, mkey=%d, key_code=%d, out_key_code=%d, pressed=%d, use_key_string_fallback=%d)", led, mkey, key_code, out_key_code, pressed, use_key_string_fallback);
|
||||
|
||||
if (!use_key_string_fallback)
|
||||
{
|
||||
if (m_panel_index == i)
|
||||
// Get keyboard layout
|
||||
u32 kb_mapping = CELL_KB_MAPPING_101;
|
||||
u32 osk_panel_mode = CELL_OSKDIALOG_PANELMODE_DEFAULT;
|
||||
for (usz i = 0; i < m_panels.size(); ++i)
|
||||
{
|
||||
osk_panel_mode = m_panels[i].osk_panel_mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (osk_panel_mode)
|
||||
{
|
||||
case CELL_OSKDIALOG_PANELMODE_DEFAULT : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_GERMAN : kb_mapping = CELL_KB_MAPPING_GERMAN_GERMANY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ENGLISH : kb_mapping = CELL_KB_MAPPING_ENGLISH_UK; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_SPANISH : kb_mapping = CELL_KB_MAPPING_SPANISH_SPAIN; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_FRENCH : kb_mapping = CELL_KB_MAPPING_FRENCH_FRANCE; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ITALIAN : kb_mapping = CELL_KB_MAPPING_ITALIAN_ITALY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_DUTCH : kb_mapping = CELL_KB_MAPPING_DUTCH_NETHERLANDS; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_PORTUGUESE : kb_mapping = CELL_KB_MAPPING_PORTUGUESE_PORTUGAL; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_RUSSIAN : kb_mapping = CELL_KB_MAPPING_RUSSIAN_RUSSIA; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_JAPANESE : kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_DEFAULT_NO_JAPANESE: kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_POLISH : kb_mapping = CELL_KB_MAPPING_POLISH_POLAND; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_KOREAN : kb_mapping = CELL_KB_MAPPING_KOREAN_KOREA; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_TURKEY : kb_mapping = CELL_KB_MAPPING_TURKISH_TURKEY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_TRADITIONAL_CHINESE: kb_mapping = CELL_KB_MAPPING_CHINESE_TRADITIONAL; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_SIMPLIFIED_CHINESE : kb_mapping = CELL_KB_MAPPING_CHINESE_SIMPLIFIED; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_PORTUGUESE_BRAZIL : kb_mapping = CELL_KB_MAPPING_PORTUGUESE_BRAZIL; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_DANISH : kb_mapping = CELL_KB_MAPPING_DANISH_DENMARK; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_SWEDISH : kb_mapping = CELL_KB_MAPPING_SWEDISH_SWEDEN; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_NORWEGIAN : kb_mapping = CELL_KB_MAPPING_NORWEGIAN_NORWAY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_FINNISH : kb_mapping = CELL_KB_MAPPING_FINNISH_FINLAND; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_JAPANESE_HIRAGANA : kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_JAPANESE_KATAKANA : kb_mapping = CELL_KB_MAPPING_106_KANA; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ALPHABET_FULL_WIDTH: kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ALPHABET : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_LATIN : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_NUMERAL_FULL_WIDTH : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_NUMERAL : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_URL : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_PASSWORD : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
default : kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
}
|
||||
|
||||
// Convert key to its u32string presentation
|
||||
const u16 converted_out_key = cellKbCnvRawCode(kb_mapping, mkey, led, out_key_code);
|
||||
std::u16string utf16_string;
|
||||
utf16_string.push_back(converted_out_key);
|
||||
const std::u32string u32_string = utf16_to_u32string(utf16_string);
|
||||
const std::string out_key_string = utf16_to_ascii8(utf16_string);
|
||||
|
||||
// Find matching key in the OSK
|
||||
bool found_key = false;
|
||||
for (const cell& current_cell : m_grid)
|
||||
{
|
||||
// TODO: maybe just ignore the current charset and check all outputs
|
||||
if (m_selected_charset < current_cell.outputs.size())
|
||||
{
|
||||
for (const auto& str : current_cell.outputs[m_selected_charset])
|
||||
{
|
||||
if (str == u32_string)
|
||||
{
|
||||
// Apply key press
|
||||
if (current_cell.callback)
|
||||
{
|
||||
current_cell.callback(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
on_default_callback(str);
|
||||
}
|
||||
|
||||
found_key = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_key)
|
||||
if (m_panel_index == i)
|
||||
{
|
||||
osk_panel_mode = m_panels[i].osk_panel_mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (osk_panel_mode)
|
||||
{
|
||||
case CELL_OSKDIALOG_PANELMODE_DEFAULT: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_GERMAN: kb_mapping = CELL_KB_MAPPING_GERMAN_GERMANY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ENGLISH: kb_mapping = CELL_KB_MAPPING_ENGLISH_UK; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_SPANISH: kb_mapping = CELL_KB_MAPPING_SPANISH_SPAIN; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_FRENCH: kb_mapping = CELL_KB_MAPPING_FRENCH_FRANCE; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ITALIAN: kb_mapping = CELL_KB_MAPPING_ITALIAN_ITALY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_DUTCH: kb_mapping = CELL_KB_MAPPING_DUTCH_NETHERLANDS; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_PORTUGUESE: kb_mapping = CELL_KB_MAPPING_PORTUGUESE_PORTUGAL; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_RUSSIAN: kb_mapping = CELL_KB_MAPPING_RUSSIAN_RUSSIA; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_JAPANESE: kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_DEFAULT_NO_JAPANESE: kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_POLISH: kb_mapping = CELL_KB_MAPPING_POLISH_POLAND; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_KOREAN: kb_mapping = CELL_KB_MAPPING_KOREAN_KOREA; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_TURKEY: kb_mapping = CELL_KB_MAPPING_TURKISH_TURKEY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_TRADITIONAL_CHINESE: kb_mapping = CELL_KB_MAPPING_CHINESE_TRADITIONAL; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_SIMPLIFIED_CHINESE: kb_mapping = CELL_KB_MAPPING_CHINESE_SIMPLIFIED; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_PORTUGUESE_BRAZIL: kb_mapping = CELL_KB_MAPPING_PORTUGUESE_BRAZIL; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_DANISH: kb_mapping = CELL_KB_MAPPING_DANISH_DENMARK; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_SWEDISH: kb_mapping = CELL_KB_MAPPING_SWEDISH_SWEDEN; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_NORWEGIAN: kb_mapping = CELL_KB_MAPPING_NORWEGIAN_NORWAY; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_FINNISH: kb_mapping = CELL_KB_MAPPING_FINNISH_FINLAND; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_JAPANESE_HIRAGANA: kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_JAPANESE_KATAKANA: kb_mapping = CELL_KB_MAPPING_106_KANA; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ALPHABET_FULL_WIDTH: kb_mapping = CELL_KB_MAPPING_106; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_ALPHABET: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_LATIN: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_NUMERAL_FULL_WIDTH: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_NUMERAL: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_URL: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
case CELL_OSKDIALOG_PANELMODE_PASSWORD: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
default: kb_mapping = CELL_KB_MAPPING_101; break;
|
||||
}
|
||||
|
||||
// Convert key to its u32string presentation
|
||||
const u16 converted_out_key = cellKbCnvRawCode(kb_mapping, mkey, led, out_key_code);
|
||||
std::u16string utf16_string;
|
||||
utf16_string.push_back(converted_out_key);
|
||||
key = utf16_to_u32string(utf16_string);
|
||||
}
|
||||
|
||||
// Find matching key in the OSK
|
||||
const auto find_key = [&]() -> bool
|
||||
{
|
||||
for (const cell& current_cell : m_grid)
|
||||
{
|
||||
for (const auto& output : current_cell.outputs)
|
||||
{
|
||||
for (const auto& str : output)
|
||||
{
|
||||
if (str == key)
|
||||
{
|
||||
// Apply key press
|
||||
if (current_cell.callback)
|
||||
{
|
||||
current_cell.callback(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
on_default_callback(str);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const bool found_key = find_key();
|
||||
|
||||
if (use_key_string_fallback)
|
||||
{
|
||||
// We don't have a keycode, so there we can't process any of the following code anyway
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle special input
|
||||
@ -686,10 +695,10 @@ namespace rsx
|
||||
switch (out_key_code)
|
||||
{
|
||||
case CELL_KEYC_SPACE:
|
||||
on_space(u32_string);
|
||||
on_space(key);
|
||||
break;
|
||||
case CELL_KEYC_BS:
|
||||
on_backspace(u32_string);
|
||||
on_backspace(key);
|
||||
break;
|
||||
case CELL_KEYC_ESCAPE:
|
||||
Close(CELL_OSKDIALOG_CLOSE_CANCEL);
|
||||
@ -701,7 +710,7 @@ namespace rsx
|
||||
}
|
||||
else
|
||||
{
|
||||
on_enter(u32_string);
|
||||
on_enter(key);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -96,7 +96,7 @@ namespace rsx
|
||||
void update_selection_by_index(u32 index);
|
||||
|
||||
void on_button_pressed(pad_button button_press) override;
|
||||
void on_key_pressed(u32 led, u32 mkey, u32 key_code, u32 out_key_code, bool pressed) override;
|
||||
void on_key_pressed(u32 led, u32 mkey, u32 key_code, u32 out_key_code, bool pressed, std::u32string key) override;
|
||||
void on_text_changed();
|
||||
|
||||
void on_default_callback(const std::u32string& str);
|
||||
|
@ -151,17 +151,24 @@ namespace rsx
|
||||
if (!handler.GetKeyboards().empty() && handler.GetInfo().status[0] == CELL_KB_STATUS_CONNECTED)
|
||||
{
|
||||
KbData& current_data = handler.GetData(0);
|
||||
KbExtraData& extra_data = handler.GetExtraData(0);
|
||||
|
||||
if (current_data.len > 0)
|
||||
if (current_data.len > 0 || !extra_data.pressed_keys.empty())
|
||||
{
|
||||
for (s32 i = 0; i < current_data.len; i++)
|
||||
{
|
||||
const KbButton& key = current_data.buttons[i];
|
||||
on_key_pressed(current_data.led, current_data.mkey, key.m_keyCode, key.m_outKeyCode, key.m_pressed);
|
||||
on_key_pressed(current_data.led, current_data.mkey, key.m_keyCode, key.m_outKeyCode, key.m_pressed, {});
|
||||
}
|
||||
|
||||
for (const std::u32string& key : extra_data.pressed_keys)
|
||||
{
|
||||
on_key_pressed(0, 0, 0, 0, true, key);
|
||||
}
|
||||
|
||||
// Flush buffer unconditionally. Otherwise we get a flood of key events.
|
||||
current_data.len = 0;
|
||||
extra_data.pressed_keys.clear();
|
||||
|
||||
// Ignore gamepad input if a key was recognized
|
||||
refresh();
|
||||
|
@ -124,7 +124,7 @@ namespace rsx
|
||||
compiled_resource get_compiled() override = 0;
|
||||
|
||||
virtual void on_button_pressed(pad_button /*button_press*/) {}
|
||||
virtual void on_key_pressed(u32 /*led*/, u32 /*mkey*/, u32 /*key_code*/, u32 /*out_key_code*/, bool /*pressed*/) {}
|
||||
virtual void on_key_pressed(u32 /*led*/, u32 /*mkey*/, u32 /*key_code*/, u32 /*out_key_code*/, bool /*pressed*/, std::u32string /*key*/) {}
|
||||
|
||||
virtual void close(bool use_callback, bool stop_pad_interception);
|
||||
|
||||
|
@ -104,7 +104,7 @@ void basic_keyboard_handler::keyPressEvent(QKeyEvent* keyEvent)
|
||||
|
||||
if (key >= 0)
|
||||
{
|
||||
Key(static_cast<u32>(key), true);
|
||||
Key(static_cast<u32>(key), true, keyEvent->text().toStdU32String());
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ void basic_keyboard_handler::keyReleaseEvent(QKeyEvent* keyEvent)
|
||||
|
||||
if (key >= 0)
|
||||
{
|
||||
Key(static_cast<u32>(key), false);
|
||||
Key(static_cast<u32>(key), false, keyEvent->text().toStdU32String());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user