cellKb/Qt: Improve basic keyboard

Sadly the shift in Qt is a bit counter productive.
You'll have to hack another key as shift until i figured it out
This commit is contained in:
Megamouse 2018-07-17 01:23:14 +02:00
parent d24f9194f7
commit ed7012c9db
4 changed files with 298 additions and 114 deletions

View File

@ -71,6 +71,8 @@ error_code cellKbClearBuf(u32 port_no)
if (port_no >= CELL_KB_MAX_KEYBOARDS)
return CELL_KB_ERROR_INVALID_PARAMETER;
std::lock_guard<std::mutex> lock(handler->m_mutex);
const KbInfo& current_info = handler->GetInfo();
if (port_no >= handler->GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
@ -83,7 +85,7 @@ error_code cellKbClearBuf(u32 port_no)
for (int i = 0; i < CELL_KB_MAX_KEYCODES; i++)
{
current_data.keycode[i] = 0;
current_data.keycode[i] = { 0, 0 };
}
return CELL_OK;
@ -110,27 +112,102 @@ u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode)
if (rawcode == 0x58) return 0x0A | 0x4000; // '\n'
// ASCII
const bool is_shift = mkey & (CELL_KB_MKEY_L_SHIFT | CELL_KB_MKEY_R_SHIFT);
const bool is_caps_lock = led & (CELL_KB_LED_CAPS_LOCK);
auto get_ascii = [is_shift, is_caps_lock](u16 lower, u16 upper)
{
return is_shift || is_caps_lock ? upper : lower;
};
if (arrange == CELL_KB_MAPPING_106) // (Japanese)
{
if (rawcode == 0x1E) return get_ascii(rawcode + 0x13, 0x21); // '1' or '!'
if (rawcode == 0x1F) return get_ascii(rawcode + 0x13, 0x22); // '2' or '"'
if (rawcode == 0x20) return get_ascii(rawcode + 0x13, 0x23); // '3' or '#'
if (rawcode == 0x21) return get_ascii(rawcode + 0x13, 0x24); // '4' or '$'
if (rawcode == 0x22) return get_ascii(rawcode + 0x13, 0x25); // '5' or '%'
if (rawcode == 0x23) return get_ascii(rawcode + 0x13, 0x26); // '6' or '&'
if (rawcode == 0x24) return get_ascii(rawcode + 0x13, 0x27); // '7' or '''
if (rawcode == 0x25) return get_ascii(rawcode + 0x13, 0x28); // '8' or '('
if (rawcode == 0x26) return get_ascii(rawcode + 0x13, 0x29); // '9' or ')'
if (rawcode == 0x27) return get_ascii(0x303, 0x7E); // '0' or '~'
if (rawcode == 0x2E) return get_ascii(0x5E, 0x7E); // '^' or '~'
if (rawcode == 0x2F) return get_ascii(0x40, 0x60); // '@' or '`'
if (rawcode == 0x30) return get_ascii(0x5B, 0x7B); // '[' or '{'
if (rawcode == 0x32) return get_ascii(0x5D, 0x7D); // ']' or '}'
if (rawcode == 0x33) return get_ascii(0x3B, 0x2B); // ';' or '+'
if (rawcode == 0x34) return get_ascii(0x3A, 0x2A); // ':' or '*'
if (rawcode == 0x87) return get_ascii(rawcode, 0x5F); // '\' or '_'
if (rawcode == 0x36) return get_ascii(0x2C, 0x3C); // ',' or '<'
if (rawcode == 0x37) return get_ascii(0x2E, 0x3E); // '.' or '>'
if (rawcode == 0x38) return get_ascii(0x2F, 0x3F); // '/' or '?'
if (rawcode == 0x89) return get_ascii(0xBE, 0x7C); // '&yen;' or '|'
}
else if (arrange == CELL_KB_MAPPING_101) // (US)
{
if (rawcode == 0x1E) return get_ascii(rawcode + 0x13, 0x21); // '1' or '!'
if (rawcode == 0x1F) return get_ascii(rawcode + 0x13, 0x40); // '2' or '@'
if (rawcode == 0x20) return get_ascii(rawcode + 0x13, 0x23); // '3' or '#'
if (rawcode == 0x21) return get_ascii(rawcode + 0x13, 0x24); // '4' or '$'
if (rawcode == 0x22) return get_ascii(rawcode + 0x13, 0x25); // '5' or '%'
if (rawcode == 0x23) return get_ascii(rawcode + 0x13, 0x5E); // '6' or '^'
if (rawcode == 0x24) return get_ascii(rawcode + 0x13, 0x26); // '7' or '&'
if (rawcode == 0x25) return get_ascii(rawcode + 0x13, 0x2A); // '8' or '*'
if (rawcode == 0x26) return get_ascii(rawcode + 0x13, 0x28); // '9' or '('
if (rawcode == 0x27) return get_ascii(0x303, 0x29); // '0' or ')'
if (rawcode == 0x2D) return get_ascii(0x2D, 0x5F); // '-' or '_'
if (rawcode == 0x2E) return get_ascii(0x3D, 0x2B); // '=' or '+'
if (rawcode == 0x2F) return get_ascii(0x5B, 0x7B); // '[' or '{'
if (rawcode == 0x30) return get_ascii(0x5D, 0x7D); // ']' or '}'
if (rawcode == 0x31) return get_ascii(0x5C, 0x7C); // '\' or '|'
if (rawcode == 0x33) return get_ascii(0x3B, 0x3A); // ';' or ':'
if (rawcode == 0x34) return get_ascii(0x27, 0x22); // ''' or '"'
if (rawcode == 0x36) return get_ascii(0x2C, 0x3C); // ',' or '<'
if (rawcode == 0x37) return get_ascii(0x2E, 0x3E); // '.' or '>'
if (rawcode == 0x38) return get_ascii(0x2F, 0x3F); // '/' or '?'
}
else if (arrange == CELL_KB_MAPPING_GERMAN_GERMANY)
{
if (rawcode == 0x1E) return get_ascii(rawcode + 0x13, 0x21); // '1' or '!'
if (rawcode == 0x1F) return get_ascii(rawcode + 0x13, 0x22); // '2' or '"'
if (rawcode == 0x20) return rawcode + 0x13; // '3' (or '<27>')
if (rawcode == 0x21) return get_ascii(rawcode + 0x13, 0x24); // '4' or '$'
if (rawcode == 0x22) return get_ascii(rawcode + 0x13, 0x25); // '5' or '%'
if (rawcode == 0x23) return get_ascii(rawcode + 0x13, 0x26); // '6' or '&'
if (rawcode == 0x24) return get_ascii(rawcode + 0x13, 0x2F); // '7' or '/'
if (rawcode == 0x25) return get_ascii(rawcode + 0x13, 0x28); // '8' or '('
if (rawcode == 0x26) return get_ascii(rawcode + 0x13, 0x29); // '9' or ')'
if (rawcode == 0x27) return get_ascii(0x303, 0x3D); // '0' or '='
if (rawcode == 0x2D) return get_ascii(0x2D, 0x5F); // '-' or '_'
if (rawcode == 0x2E) return 0x5E; // '^' (or '<27>')
if (rawcode == 0x36) return get_ascii(0x2C, 0x3B); // ',' or ';'
if (rawcode == 0x37) return get_ascii(0x2E, 0x3A); // '.' or ':'
// TODO: <>#'+*~[]{}\|
}
if (rawcode >= 0x04 && rawcode <= 0x1D) // 'A' - 'Z'
{
rawcode -=
(mkey&(CELL_KB_MKEY_L_SHIFT|CELL_KB_MKEY_R_SHIFT)) ?
((led&(CELL_KB_LED_CAPS_LOCK)) ? 0 : 0x20) :
((led&(CELL_KB_LED_CAPS_LOCK)) ? 0x20 : 0);
(is_shift)
? ((led & (CELL_KB_LED_CAPS_LOCK)) ? 0 : 0x20)
: ((led & (CELL_KB_LED_CAPS_LOCK)) ? 0x20 : 0);
return rawcode + 0x5D;
}
if (rawcode >= 0x1E && rawcode <= 0x26) return rawcode + 0x13; // '1' - '9'
if (rawcode == 0x27) return 0x30; // '0'
if (rawcode == 0x28) return 0x0A; // '\n'
if (rawcode == 0x29) return 0x1B; // 'ESC'
if (rawcode == 0x2A) return 0x08; // '\b'
if (rawcode == 0x2B) return 0x09; // '\t'
if (rawcode == 0x2C) return 0x20; // ' '
if (rawcode == 0x2D) return 0x2D; // '-'
if (rawcode == 0x2E) return 0x3D; // '='
if (rawcode == 0x36) return 0x2C; // ','
if (rawcode == 0x37) return 0x2E; // '.'
if (rawcode == 0x38) return 0x2F; // '/'
if (rawcode == 0x87) return 0x5C; // '\'
if (rawcode == 0x2C) return 0x20; // 'space'
// (TODO: Add more cases)
// TODO: Add more cases (e.g. what about '`' and '~' on english layouts) and layouts (e.g. german)
return 0x0000;
}
@ -147,6 +224,8 @@ error_code cellKbGetInfo(vm::ptr<CellKbInfo> info)
if (!info)
return CELL_KB_ERROR_INVALID_PARAMETER;
std::lock_guard<std::mutex> lock(handler->m_mutex);
const KbInfo& current_info = handler->GetInfo();
info->max_connect = current_info.max_connect;
info->now_connect = current_info.now_connect;
@ -172,6 +251,8 @@ error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
if (port_no >= CELL_KB_MAX_KEYBOARDS || !data)
return CELL_KB_ERROR_INVALID_PARAMETER;
std::lock_guard<std::mutex> lock(handler->m_mutex);
const KbInfo& current_info = handler->GetInfo();
if (port_no >= handler->GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)
@ -184,11 +265,9 @@ error_code cellKbRead(u32 port_no, vm::ptr<CellKbData> data)
for (s32 i = 0; i < current_data.len; i++)
{
data->keycode[i] = current_data.keycode[i];
data->keycode[i] = current_data.keycode[i].first;
}
current_data.len = 0;
return CELL_OK;
}
@ -207,6 +286,8 @@ error_code cellKbSetCodeType(u32 port_no, u32 type)
if (port_no >= handler->GetKeyboards().size())
return CELL_OK;
std::lock_guard<std::mutex> lock(handler->m_mutex);
KbConfig& current_config = handler->GetConfig(port_no);
current_config.code_type = type;
@ -233,6 +314,8 @@ error_code cellKbSetLEDStatus(u32 port_no, u8 led)
if (port_no >= handler->GetKeyboards().size() || handler->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);
current_data.led = static_cast<u32>(led);
@ -254,6 +337,8 @@ error_code cellKbSetReadMode(u32 port_no, u32 rmode)
if (port_no >= handler->GetKeyboards().size())
return CELL_OK;
std::lock_guard<std::mutex> lock(handler->m_mutex);
KbConfig& current_config = handler->GetConfig(port_no);
current_config.read_mode = rmode;
@ -274,6 +359,8 @@ error_code cellKbGetConfiguration(u32 port_no, vm::ptr<CellKbConfig> config)
if (port_no >= CELL_KB_MAX_KEYBOARDS)
return CELL_KB_ERROR_INVALID_PARAMETER;
std::lock_guard<std::mutex> lock(handler->m_mutex);
const KbInfo& current_info = handler->GetInfo();
if (port_no >= handler->GetKeyboards().size() || current_info.status[port_no] != CELL_KB_STATUS_CONNECTED)

