2020-12-05 13:08:24 +01:00
#include "basic_keyboard_handler.h"
2017-06-04 09:48:33 -05:00
2017-07-12 09:07:40 -05:00
#include <QApplication>
2017-06-04 09:48:33 -05:00
2020-02-15 23:36:20 +01:00
#include "Emu/system_config.h"
2020-10-04 22:46:28 +02:00
#include "Emu/Io/interception.h"
2018-07-17 01:23:14 +02:00
2019-08-13 00:17:32 +02:00
#ifdef _WIN32
#include "windows.h"
2026-06-23 08:04:31 +02:00
#elif __linux__
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-x11.h>
#include <private/qxkbcommon_p.h>
#include <QGuiApplication>
2019-08-13 00:17:32 +02:00
#endif
2020-02-01 10:43:43 +03:00
LOG_CHANNEL ( input_log , "Input" );
2020-02-01 07:15:50 +03:00
2024-04-25 23:17:27 +02:00
void basic_keyboard_handler :: Init ( keyboard_consumer & consumer , const u32 max_connect )
2017-06-04 09:48:33 -05:00
{
2024-04-25 23:17:27 +02:00
KbInfo & info = consumer . GetInfo ();
std :: vector < Keyboard >& keyboards = consumer . GetKeyboards ();
info = {};
keyboards . clear ();
2022-04-25 18:44:28 +02:00
2018-07-17 01:23:14 +02:00
for ( u32 i = 0 ; i < max_connect ; i ++ )
2017-06-04 09:48:33 -05:00
{
2022-04-19 22:30:20 +02:00
Keyboard kb {};
2019-08-17 16:08:47 +02:00
kb . m_config . arrange = g_cfg . sys . keyboard_type ;
2018-07-17 01:23:14 +02:00
2024-04-25 23:17:27 +02:00
if ( consumer . id () == keyboard_consumer :: identifier :: overlays )
{
// Enable key repeat
kb . m_key_repeat = true ;
}
LoadSettings ( kb );
keyboards . emplace_back ( kb );
2017-06-04 09:48:33 -05:00
}
2024-04-25 23:17:27 +02:00
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)
2017-06-04 09:48:33 -05:00
}
2017-07-12 09:07:40 -05:00
/* Sets the target window for the event handler, and also installs an event filter on the target. */
void basic_keyboard_handler :: SetTargetWindow ( QWindow * target )
{
2026-06-23 08:04:31 +02:00
if ( target )
2017-07-12 09:07:40 -05:00
{
m_target = target ;
target -> installEventFilter ( this );
}
else
{
// If this is hit, it probably means that some refactoring occurs because currently a gsframe is created in Load.
// We still want events so filter from application instead since target is null.
QApplication :: instance () -> installEventFilter ( this );
2020-02-01 07:15:50 +03:00
input_log . error ( "Trying to set keyboard handler to a null target window." );
2017-07-12 09:07:40 -05:00
}
}
2021-04-07 23:05:18 +02:00
bool basic_keyboard_handler :: eventFilter ( QObject * watched , QEvent * event )
2017-06-04 09:48:33 -05:00
{
2024-08-12 20:31:06 +02:00
if ( ! event ) [[unlikely]]
2019-08-13 00:17:32 +02:00
{
return false ;
}
2024-08-12 20:31:06 +02:00
if ( input :: g_active_mouse_and_keyboard != input :: active_mouse_and_keyboard :: emulated )
{
if ( ! m_keys_released )
{
ReleaseAllKeys ();
}
return false ;
}
m_keys_released = false ;
2017-07-12 09:07:40 -05:00
// !m_target is for future proofing when gsrender isn't automatically initialized on load.
// !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target)
2021-04-07 23:05:18 +02:00
if ( ! m_target || ! m_target -> isVisible () || watched == m_target )
2017-06-04 09:48:33 -05:00
{
2021-04-17 11:22:54 +02:00
switch ( event -> type ())
{
case QEvent :: KeyPress :
2017-06-04 09:48:33 -05:00
{
2021-04-07 23:05:18 +02:00
keyPressEvent ( static_cast < QKeyEvent *> ( event ));
2021-04-17 11:22:54 +02:00
break ;
2017-06-04 09:48:33 -05:00
}
2021-04-17 11:22:54 +02:00
case QEvent :: KeyRelease :
2017-06-04 09:48:33 -05:00
{
2021-04-07 23:05:18 +02:00
keyReleaseEvent ( static_cast < QKeyEvent *> ( event ));
2021-04-17 11:22:54 +02:00
break ;
}
case QEvent :: FocusOut :
{
ReleaseAllKeys ();
break ;
}
default :
{
break ;
}
2017-06-04 09:48:33 -05:00
}
}
return false ;
}
void basic_keyboard_handler :: keyPressEvent ( QKeyEvent * keyEvent )
{
2024-08-12 20:31:06 +02:00
if ( ! keyEvent ) [[unlikely]]
2019-08-13 00:17:32 +02:00
{
return ;
}
2024-04-25 23:17:27 +02:00
if ( m_consumers . empty ())
2017-12-31 12:01:11 +01:00
{
keyEvent -> ignore ();
return ;
}
2019-08-13 00:17:32 +02:00
2026-06-23 08:04:31 +02:00
const int key = get_unmodified_key ( keyEvent );
2019-08-13 00:17:32 +02:00
2024-06-23 11:26:34 +02:00
if ( key < 0 || ! HandleKey ( static_cast < u32 > ( key ), keyEvent -> nativeScanCode (), true , keyEvent -> isAutoRepeat (), keyEvent -> text (). toStdU32String ()))
2019-08-13 00:17:32 +02:00
{
2024-04-25 23:17:27 +02:00
keyEvent -> ignore ();
2019-08-13 00:17:32 +02:00
}
2017-06-04 09:48:33 -05:00
}
void basic_keyboard_handler :: keyReleaseEvent ( QKeyEvent * keyEvent )
{
2024-08-12 20:31:06 +02:00
if ( ! keyEvent ) [[unlikely]]
2019-08-13 00:17:32 +02:00
{
return ;
}
2024-04-25 23:17:27 +02:00
if ( m_consumers . empty ())
2017-12-31 12:01:11 +01:00
{
keyEvent -> ignore ();
return ;
}
2019-08-13 00:17:32 +02:00
2026-06-23 08:04:31 +02:00
const int key = get_unmodified_key ( keyEvent );
2019-08-13 00:17:32 +02:00
2024-06-23 11:26:34 +02:00
if ( key < 0 || ! HandleKey ( static_cast < u32 > ( key ), keyEvent -> nativeScanCode (), false , keyEvent -> isAutoRepeat (), keyEvent -> text (). toStdU32String ()))
2019-08-13 00:17:32 +02:00
{
2024-04-25 23:17:27 +02:00
keyEvent -> ignore ();
2019-08-13 00:17:32 +02:00
}
}
// This should get the actual unmodified key without getting too crazy.
2026-06-23 08:04:31 +02:00
// key() only shows the modifiers and the modified key.
// e.g. 'Shift+1' may result in Qt::Key_Exclam, so we lose the information that Qt::Key_1 was pressed.
// We want to find the actual physical key that was pressed (and return Qt::Key_1 in this example).
s32 basic_keyboard_handler :: get_unmodified_key ( QKeyEvent * keyEvent )
2019-08-13 00:17:32 +02:00
{
2024-08-12 20:31:06 +02:00
if ( ! keyEvent ) [[unlikely]]
2019-08-13 00:17:32 +02:00
{
return - 1 ;
}
2019-08-17 20:57:07 +02:00
const int key = keyEvent -> key ();
if ( key < 0 )
{
return key ;
}
2019-08-17 21:28:01 +02:00
u32 raw_key = static_cast < u32 > ( key );
2019-08-13 00:17:32 +02:00
if ( keyEvent -> modifiers () != Qt :: NoModifier && ! keyEvent -> text (). isEmpty ())
{
2026-06-23 08:04:31 +02:00
#ifdef _WIN32
2021-04-07 23:05:18 +02:00
u32 mapped_key = static_cast < u32 > ( MapVirtualKeyA ( static_cast < UINT > ( keyEvent -> nativeVirtualKey ()), MAPVK_VK_TO_CHAR ));
2019-08-17 20:57:07 +02:00
if ( raw_key != mapped_key )
2019-08-13 00:17:32 +02:00
{
2019-08-17 20:57:07 +02:00
if ( mapped_key > 0x80000000 ) // diacritics
{
mapped_key -= 0x80000000 ;
}
raw_key = mapped_key ;
2019-08-13 00:17:32 +02:00
}
2026-06-23 08:04:31 +02:00
#elif __linux__
class kb_mapper
{
public :
kb_mapper ()
{
m_ctx = xkb_context_new ( XKB_CONTEXT_NO_FLAGS );
}
~ kb_mapper ()
{
if ( m_ctx ) xkb_context_unref ( m_ctx );
}
s32 get_unmodified_key ( u32 qt_native_scan_code )
{
if ( ! m_ctx ) return - 1 ;
auto * connection = get_connection ();
if ( ! connection ) return - 1 ;
const int device_id = xkb_x11_get_core_keyboard_device_id ( connection );
xkb_keymap * keymap = xkb_x11_keymap_new_from_device ( m_ctx , connection , device_id , XKB_KEYMAP_COMPILE_NO_FLAGS );
if ( ! keymap ) return - 1 ;
xkb_state * state = xkb_x11_state_new_from_device ( keymap , connection , device_id );
if ( ! state )
{
xkb_keymap_unref ( keymap );
return - 1 ;
}
const xkb_keycode_t code = static_cast < xkb_keycode_t > ( qt_native_scan_code );
const xkb_layout_index_t layout = xkb_state_serialize_layout ( state , XKB_STATE_LAYOUT_EFFECTIVE );
const xkb_keysym_t * syms = nullptr ;
const int count = xkb_keymap_key_get_syms_by_level ( keymap , code , layout , 0 , & syms );
const auto new_key = ( syms && count > 0 ) ? QXkbCommon :: keysymToQtKey ( syms [ 0 ], Qt :: NoModifier , nullptr , code ) : - 1 ;
xkb_state_unref ( state );
xkb_keymap_unref ( keymap );
return new_key ;
}
private :
xcb_connection_t * get_connection ()
{
if ( ! qGuiApp ) return nullptr ;
auto * native_interface = qGuiApp -> nativeInterface < QNativeInterface :: QX11Application > ();
return native_interface ? native_interface -> connection () : nullptr ;
}
xkb_context * m_ctx = nullptr ;
};
static kb_mapper mapper = kb_mapper ();
if ( const int res = mapper . get_unmodified_key ( keyEvent -> nativeScanCode ()); res > 0 )
{
raw_key = res ;
}
#elif __APPLE__
// TODO
2019-08-13 00:17:32 +02:00
#endif
2026-06-23 08:04:31 +02:00
}
2019-08-13 00:17:32 +02:00
2019-08-17 20:57:07 +02:00
return static_cast < s32 > ( raw_key );
2017-06-04 09:48:33 -05:00
}
2024-04-25 23:17:27 +02:00
void basic_keyboard_handler :: LoadSettings ( Keyboard & keyboard )
2017-06-04 09:48:33 -05:00
{
2024-04-19 01:57:04 +02:00
std :: vector < KbButton > buttons ;
2020-12-14 14:33:43 +01:00
2017-06-04 09:48:33 -05:00
// Meta Keys
2024-06-23 10:41:33 +02:00
buttons . emplace_back ( Qt :: Key_Control , CELL_KB_MKEY_L_CTRL );
2020-12-14 14:33:43 +01:00
buttons . emplace_back ( Qt :: Key_Shift , CELL_KB_MKEY_L_SHIFT );
buttons . emplace_back ( Qt :: Key_Alt , CELL_KB_MKEY_L_ALT );
2024-06-23 11:26:34 +02:00
buttons . emplace_back ( Qt :: Key_Meta , CELL_KB_MKEY_L_WIN );
2024-06-23 10:41:33 +02:00
//buttons.emplace_back(, CELL_KB_MKEY_R_CTRL); // There is no way to know if it's left or right in Qt at the moment
//buttons.emplace_back(, CELL_KB_MKEY_R_SHIFT); // There is no way to know if it's left or right in Qt at the moment
//buttons.emplace_back(, CELL_KB_MKEY_R_ALT); // There is no way to know if it's left or right in Qt at the moment
2024-06-23 11:26:34 +02:00
//buttons.emplace_back(, CELL_KB_MKEY_R_WIN); // There is no way to know if it's left or right in Qt at the moment
buttons . emplace_back ( Qt :: Key_Super_L , CELL_KB_MKEY_L_WIN ); // The super keys are supposed to be the windows keys, but they trigger the meta key instead. Let's assign the windows keys to both.
buttons . emplace_back ( Qt :: Key_Super_R , CELL_KB_MKEY_R_WIN ); // The super keys are supposed to be the windows keys, but they trigger the meta key instead. Let's assign the windows keys to both.
2017-06-04 09:48:33 -05:00
// CELL_KB_RAWDAT
2024-06-23 10:41:33 +02:00
//buttons.emplace_back(, CELL_KEYC_NO_EVENT); // Redundant, listed for completeness
2020-12-14 14:33:43 +01:00
//buttons.emplace_back(, CELL_KEYC_E_ROLLOVER);
//buttons.emplace_back(, CELL_KEYC_E_POSTFAIL);
//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 );
2024-04-25 23:17:27 +02:00
buttons . emplace_back ( Qt :: Key_CapsLock , CELL_KEYC_CAPS_LOCK );
2020-12-14 14:33:43 +01:00
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 );
buttons . emplace_back ( Qt :: Key_F4 , CELL_KEYC_F4 );
buttons . emplace_back ( Qt :: Key_F5 , CELL_KEYC_F5 );
buttons . emplace_back ( Qt :: Key_F6 , CELL_KEYC_F6 );
buttons . emplace_back ( Qt :: Key_F7 , CELL_KEYC_F7 );
buttons . emplace_back ( Qt :: Key_F8 , CELL_KEYC_F8 );
buttons . emplace_back ( Qt :: Key_F9 , CELL_KEYC_F9 );
buttons . emplace_back ( Qt :: Key_F10 , CELL_KEYC_F10 );
buttons . emplace_back ( Qt :: Key_F11 , CELL_KEYC_F11 );
buttons . emplace_back ( Qt :: Key_F12 , CELL_KEYC_F12 );
buttons . emplace_back ( Qt :: Key_Print , CELL_KEYC_PRINTSCREEN );
buttons . emplace_back ( Qt :: Key_ScrollLock , CELL_KEYC_SCROLL_LOCK );
buttons . emplace_back ( Qt :: Key_Pause , CELL_KEYC_PAUSE );
buttons . emplace_back ( Qt :: Key_Insert , CELL_KEYC_INSERT );
buttons . emplace_back ( Qt :: Key_Home , CELL_KEYC_HOME );
buttons . emplace_back ( Qt :: Key_PageUp , CELL_KEYC_PAGE_UP );
buttons . emplace_back ( Qt :: Key_Delete , CELL_KEYC_DELETE );
buttons . emplace_back ( Qt :: Key_End , CELL_KEYC_END );
buttons . emplace_back ( Qt :: Key_PageDown , CELL_KEYC_PAGE_DOWN );
buttons . emplace_back ( Qt :: Key_Right , CELL_KEYC_RIGHT_ARROW );
buttons . emplace_back ( Qt :: Key_Left , CELL_KEYC_LEFT_ARROW );
buttons . emplace_back ( Qt :: Key_Down , CELL_KEYC_DOWN_ARROW );
buttons . emplace_back ( Qt :: Key_Up , CELL_KEYC_UP_ARROW );
2024-06-23 10:41:33 +02:00
//buttons.emplace_back(, CELL_KEYC_NUM_LOCK);
2024-06-23 11:26:34 +02:00
//buttons.emplace_back(, CELL_KEYC_APPLICATION); // This is probably the PS key on the PS3 keyboard
2020-12-14 14:33:43 +01:00
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 );
2017-06-04 09:48:33 -05:00
// CELL_KB_KEYPAD
2020-12-14 14:33:43 +01:00
buttons . emplace_back ( Qt :: Key_NumLock , CELL_KEYC_KPAD_NUMLOCK );
buttons . emplace_back ( Qt :: Key_division , CELL_KEYC_KPAD_SLASH ); // should ideally be slash but that's occupied obviously
buttons . emplace_back ( Qt :: Key_multiply , CELL_KEYC_KPAD_ASTERISK ); // should ideally be asterisk but that's occupied obviously
//buttons.emplace_back(Qt::Key_Minus, CELL_KEYC_KPAD_MINUS); // should ideally be minus but that's occupied obviously
buttons . emplace_back ( Qt :: Key_Plus , CELL_KEYC_KPAD_PLUS );
buttons . emplace_back ( Qt :: Key_Enter , CELL_KEYC_KPAD_ENTER );
//buttons.emplace_back(Qt::Key_1, CELL_KEYC_KPAD_1);
//buttons.emplace_back(Qt::Key_2, CELL_KEYC_KPAD_2);
//buttons.emplace_back(Qt::Key_3, CELL_KEYC_KPAD_3);
//buttons.emplace_back(Qt::Key_4, CELL_KEYC_KPAD_4);
//buttons.emplace_back(Qt::Key_5, CELL_KEYC_KPAD_5);
//buttons.emplace_back(Qt::Key_6, CELL_KEYC_KPAD_6);
//buttons.emplace_back(Qt::Key_7, CELL_KEYC_KPAD_7);
//buttons.emplace_back(Qt::Key_8, CELL_KEYC_KPAD_8);
//buttons.emplace_back(Qt::Key_9, CELL_KEYC_KPAD_9);
//buttons.emplace_back(Qt::Key_0, CELL_KEYC_KPAD_0);
//buttons.emplace_back(Qt::Key_Delete, CELL_KEYC_KPAD_PERIOD);
2017-06-04 09:48:33 -05:00
// ASCII Printable characters
2020-12-14 14:33:43 +01:00
buttons . emplace_back ( Qt :: Key_A , CELL_KEYC_A );
buttons . emplace_back ( Qt :: Key_B , CELL_KEYC_B );
buttons . emplace_back ( Qt :: Key_C , CELL_KEYC_C );
buttons . emplace_back ( Qt :: Key_D , CELL_KEYC_D );
buttons . emplace_back ( Qt :: Key_E , CELL_KEYC_E );
buttons . emplace_back ( Qt :: Key_F , CELL_KEYC_F );
buttons . emplace_back ( Qt :: Key_G , CELL_KEYC_G );
buttons . emplace_back ( Qt :: Key_H , CELL_KEYC_H );
buttons . emplace_back ( Qt :: Key_I , CELL_KEYC_I );
buttons . emplace_back ( Qt :: Key_J , CELL_KEYC_J );
buttons . emplace_back ( Qt :: Key_K , CELL_KEYC_K );
buttons . emplace_back ( Qt :: Key_L , CELL_KEYC_L );
buttons . emplace_back ( Qt :: Key_M , CELL_KEYC_M );
buttons . emplace_back ( Qt :: Key_N , CELL_KEYC_N );
buttons . emplace_back ( Qt :: Key_O , CELL_KEYC_O );
buttons . emplace_back ( Qt :: Key_P , CELL_KEYC_P );
buttons . emplace_back ( Qt :: Key_Q , CELL_KEYC_Q );
buttons . emplace_back ( Qt :: Key_R , CELL_KEYC_R );
buttons . emplace_back ( Qt :: Key_S , CELL_KEYC_S );
buttons . emplace_back ( Qt :: Key_T , CELL_KEYC_T );
buttons . emplace_back ( Qt :: Key_U , CELL_KEYC_U );
buttons . emplace_back ( Qt :: Key_V , CELL_KEYC_V );
buttons . emplace_back ( Qt :: Key_W , CELL_KEYC_W );
buttons . emplace_back ( Qt :: Key_X , CELL_KEYC_X );
buttons . emplace_back ( Qt :: Key_Y , CELL_KEYC_Y );
buttons . emplace_back ( Qt :: Key_Z , CELL_KEYC_Z );
2018-07-17 01:23:14 +02:00
2020-12-14 14:33:43 +01:00
buttons . emplace_back ( Qt :: Key_1 , CELL_KEYC_1 );
buttons . emplace_back ( Qt :: Key_2 , CELL_KEYC_2 );
buttons . emplace_back ( Qt :: Key_3 , CELL_KEYC_3 );
buttons . emplace_back ( Qt :: Key_4 , CELL_KEYC_4 );
buttons . emplace_back ( Qt :: Key_5 , CELL_KEYC_5 );
buttons . emplace_back ( Qt :: Key_6 , CELL_KEYC_6 );
buttons . emplace_back ( Qt :: Key_7 , CELL_KEYC_7 );
buttons . emplace_back ( Qt :: Key_8 , CELL_KEYC_8 );
buttons . emplace_back ( Qt :: Key_9 , CELL_KEYC_9 );
buttons . emplace_back ( Qt :: Key_0 , CELL_KEYC_0 );
2017-06-04 09:48:33 -05:00
2020-12-14 14:33:43 +01:00
buttons . emplace_back ( Qt :: Key_Return , CELL_KEYC_ENTER );
buttons . emplace_back ( Qt :: Key_Backspace , CELL_KEYC_BS );
buttons . emplace_back ( Qt :: Key_Tab , CELL_KEYC_TAB );
buttons . emplace_back ( Qt :: Key_Space , CELL_KEYC_SPACE );
buttons . emplace_back ( Qt :: Key_Minus , CELL_KEYC_MINUS );
buttons . emplace_back ( Qt :: Key_Equal , CELL_KEYC_EQUAL_101 );
buttons . emplace_back ( Qt :: Key_AsciiCircum , CELL_KEYC_ACCENT_CIRCONFLEX_106 );
buttons . emplace_back ( Qt :: Key_At , CELL_KEYC_ATMARK_106 );
buttons . emplace_back ( Qt :: Key_Semicolon , CELL_KEYC_SEMICOLON );
buttons . emplace_back ( Qt :: Key_Apostrophe , CELL_KEYC_QUOTATION_101 );
buttons . emplace_back ( Qt :: Key_Colon , CELL_KEYC_COLON_106 );
buttons . emplace_back ( Qt :: Key_Comma , CELL_KEYC_COMMA );
buttons . emplace_back ( Qt :: Key_Period , CELL_KEYC_PERIOD );
buttons . emplace_back ( Qt :: Key_Slash , CELL_KEYC_SLASH );
buttons . emplace_back ( Qt :: Key_yen , CELL_KEYC_YEN_106 );
2019-08-17 16:21:37 +02:00
2024-04-19 04:43:09 +02:00
// Some buttons share the same key code on different layouts
if ( keyboard . m_config . arrange == CELL_KB_MAPPING_106 )
{
buttons . emplace_back ( Qt :: Key_Backslash , CELL_KEYC_BACKSLASH_106 );
buttons . emplace_back ( Qt :: Key_BracketLeft , CELL_KEYC_LEFT_BRACKET_106 );
buttons . emplace_back ( Qt :: Key_BracketRight , CELL_KEYC_RIGHT_BRACKET_106 );
}
else
{
buttons . emplace_back ( Qt :: Key_Backslash , CELL_KEYC_BACKSLASH_101 );
buttons . emplace_back ( Qt :: Key_BracketLeft , CELL_KEYC_LEFT_BRACKET_101 );
buttons . emplace_back ( Qt :: Key_BracketRight , CELL_KEYC_RIGHT_BRACKET_101 );
}
2019-08-17 16:21:37 +02:00
// Made up helper buttons
2020-12-14 14:33:43 +01:00
buttons . emplace_back ( Qt :: Key_Less , CELL_KEYC_LESS );
buttons . emplace_back ( Qt :: Key_NumberSign , CELL_KEYC_HASHTAG );
buttons . emplace_back ( Qt :: Key_ssharp , CELL_KEYC_SSHARP );
buttons . emplace_back ( Qt :: Key_QuoteLeft , CELL_KEYC_BACK_QUOTE );
buttons . emplace_back ( Qt :: Key_acute , CELL_KEYC_BACK_QUOTE );
2024-04-19 01:57:04 +02:00
// Fill our map
for ( const KbButton & button : buttons )
{
2024-04-19 04:43:09 +02:00
if ( ! keyboard . m_keys . try_emplace ( button . m_keyCode , button ). second )
{
input_log . error ( "basic_keyboard_handler failed to set key code %d" , button . m_keyCode );
}
2024-04-19 01:57:04 +02:00
}
2017-06-04 09:48:33 -05:00
}