From 0e5b1dfebd14f69ce0a7c41214cbfd04401c531f Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 2 Apr 2017 13:30:23 +0200 Subject: [PATCH] Remap meta key to left alt on FreeBSD console --- ChangeLog | 6 +++ build.sh | 21 +++++++++- src/fterm.cpp | 102 +++++++++++++++++++++++++++++++++++++++++------ src/fterm.h | 22 +++++++--- src/fwidget.cpp | 2 +- test/termcap.cpp | 18 +++++++-- 6 files changed, 147 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7acb4a8a..649fc6cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-04-02 Markus Gans + * Remap the meta key to left alt key at runtime + on the FreeBSD console + (Console switching is still possible with + Ctrl-Alt-F1 through Ctrl-Alt-F8) + 2017-03-30 Markus Gans * Fixed bug: termcap "me" does not reset the alternate character set diff --git a/build.sh b/build.sh index 1ad3360e..5dd1c71a 100755 --- a/build.sh +++ b/build.sh @@ -3,6 +3,23 @@ #CXX="clang++" PREFIX="/usr" +# Get number of logical processor cores +if command -v getconf >/dev/null 2>&1 +then + CPU_COUNT="$(getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null)" || CPU_COUNT="0" +fi + +if [ "$CPU_COUNT" -eq 0 ] +then + if command -v nproc >/dev/null 2>&1 + then + CPU_COUNT="$(nproc 2>/dev/null)" || CPU_COUNT="0" + fi +fi + +test "$CPU_COUNT" -eq 0 && CPU_COUNT=1 + +# Build commands case "$1" in "--release"|"release") ./configure --prefix="$PREFIX" @@ -44,5 +61,7 @@ case "$1" in ;; esac -make V=1 -j10 +JOBS="$((CPU_COUNT/2))" +test "$JOBS" -eq 0 && JOBS=1 +make V=1 -j$JOBS # make install diff --git a/src/fterm.cpp b/src/fterm.cpp index db9faf1c..9a3cdeda 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -116,6 +116,7 @@ fc::consoleCursorStyle FTerm::console_cursor_style; unimapdesc FTerm::screen_unicode_map; #endif +uChar FTerm::bsd_alt_keymap = 0; //---------------------------------------------------------------------- // class FTerm @@ -1575,7 +1576,7 @@ int FTerm::UTF8decode (const char utf8[]) // protected methods of FTerm //---------------------------------------------------------------------- #if defined(__linux__) -void FTerm::init_consoleCharMap() +void FTerm::initLinuxConsoleCharMap() { uInt c1, c2, c3, c4, c5; @@ -1744,11 +1745,8 @@ int FTerm::isLinuxConsole() } #endif -//---------------------------------------------------------------------- -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) - #include #if defined(BSD) - +//---------------------------------------------------------------------- bool FTerm::isBSDConsole() { keymap_t keymap; @@ -1759,7 +1757,55 @@ bool FTerm::isBSDConsole() return false; } -#endif +//---------------------------------------------------------------------- +bool FTerm::saveBSDAltKey() +{ + keymap_t keymap; + int ret; + static const int left_alt = 0x38; + + ret = ioctl(0, GIO_KEYMAP, &keymap); + + if ( ret < 0 ) + return false; + + // save current mapping + bsd_alt_keymap = keymap.key[left_alt].map[0]; + return true; +} + +//---------------------------------------------------------------------- +bool FTerm::setBSDAltKey (uChar key) +{ + keymap_t keymap; + int ret; + static const int left_alt = 0x38; + + ret = ioctl(0, GIO_KEYMAP, &keymap); + + if ( ret < 0 ) + return false; + + // map to meta key + keymap.key[left_alt].map[0] = key; + + if ( (keymap.n_keys > 0) && (ioctl(0, PIO_KEYMAP, &keymap) < 0)) + return false; + else + return true; +} + +//---------------------------------------------------------------------- +bool FTerm::setBSDAlt2Meta() +{ + return setBSDAltKey (META); +} + +//---------------------------------------------------------------------- +bool FTerm::resetBSDAlt2Meta() +{ + return setBSDAltKey(bsd_alt_keymap); +} #endif #if defined(__linux__) @@ -2197,9 +2243,10 @@ int FTerm::setUnicodeMap (struct unimapdesc* unimap) } //---------------------------------------------------------------------- -void FTerm::init_console() +void FTerm::initLinuxConsole() { - // initialize terminal and Linux console + // initialize Linux console + fd_tty = -1; screen_unicode_map.entries = 0; screen_font.data = 0; @@ -2223,6 +2270,23 @@ void FTerm::init_console() } #endif +#if defined(BSD) +//---------------------------------------------------------------------- +void FTerm::initBSDConsole() +{ + // initialize BSD console + + if ( isBSDConsole() ) + { + // save current left alt key mapping + saveBSDAltKey(); + + // map meta key to left alt key + setBSDAlt2Meta(); + } +} +#endif + //---------------------------------------------------------------------- uInt FTerm::getBaudRate (const struct termios* termios_p) { @@ -3044,8 +3108,6 @@ void FTerm::init_termcaps() const_cast(CSI "29m"); } -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) - #include #if defined(BSD) if ( isBSDConsole() ) { @@ -3057,9 +3119,14 @@ void FTerm::init_termcaps() "q\304t\303u\264" "v\301w\302x\263" "y\363z\362~\371"); + tcap[fc::t_set_attributes].string = \ + const_cast(CSI "0%?%p1%p6%|" + "%t;1%;%?%p2%t;" + "4%;%?%p1%p3%|" + "%t;7%;%?%p4%t;" + "5%;m%?%p9%t\016%e\017%;"); FTermcap::attr_without_color = 18; } -#endif #endif // read termcap key strings @@ -3341,8 +3408,13 @@ void FTerm::init() term_name = ttyname(stdout_no); #if defined(__linux__) - // initialize terminal and Linux console - init_console(); + // initialize Linux console + initLinuxConsole(); +#endif + +#if defined(BSD) + // initialize BSD console + initBSDConsole(); #endif // save termios settings @@ -3682,6 +3754,10 @@ void FTerm::finish() } #endif +#if defined(BSD) + resetBSDAlt2Meta(); +#endif + if ( kde_konsole ) setKDECursor(fc::BlockCursor); diff --git a/src/fterm.h b/src/fterm.h index ead25017..f3e50fff 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -254,8 +254,9 @@ class FTerm protected: // Methods #if defined(__linux__) - static void init_consoleCharMap(); + static void initLinuxConsoleCharMap(); #endif + static bool charEncodable (uInt); static uInt charEncode (uInt); static uInt charEncode (uInt, fc::encoding); @@ -318,7 +319,14 @@ class FTerm #if defined(__linux__) static int isLinuxConsole(); #endif + +#if defined(BSD) static bool isBSDConsole(); + static bool saveBSDAltKey(); + static bool setBSDAltKey (uChar); + static bool setBSDAlt2Meta(); + static bool resetBSDAlt2Meta(); +#endif // Methods #if defined(__linux__) @@ -342,7 +350,11 @@ class FTerm static int setScreenFont (uChar*, uInt, uInt, uInt, bool = false); static int setUnicodeMap (struct unimapdesc*); static int getUnicodeMap (); - static void init_console(); + static void initLinuxConsole(); +#endif + +#if defined(BSD) + static void initBSDConsole(); #endif static uInt getBaudRate (const struct termios*); @@ -409,10 +421,10 @@ class FTerm static bool resize_term; static struct termios term_init; - static fc::consoleCursorStyle console_cursor_style; - static struct console_font_op screen_font; - static struct unimapdesc screen_unicode_map; + static struct console_font_op screen_font; + static struct unimapdesc screen_unicode_map; + static uChar bsd_alt_keymap; static FOptiMove* opti_move; static FOptiAttr* opti_attr; diff --git a/src/fwidget.cpp b/src/fwidget.cpp index 685cb4f1..476791b8 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -1160,7 +1160,7 @@ void FWidget::show() #if defined(__linux__) // Important: Do not use setNewFont() or setVGAFont() after // the console character mapping has been initialized - init_consoleCharMap(); + initLinuxConsoleCharMap(); #endif // set xterm underline cursor diff --git a/test/termcap.cpp b/test/termcap.cpp index 7aabc303..8890ad6e 100644 --- a/test/termcap.cpp +++ b/test/termcap.cpp @@ -1,6 +1,7 @@ // File: opti-move.cpp #include +#include #include "fapp.h" #include "ftermcap.h" #include "fvterm.h" @@ -51,18 +52,27 @@ void tcapString (std::string name, const char* cap_str) for (uInt i=0; i < len; i++) { - if ( cap_str[i] < 32 ) + uChar c = cap_str[i]; + + if ( c < 32 ) { - if ( cap_str[i] == 27 ) + if ( c == 27 ) sequence += "\\E"; else { sequence += '^'; - sequence += cap_str[i] + 64; + sequence += c + 64; } } + else if ( c >= 127 ) + { + std::ostringstream o; + o << std::oct << int(c); + sequence += "\\"; + sequence += o.str(); + } else - sequence += cap_str[i]; + sequence += c; } std::cout << sequence << " ";