View File

@ -1,5 +1,7 @@
#pragma once
#include <mutex>
// TODO: HLE info (constants, structs, etc.) should not be available here
extern u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode); // (TODO: Can it be problematic to place SysCalls in middle of nowhere?)
@ -192,6 +194,19 @@ enum CellKbMappingType
CELL_KB_MAPPING_TURKISH_TURKEY
};
enum QtKeys
{
Key_Shift = 0x01000020,
Key_Control = 0x01000021,
Key_Meta = 0x01000022,
Key_Alt = 0x01000023,
Key_CapsLock = 0x01000024,
Key_NumLock = 0x01000025,
Key_ScrollLock = 0x01000026,
Key_Super_L = 0x01000053,
Key_Super_R = 0x01000054
};
static const u32 KB_MAX_KEYBOARDS = 127;
static const u32 KB_MAX_KEYCODES = 62;
@ -208,7 +223,7 @@ struct KbData
u32 led;
u32 mkey;
s32 len;
u16 keycode[KB_MAX_KEYCODES];
std::pair<u16, u32> keycode[KB_MAX_KEYCODES];
KbData()
: led(0)
@ -225,7 +240,7 @@ struct KbConfig
u32 code_type;
KbConfig()
: arrange(CELL_KB_MAPPING_106)
: arrange(CELL_KB_MAPPING_101)
, read_mode(CELL_KB_RMODE_INPUTCHAR)
, code_type(CELL_KB_CODETYPE_ASCII)
{
@ -268,66 +283,138 @@ protected:
std::vector<Keyboard> m_keyboards;
public:
std::mutex m_mutex;
virtual void Init(const u32 max_connect) = 0;
virtual ~KeyboardHandlerBase() = default;
void Key(const u32 code, bool pressed)
void Key(u32 code, bool pressed)
{
for(Keyboard& keyboard : m_keyboards)
// TODO: Key Repeat
std::lock_guard<std::mutex> lock(m_mutex);
for (Keyboard& keyboard : m_keyboards)
{
KbData& data = keyboard.m_data;
KbConfig& config = keyboard.m_config;
// TODO: handle read modes
for(KbButton& button : keyboard.m_buttons)
for (const KbButton& button : keyboard.m_buttons)
{
if(button.m_keyCode != code)
if (button.m_keyCode != code)
continue;
u16 kcode = CELL_KEYC_NO_EVENT;
bool is_meta_key = IsMetaKey(code);
if (!is_meta_key)
{
if (config.code_type == CELL_KB_CODETYPE_RAW)
{
kcode = button.m_outKeyCode;
}
else // config.code_type == CELL_KB_CODETYPE_ASCII
{
kcode = cellKbCnvRawCode(config.arrange, data.mkey, data.led, button.m_outKeyCode);
}
}
if (pressed)
{
if (data.len == 1 && data.keycode[0].first == CELL_KEYC_NO_EVENT)
{
data.len = 0;
}
// Meta Keys
if (code == 308 || code == 307 || code == 306 || code == 393 || code == 396 || code == 394)
if (is_meta_key)
{
data.mkey |= button.m_outKeyCode;
if (config.read_mode == CELL_KB_RMODE_INPUTCHAR)
{
data.keycode[0] = {CELL_KEYC_NO_EVENT, button.m_outKeyCode};
}
else
{
data.keycode[data.len % KB_MAX_KEYCODES] = { CELL_KEYC_NO_EVENT, button.m_outKeyCode };
}
}
else
{
// Led Keys
if (code == 364) data.led ^= CELL_KB_LED_NUM_LOCK;
if (code == 311) data.led ^= CELL_KB_LED_CAPS_LOCK;
if (code == 365) data.led ^= CELL_KB_LED_SCROLL_LOCK;
if (code == Key_CapsLock) data.led ^= CELL_KB_LED_CAPS_LOCK;
if (code == Key_NumLock) data.led ^= CELL_KB_LED_NUM_LOCK;
if (code == Key_ScrollLock) data.led ^= CELL_KB_LED_SCROLL_LOCK;
// if (code == Key_Kana_Lock) data.led ^= CELL_KB_LED_KANA;
// if (code == ???) data.led ^= CELL_KB_LED_COMPOSE;
u16 kcode;
if (config.code_type == CELL_KB_CODETYPE_RAW)
if (config.read_mode == CELL_KB_RMODE_INPUTCHAR)
{
kcode = button.m_outKeyCode;
data.keycode[0] = { kcode, 0 };
}
else //config.code_type == CELL_KB_CODETYPE_ASCII
else
{
kcode = cellKbCnvRawCode(config.arrange, data.mkey, data.led, button.m_outKeyCode);
data.keycode[data.len % KB_MAX_KEYCODES] = { kcode, 0 };
}
data.keycode[data.len % KB_MAX_KEYCODES] = kcode;
data.len++;
}
data.len = std::min(data.len + 1, (int)KB_MAX_KEYCODES);
}
else
{
// Meta Keys
if (code == 308 || code == 307 || code == 306 || code == 393 || code == 396 || code == 394)
if (is_meta_key)
{
data.mkey &= ~button.m_outKeyCode;
}
// Needed to indicate key releases. Without this you have to tap another key before using the same key again
data.keycode[0] = CELL_KEYC_NO_EVENT;
data.len = 1;
if (config.read_mode == CELL_KB_RMODE_INPUTCHAR)
{
data.keycode[0] = { CELL_KEYC_NO_EVENT, 0 };
data.len = 1;
}
else
{
s32 index = data.len;
for (s32 i = 0; i < data.len; i++)
{
if (data.keycode[i].first == kcode && (!is_meta_key || data.keycode[i].second == button.m_outKeyCode))
{
index = i;
break;
}
}
for (s32 i = index; i < data.len - 1; i++)
{
data.keycode[i] = data.keycode[i + 1];
}
if (data.len <= 1)
{
data.keycode[0] = { CELL_KEYC_NO_EVENT, 0 };
}
data.len = std::max(1, data.len - 1);
}
}
}
}
}
bool IsMetaKey(u32 code)
{
return code == Key_Control
|| code == Key_Shift
|| code == Key_Alt
|| code == Key_Super_L
|| code == Key_Super_R;
}
KbInfo& GetInfo() { return m_info; }
std::vector<Keyboard>& GetKeyboards() { return m_keyboards; }
std::vector<KbButton>& GetButtons(const u32 keyboard) { return m_keyboards[keyboard].m_buttons; }

View File

@ -510,7 +510,7 @@ struct cfg_root : cfg::node
{
node_sys(cfg::node* _this) : cfg::node(_this, "System") {}
cfg::_enum<CellSysutilLang> language{this, "Language"};
cfg::_enum<CellSysutilLang> language{this, "Language", (CellSysutilLang)1}; // CELL_SYSUTIL_LANG_ENGLISH_US
} sys{this};

View File

@ -3,11 +3,20 @@
#include <QApplication>
#include <QKeyEvent>
#include "Emu/System.h"
void basic_keyboard_handler::Init(const u32 max_connect)
{
for (u32 i = 0; i<max_connect; i++)
for (u32 i = 0; i < max_connect; i++)
{
m_keyboards.emplace_back(Keyboard());
Keyboard kb = Keyboard();
// Only differentiate between japanese and us layouts right now
kb.m_config.arrange = g_cfg.sys.language == 0 // CELL_SYSUTIL_LANG_JAPANESE
? CELL_KB_MAPPING_106
: CELL_KB_MAPPING_101;
m_keyboards.emplace_back();
}
LoadSettings();
@ -80,7 +89,7 @@ void basic_keyboard_handler::keyReleaseEvent(QKeyEvent* keyEvent)
void basic_keyboard_handler::LoadSettings()
{
// Meta Keys
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Control, CELL_KB_MKEY_L_CTRL);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_Control, CELL_KB_MKEY_L_CTRL);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Shift, CELL_KB_MKEY_L_SHIFT);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Alt, CELL_KB_MKEY_L_ALT);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Super_L, CELL_KB_MKEY_L_WIN);
@ -95,8 +104,8 @@ void basic_keyboard_handler::LoadSettings()
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_POSTFAIL);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_E_UNDEF);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Escape, CELL_KEYC_ESCAPE);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_106_KANJI);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_CapsLock, CELL_KEYC_CAPS_LOCK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Kanji, CELL_KEYC_106_KANJI);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_CapsLock, CELL_KEYC_CAPS_LOCK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F1, CELL_KEYC_F1);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F2, CELL_KEYC_F2);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F3, CELL_KEYC_F3);
@ -113,7 +122,7 @@ void basic_keyboard_handler::LoadSettings()
m_keyboards[0].m_buttons.emplace_back(Qt::Key_ScrollLock, CELL_KEYC_SCROLL_LOCK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Pause, CELL_KEYC_PAUSE);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Insert, CELL_KEYC_INSERT);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_HOME);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Home, CELL_KEYC_HOME);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_PageUp, CELL_KEYC_PAGE_UP);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Delete, CELL_KEYC_DELETE);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_End, CELL_KEYC_END);
@ -124,87 +133,88 @@ void basic_keyboard_handler::LoadSettings()
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Up, CELL_KEYC_UP_ARROW);
//m_keyboards[0].m_buttons.emplace_back(WXK_NUMLOCK, CELL_KEYC_NUM_LOCK);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_APPLICATION);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_KANA);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_HENKAN);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_MUHENKAN);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Kana_Shift, CELL_KEYC_KANA); // maybe Key_Kana_Lock
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Henkan, CELL_KEYC_HENKAN);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Muhenkan, CELL_KEYC_MUHENKAN);
// CELL_KB_KEYPAD
m_keyboards[0].m_buttons.emplace_back(Qt::Key_NumLock, CELL_KEYC_KPAD_NUMLOCK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_division, CELL_KEYC_KPAD_SLASH);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_multiply, CELL_KEYC_KPAD_ASTERISK);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Minus, CELL_KEYC_KPAD_MINUS);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_division, CELL_KEYC_KPAD_SLASH); // should ideally be slash but that's occupied obviously
m_keyboards[0].m_buttons.emplace_back(Qt::Key_multiply, CELL_KEYC_KPAD_ASTERISK); // should ideally be asterisk but that's occupied obviously
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_Minus, CELL_KEYC_KPAD_MINUS); // should ideally be minus but that's occupied obviously
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Plus, CELL_KEYC_KPAD_PLUS);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Enter, CELL_KEYC_KPAD_ENTER);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_1, CELL_KEYC_KPAD_1);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_2, CELL_KEYC_KPAD_2);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_3, CELL_KEYC_KPAD_3);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_4, CELL_KEYC_KPAD_4);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_5, CELL_KEYC_KPAD_5);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_6, CELL_KEYC_KPAD_6);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_7, CELL_KEYC_KPAD_7);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_8, CELL_KEYC_KPAD_8);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_9, CELL_KEYC_KPAD_9);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_0, CELL_KEYC_KPAD_0);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Delete, CELL_KEYC_KPAD_PERIOD);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_1, CELL_KEYC_KPAD_1);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_2, CELL_KEYC_KPAD_2);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_3, CELL_KEYC_KPAD_3);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_4, CELL_KEYC_KPAD_4);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_5, CELL_KEYC_KPAD_5);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_6, CELL_KEYC_KPAD_6);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_7, CELL_KEYC_KPAD_7);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_8, CELL_KEYC_KPAD_8);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_9, CELL_KEYC_KPAD_9);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_0, CELL_KEYC_KPAD_0);
//m_keyboards[0].m_buttons.emplace_back(Qt::Key_Delete, CELL_KEYC_KPAD_PERIOD);
// ASCII Printable characters
m_keyboards[0].m_buttons.emplace_back('A', CELL_KEYC_A);
m_keyboards[0].m_buttons.emplace_back('B', CELL_KEYC_B);
m_keyboards[0].m_buttons.emplace_back('C', CELL_KEYC_C);
m_keyboards[0].m_buttons.emplace_back('D', CELL_KEYC_D);
m_keyboards[0].m_buttons.emplace_back('E', CELL_KEYC_E);
m_keyboards[0].m_buttons.emplace_back('F', CELL_KEYC_F);
m_keyboards[0].m_buttons.emplace_back('G', CELL_KEYC_G);
m_keyboards[0].m_buttons.emplace_back('H', CELL_KEYC_H);
m_keyboards[0].m_buttons.emplace_back('I', CELL_KEYC_I);
m_keyboards[0].m_buttons.emplace_back('J', CELL_KEYC_J);
m_keyboards[0].m_buttons.emplace_back('K', CELL_KEYC_K);
m_keyboards[0].m_buttons.emplace_back('L', CELL_KEYC_L);
m_keyboards[0].m_buttons.emplace_back('M', CELL_KEYC_M);
m_keyboards[0].m_buttons.emplace_back('N', CELL_KEYC_N);
m_keyboards[0].m_buttons.emplace_back('O', CELL_KEYC_O);
m_keyboards[0].m_buttons.emplace_back('P', CELL_KEYC_P);
m_keyboards[0].m_buttons.emplace_back('Q', CELL_KEYC_Q);
m_keyboards[0].m_buttons.emplace_back('R', CELL_KEYC_R);
m_keyboards[0].m_buttons.emplace_back('S', CELL_KEYC_S);
m_keyboards[0].m_buttons.emplace_back('T', CELL_KEYC_T);
m_keyboards[0].m_buttons.emplace_back('U', CELL_KEYC_U);
m_keyboards[0].m_buttons.emplace_back('V', CELL_KEYC_V);
m_keyboards[0].m_buttons.emplace_back('W', CELL_KEYC_W);
m_keyboards[0].m_buttons.emplace_back('X', CELL_KEYC_X);
m_keyboards[0].m_buttons.emplace_back('Y', CELL_KEYC_Y);
m_keyboards[0].m_buttons.emplace_back('Z', CELL_KEYC_Z);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_A, CELL_KEYC_A);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_B, CELL_KEYC_B);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_C, CELL_KEYC_C);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_D, CELL_KEYC_D);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_E, CELL_KEYC_E);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_F, CELL_KEYC_F);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_G, CELL_KEYC_G);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_H, CELL_KEYC_H);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_I, CELL_KEYC_I);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_J, CELL_KEYC_J);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_K, CELL_KEYC_K);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_L, CELL_KEYC_L);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_M, CELL_KEYC_M);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_N, CELL_KEYC_N);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_O, CELL_KEYC_O);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_P, CELL_KEYC_P);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Q, CELL_KEYC_Q);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_R, CELL_KEYC_R);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_S, CELL_KEYC_S);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_T, CELL_KEYC_T);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_U, CELL_KEYC_U);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_V, CELL_KEYC_V);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_W, CELL_KEYC_W);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_X, CELL_KEYC_X);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Y, CELL_KEYC_Y);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Z, CELL_KEYC_Z);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_1, CELL_KEYC_1);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_2, CELL_KEYC_2);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_3, CELL_KEYC_3);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_4, CELL_KEYC_4);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_5, CELL_KEYC_5);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_6, CELL_KEYC_6);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_7, CELL_KEYC_7);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_8, CELL_KEYC_8);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_9, CELL_KEYC_9);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_0, CELL_KEYC_0);
m_keyboards[0].m_buttons.emplace_back('1', CELL_KEYC_1);
m_keyboards[0].m_buttons.emplace_back('2', CELL_KEYC_2);
m_keyboards[0].m_buttons.emplace_back('3', CELL_KEYC_3);
m_keyboards[0].m_buttons.emplace_back('4', CELL_KEYC_4);
m_keyboards[0].m_buttons.emplace_back('5', CELL_KEYC_5);
m_keyboards[0].m_buttons.emplace_back('6', CELL_KEYC_6);
m_keyboards[0].m_buttons.emplace_back('7', CELL_KEYC_7);
m_keyboards[0].m_buttons.emplace_back('8', CELL_KEYC_8);
m_keyboards[0].m_buttons.emplace_back('9', CELL_KEYC_9);
m_keyboards[0].m_buttons.emplace_back('0', CELL_KEYC_0);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Return, CELL_KEYC_ENTER);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_ESC);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Backspace, CELL_KEYC_BS);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Tab, CELL_KEYC_TAB);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Space, CELL_KEYC_SPACE);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Minus, CELL_KEYC_MINUS);
m_keyboards[0].m_buttons.emplace_back('=', CELL_KEYC_EQUAL_101);
m_keyboards[0].m_buttons.emplace_back('^', CELL_KEYC_ACCENT_CIRCONFLEX_106);
//m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_LEFT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back('@', CELL_KEYC_ATMARK_106);
//m_keyboards[0].m_buttons.emplace_back(')', CELL_KEYC_RIGHT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_LEFT_BRACKET_106);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_BACKSLASH_101);
m_keyboards[0].m_buttons.emplace_back('(', CELL_KEYC_RIGHT_BRACKET_106);
m_keyboards[0].m_buttons.emplace_back(';', CELL_KEYC_SEMICOLON);
m_keyboards[0].m_buttons.emplace_back('"', CELL_KEYC_QUOTATION_101);
m_keyboards[0].m_buttons.emplace_back(':', CELL_KEYC_COLON_106);
m_keyboards[0].m_buttons.emplace_back(',', CELL_KEYC_COMMA);
m_keyboards[0].m_buttons.emplace_back('.', CELL_KEYC_PERIOD);
m_keyboards[0].m_buttons.emplace_back('/', CELL_KEYC_SLASH);
m_keyboards[0].m_buttons.emplace_back('\\', CELL_KEYC_BACKSLASH_106);
//m_keyboards[0].m_buttons.emplace_back(, CELL_KEYC_YEN_106);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Equal, CELL_KEYC_EQUAL_101);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_AsciiCircum, CELL_KEYC_ACCENT_CIRCONFLEX_106);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_BracketLeft, CELL_KEYC_LEFT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_At, CELL_KEYC_ATMARK_106);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_BracketRight, CELL_KEYC_RIGHT_BRACKET_101);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_BracketLeft, CELL_KEYC_LEFT_BRACKET_106);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Backslash, CELL_KEYC_BACKSLASH_101);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_BracketRight, CELL_KEYC_RIGHT_BRACKET_106);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Semicolon, CELL_KEYC_SEMICOLON);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_QuoteDbl, CELL_KEYC_QUOTATION_101);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Colon, CELL_KEYC_COLON_106);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Comma, CELL_KEYC_COMMA);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Period, CELL_KEYC_PERIOD);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Slash, CELL_KEYC_SLASH);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_Backslash, CELL_KEYC_BACKSLASH_106);
m_keyboards[0].m_buttons.emplace_back(Qt::Key_yen, CELL_KEYC_YEN_106);
}