From 3a822e3f3bce3d399614721769153d68ac85dd19 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sat, 23 Jul 2016 19:50:28 +0200 Subject: [PATCH] Add a modifier key correction for the linux tty --- ChangeLog | 4 + src/fapp.cpp | 283 +++++++++++++++++++++++++++++++++++++++++++++++++ src/fapp.h | 1 + src/fenum.h | 1 + src/fkey_map.h | 11 +- src/fterm.cpp | 29 ++++- src/fterm.h | 10 ++ 7 files changed, 333 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34691143..d743747a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-07-23 Markus Gans + * Add a modifier key correction for the linux tty + * Support to read meta+enter from keyboard + 2016-07-16 Markus Gans * Support to read meta+tab from keyboard diff --git a/src/fapp.cpp b/src/fapp.cpp index 373c1cde..13b66bbb 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -300,6 +300,8 @@ void FApplication::processKeyboardEvent() if ( key != NEED_MORE_DATA ) { + key = modifierKeyCorrection (key); + if ( key == fc::Fckey_l ) // Ctrl-L (redraw the screen) redraw(); @@ -431,6 +433,283 @@ void FApplication::processKeyboardEvent() } } +//---------------------------------------------------------------------- +int FApplication::modifierKeyCorrection (int& key) +{ + // get the current modifier key state + getModifierKey(); + modifier_key& m = mod_key; + + if ( m.shift && ! m.ctrl && ! m.alt ) + { + switch ( key ) + { + case fc::Fkey_up: + return fc::Fkey_sr; // Shift+Up + + case fc::Fkey_down: + return fc::Fkey_sf; // Shift+Down + + case fc::Fkey_left: + return fc::Fkey_sleft; // Shift+Left + + case fc::Fkey_right: + return fc::Fkey_sright; // Shift+Right + + case fc::Fkey_ic: + return fc::Fkey_sic; // Shift+Ins + + case fc::Fkey_dc: + return fc::Fkey_sdc; // Shift+Del + + case fc::Fkey_home: + return fc::Fkey_shome; // Shift+Home + + case fc::Fkey_end: + return fc::Fkey_send; // Shift+End + + case fc::Fkey_ppage: + return fc::Fkey_sprevious; // Shift+PgUp + + case fc::Fkey_npage: + return fc::Fkey_snext; // Shift+PgDn + + default: + return key; + } + } + else if ( ! m.shift && m.ctrl && ! m.alt ) + { + switch ( key ) + { + case fc::Fkey_up: + return fc::Fckey_up; // Ctrl+Up + + case fc::Fkey_down: + return fc::Fckey_down; // Ctrl+Down + + case fc::Fkey_left: + return fc::Fckey_left; // Ctrl+Left + + case fc::Fkey_right: + return fc::Fckey_right; // Ctrl+Right + + case fc::Fkey_ic: + return fc::Fckey_ic; // Ctrl+Ins + + case fc::Fkey_dc: + return fc::Fckey_dc; // Ctrl+Del + + case fc::Fkey_home: + return fc::Fckey_home; // Ctrl+Home + + case fc::Fkey_end: + return fc::Fckey_end; // Ctrl+End + + case fc::Fkey_ppage: + return fc::Fckey_ppage; // Ctrl+PgUp + + case fc::Fkey_npage: + return fc::Fckey_npage; // Ctrl+PgDn + + default: + return key; + } + } + else if ( ! m.shift && ! m.ctrl && m.alt ) + { + switch ( key ) + { + case fc::Fkey_up: + return fc::Fmkey_up; // Meta+Up + + case fc::Fkey_down: + return fc::Fmkey_down; // Meta+Down + + case fc::Fkey_left: + return fc::Fmkey_left; // Meta+Left + + case fc::Fkey_right: + return fc::Fmkey_right; // Meta+Right + + case fc::Fkey_ic: + return fc::Fmkey_ic; // Meta+Ins + + case fc::Fkey_dc: + return fc::Fmkey_dc; // Meta+Del + + case fc::Fkey_home: + return fc::Fmkey_home; // Meta+Home + + case fc::Fkey_end: + return fc::Fmkey_end; // Meta+End + + case fc::Fkey_ppage: + return fc::Fmkey_ppage; // Meta+PgUp + + case fc::Fkey_npage: + return fc::Fmkey_npage; // Meta+PgDn + + default: + return key; + } + } + else if ( m.shift && m.ctrl && ! m.alt ) + { + switch ( key ) + { + case fc::Fkey_up: + return fc::Fckey_sup; // Shift+Ctrl+Up + + case fc::Fkey_down: + return fc::Fckey_sdown; // Shift+Ctrl+Down + + case fc::Fkey_left: + return fc::Fckey_sleft; // Shift+Ctrl+Left + + case fc::Fkey_right: + return fc::Fckey_sright; // Shift+Ctrl+Right + + case fc::Fkey_ic: + return fc::Fckey_sic; // Shift+Ctrl+Ins + + case fc::Fkey_dc: + return fc::Fckey_sdc; // Shift+Ctrl+Del + + case fc::Fkey_home: + return fc::Fckey_shome; // Shift+Ctrl+Home + + case fc::Fkey_end: + return fc::Fckey_send; // Shift+Ctrl+End + + case fc::Fkey_ppage: + return fc::Fckey_sppage; // Shift+Ctrl+PgUp + + case fc::Fkey_npage: + return fc::Fckey_snpage; // Shift+Ctrl+PgDn + + default: + return key; + } + } + else if ( m.shift && ! m.ctrl && m.alt ) + { + switch ( key ) + { + case fc::Fkey_up: + return fc::Fmkey_sup; // Shift+Meta+Up + + case fc::Fkey_down: + return fc::Fmkey_sdown; // Shift+Meta+Down + + case fc::Fkey_left: + return fc::Fmkey_sright; // Shift+Meta+Left + + case fc::Fkey_right: + return fc::Fmkey_sleft; // Shift+Meta+Right + + case fc::Fkey_ic: + return fc::Fmkey_sic; // Shift+Meta+Ins + + case fc::Fkey_dc: + return fc::Fmkey_sdc; // Shift+Meta+Del + + case fc::Fkey_home: + return fc::Fmkey_shome; // Shift+Meta+Home + + case fc::Fkey_end: + return fc::Fmkey_send; // Shift+Meta+End + + case fc::Fkey_ppage: + return fc::Fmkey_sppage; // Shift+Meta+PgUp + + case fc::Fkey_npage: + return fc::Fmkey_snpage; // Shift+Meta+PgDn + + default: + return key; + } + } + else if ( ! m.shift && m.ctrl && m.alt ) + { + switch ( key ) + { + case fc::Fkey_up: + return fc::Fcmkey_up; // Ctrl+Meta+Up + + case fc::Fkey_down: + return fc::Fcmkey_down; // Ctrl+Meta+Down + + case fc::Fkey_left: + return fc::Fcmkey_left; // Ctrl+Meta+Left + + case fc::Fkey_right: + return fc::Fcmkey_right; // Ctrl+Meta+Right + + case fc::Fkey_ic: + return fc::Fcmkey_ic; // Ctrl+Meta+Ins + + case fc::Fkey_dc: + return fc::Fcmkey_dc; // Ctrl+Meta+Del + + case fc::Fkey_home: + return fc::Fcmkey_home; // Ctrl+Meta+Home + + case fc::Fkey_end: + return fc::Fcmkey_end; // Ctrl+Meta+End + + case fc::Fkey_ppage: + return fc::Fcmkey_ppage; // Ctrl+Meta+PgUp + + case fc::Fkey_npage: + return fc::Fcmkey_npage; // Ctrl+Meta+PgDn + + default: + return key; + } + } + else if ( m.shift && m.ctrl && m.alt ) + { + switch ( key ) + { + case fc::Fkey_up: + return fc::Fcmkey_sup; // Shift+Ctrl+Meta+Up + + case fc::Fkey_down: + return fc::Fcmkey_sdown; // Shift+Ctrl+Meta+Down + + case fc::Fkey_left: + return fc::Fcmkey_sleft; // Shift+Ctrl+Meta+Left + + case fc::Fkey_right: + return fc::Fcmkey_sright; // Shift+Ctrl+Meta+Right + + case fc::Fkey_ic: + return fc::Fcmkey_sic; // Shift+Ctrl+Meta+Ins + + case fc::Fkey_dc: + return fc::Fcmkey_sdc; // Shift+Ctrl+Meta+Del + + case fc::Fkey_home: + return fc::Fcmkey_shome; // Shift+Ctrl+Meta+Home + + case fc::Fkey_end: + return fc::Fcmkey_send; // Shift+Ctrl+Meta+End + + case fc::Fkey_ppage: + return fc::Fcmkey_sppage; // Shift+Ctrl+Meta+PgUp + + case fc::Fkey_npage: + return fc::Fcmkey_snpage; // Shift+Ctrl+Meta+PgDn + + default: + return key; + } + } + + return key; +} + //---------------------------------------------------------------------- void FApplication::processDialogSwitchAccelerator() { @@ -599,6 +878,7 @@ bool FApplication::parseX11Mouse() x = uChar(x11_mouse[1] - 0x20); y = uChar(x11_mouse[2] - 0x20); newMousePosition.setPoint(x,y); + // fill bit field with 0 memset(&b_state, 0x00, sizeof(b_state)); if ( (x11_mouse[0] & key_shift) == key_shift ) @@ -691,6 +971,7 @@ bool FApplication::parseSGRMouse() } newMousePosition.setPoint(x,y); + // fill bit field with 0 memset(&b_state, 0x00, sizeof(b_state)); if ( (button & key_shift) == key_shift ) @@ -887,6 +1168,7 @@ bool FApplication::parseUrxvtMouse() y = uChar(term->getHeight()); newMousePosition.setPoint(x,y); + // fill bit field with 0 memset(&b_state, 0x00, sizeof(b_state)); if ( (button & key_shift) == key_shift ) @@ -925,6 +1207,7 @@ bool FApplication::parseUrxvtMouse() #ifdef F_HAVE_LIBGPM bool FApplication::processGpmEvent() { + // fill bit field with 0 memset(&b_state, 0x00, sizeof(b_state)); if ( Gpm_GetEvent(&gpm_ev) == 1 ) diff --git a/src/fapp.h b/src/fapp.h index 0d52f4ab..ed147642 100644 --- a/src/fapp.h +++ b/src/fapp.h @@ -124,6 +124,7 @@ class FApplication : public FWidget bool KeyPressed(); ssize_t readKey(); void processKeyboardEvent(); + int modifierKeyCorrection (int& key); void processDialogSwitchAccelerator(); void processAccelerator (FWidget*); void getX11ButtonState (int); diff --git a/src/fenum.h b/src/fenum.h index d68971b3..94f4a948 100644 --- a/src/fenum.h +++ b/src/fenum.h @@ -510,6 +510,7 @@ class fc Fkey_urxvt_mouse = 0x2000022, // urxvt mouse extension Fmkey_meta = 0x20000e0, // meta key offset Fmkey_tab = 0x20000e9, // M-tab + Fmkey_enter = 0x20000ea, // M-enter Fmkey_space = 0x2000100, // M-' ' Fmkey_bang = 0x2000101, // M-! Fmkey_quotes = 0x2000102, // M-" diff --git a/src/fkey_map.h b/src/fkey_map.h index c9c4dd39..24c2e26a 100644 --- a/src/fkey_map.h +++ b/src/fkey_map.h @@ -326,6 +326,8 @@ static metakeymap Fmetakey[] = { fc::Fcmkey_smenu , "\033[29;8~" }, // shift-ctrl-M-menu { fc::Fkey_escape_mintty , "\033O["}, // mintty Esc { fc::Fmkey_tab , "\033\t"}, // M-tab + { fc::Fmkey_enter , "\033\n"}, // M-enter + { fc::Fmkey_enter , "\033\r"}, // M-enter { fc::Fmkey_space , "\033 " }, // M-' ' { fc::Fmkey_bang , "\033!" }, // M-! { fc::Fmkey_quotes , "\033\""}, // M-" @@ -675,10 +677,10 @@ static keyname FkeyName[] = { fc::Fckey_down , "Ctrl+Down" }, { fc::Fckey_right , "Ctrl+Right" }, { fc::Fckey_left , "Ctrl+Left" }, - { fc::Fckey_sic , "Ctrl+Ins" }, - { fc::Fckey_sdc , "Ctrl+Del" }, - { fc::Fckey_shome , "Ctrl+Home" }, - { fc::Fckey_send , "Ctrl+End" }, + { fc::Fckey_sic , "Shift+Ctrl+Ins" }, + { fc::Fckey_sdc , "Shift+Ctrl+Del" }, + { fc::Fckey_shome , "Shift+Ctrl+Home" }, + { fc::Fckey_send , "Shift+Ctrl+End" }, { fc::Fckey_sppage , "Shift+Ctrl+PgUp" }, { fc::Fckey_snpage , "Shift+Ctrl+PgDn" }, { fc::Fckey_sup , "Shift+Ctrl+Up" }, @@ -726,6 +728,7 @@ static keyname FkeyName[] = { fc::Fcmkey_menu , "Ctrl+Meta+Menu" }, { fc::Fcmkey_smenu , "Shift+Ctrl+Meta+Menu" }, { fc::Fmkey_tab , "Meta+Tab" }, + { fc::Fmkey_enter , "Meta+Enter" }, { fc::Fmkey_space , "Meta+Space" }, { fc::Fmkey_bang , "Meta+!" }, { fc::Fmkey_quotes , "Meta+\"" }, diff --git a/src/fterm.cpp b/src/fterm.cpp index 9e11c99b..f32d2c30 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -96,6 +96,7 @@ const FString* FTerm::AnswerBack = 0; const FString* FTerm::Sec_DA = 0; FOptiMove* FTerm::opti_move = 0; FOptiAttr* FTerm::opti_attr = 0; +FTerm::modifier_key FTerm::mod_key; FTerm::term_area* FTerm::vterm = 0; FTerm::term_area* FTerm::vdesktop = 0; FTerm::term_area* FTerm::vmenubar = 0; @@ -388,7 +389,7 @@ int FTerm::setScreenFont ( uChar* fontdata, uInt count return -1; // initialize unused padding bytes in struct - memset(&font, 0, sizeof(console_font_op)); + memset(&font, 0x00, sizeof(console_font_op)); font.op = KD_FONT_OP_SET; font.flags = 0; @@ -687,7 +688,7 @@ int FTerm::parseKeyString ( char* buffer } //---------------------------------------------------------------------- -FString FTerm::getKeyName(int keynum) +FString FTerm::getKeyName (int keynum) { for (int i=0; FkeyName[i].string[0] != 0; i++) if ( FkeyName[i].num && FkeyName[i].num == keynum ) @@ -699,6 +700,30 @@ FString FTerm::getKeyName(int keynum) return FString(""); } +//---------------------------------------------------------------------- +void FTerm::getModifierKey() +{ + char subcode = 6; + // fill bit field with 0 + memset (&mod_key, 0x00, sizeof(mod_key)); + + // TIOCLINUX, subcode=6 + if ( ioctl(0, TIOCLINUX, &subcode) >= 0 ) + { + if ( subcode & (1 << KG_SHIFT) ) + mod_key.shift = true; + + if ( subcode & (1 << KG_ALTGR) ) + mod_key.alt_gr = true; + + if ( subcode & (1 << KG_CTRL) ) + mod_key.ctrl = true; + + if ( subcode & (1 << KG_ALT) ) + mod_key.alt = true; + } +} + //---------------------------------------------------------------------- void FTerm::init_console() { diff --git a/src/fterm.h b/src/fterm.h index ad2b192d..621f0fa1 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -190,6 +190,15 @@ class FTerm dacreg d[16]; } map; + static struct modifier_key // bit field + { + uChar shift : 1; // 0..1 + uChar alt_gr : 1; // 0..1 + uChar ctrl : 1; // 0..1 + uChar alt : 1; // 0..1 + uChar : 4; // padding bits + } mod_key; + protected: static bool NewFont; static bool VGAFont; @@ -290,6 +299,7 @@ class FTerm int getLineNumber(); int getColumnNumber(); static FString getKeyName (int); + static void getModifierKey(); static char* getTermType(); static char* getTermName();