From 75afbb58afa43db2037d2496920639bd4ce3b74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 24 Jun 2022 20:19:16 -0300 Subject: [PATCH] eterm: Refactor and fix. --- projects/linux/ee.creator.user | 11 +- projects/linux/ee.files | 4 +- src/tools/eterm/eterm.cpp | 8 +- src/tools/eterm/eterminaldisplay.cpp | 1171 ----------------- src/tools/eterm/eterminaldisplay.hpp | 215 --- src/tools/eterm/system/process.cpp | 20 +- ...rminaldisplay.cpp => iterminaldisplay.cpp} | 28 +- ...rminaldisplay.hpp => iterminaldisplay.hpp} | 14 +- src/tools/eterm/terminal/terminalemulator.cpp | 12 +- src/tools/eterm/terminal/terminalemulator.hpp | 10 +- 10 files changed, 54 insertions(+), 1439 deletions(-) delete mode 100644 src/tools/eterm/eterminaldisplay.cpp delete mode 100644 src/tools/eterm/eterminaldisplay.hpp rename src/tools/eterm/terminal/{terminaldisplay.cpp => iterminaldisplay.cpp} (70%) rename src/tools/eterm/terminal/{terminaldisplay.hpp => iterminaldisplay.hpp} (87%) diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 0aa551710..45225df9f 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -83,6 +83,7 @@ false true + 0 @@ -1518,14 +1519,6 @@ ProjectExplorer.Project.Updater.FileVersion 22 - - UserStickyKeys - - ProjectExplorer.Project.Target.1 - ProjectExplorer.Project.Target.1/ProjectExplorer.ProjectConfiguration.DefaultDisplayName - ProjectExplorer.Project.Target.1/ProjectExplorer.ProjectConfiguration.DisplayName - - Version 22 diff --git a/projects/linux/ee.files b/projects/linux/ee.files index 56ab07621..134f3221d 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -1133,8 +1133,6 @@ ../../src/tools/ecode/version.hpp ../../src/tools/ecode/widgetcommandexecuter.hpp ../../src/tools/eterm/eterm.cpp -../../src/tools/eterm/eterminaldisplay.cpp -../../src/tools/eterm/eterminaldisplay.hpp ../../src/tools/eterm/system/autohandle.cpp ../../src/tools/eterm/system/autohandle.hpp ../../src/tools/eterm/system/ipipe.hpp @@ -1149,6 +1147,8 @@ ../../src/tools/eterm/terminal/boxdraw.hpp ../../src/tools/eterm/terminal/boxdrawdata.hpp ../../src/tools/eterm/terminal/ipseudoterminal.hpp +../../src/tools/eterm/terminal/iterminaldisplay.cpp +../../src/tools/eterm/terminal/iterminaldisplay.hpp ../../src/tools/eterm/terminal/nonspacing.hpp ../../src/tools/eterm/terminal/pseudoterminal.cpp ../../src/tools/eterm/terminal/pseudoterminal.hpp diff --git a/src/tools/eterm/eterm.cpp b/src/tools/eterm/eterm.cpp index 817e2903d..3d26ccafe 100644 --- a/src/tools/eterm/eterm.cpp +++ b/src/tools/eterm/eterm.cpp @@ -1,8 +1,8 @@ -#include "eterminaldisplay.hpp" +#include "terminal/terminaldisplay.hpp" #include EE::Window::Window* win = NULL; -std::shared_ptr terminal = nullptr; +std::shared_ptr terminal = nullptr; void inputCallback( InputEvent* event ) { if ( !terminal ) @@ -101,8 +101,8 @@ EE_MAIN_FUNC int main( int, char*[] ) { shell = "/bin/bash"; } - terminal = ETerminalDisplay::create( win, fontMono, PixelDensity::dpToPx( 11 ), - win->getSize().asFloat(), shell, {}, "", 0 ); + terminal = TerminalDisplay::create( win, fontMono, PixelDensity::dpToPx( 11 ), + win->getSize().asFloat(), shell, {}, "" ); } win->getInput()->pushCallback( &inputCallback ); diff --git a/src/tools/eterm/eterminaldisplay.cpp b/src/tools/eterm/eterminaldisplay.cpp deleted file mode 100644 index 5bb66d424..000000000 --- a/src/tools/eterm/eterminaldisplay.cpp +++ /dev/null @@ -1,1171 +0,0 @@ -#include "eterminaldisplay.hpp" -#include "system/processfactory.hpp" -#include "terminal/boxdraw.hpp" -#include -#include -#include -#include -#include - -TerminalKeyMap::TerminalKeyMap( const TerminalKey keys[], size_t keysLen, - const TerminalScancode platformKeys[], size_t platformKeysLen, - const TerminalShortcut shortcuts[], size_t shortcutsLen ) { - for ( size_t i = 0; i < keysLen; i++ ) { - auto& e = m_keyMap[keys[i].keysym]; - e.push_back( { keys[i].mask, keys[i].string, keys[i].appkey, keys[i].appcursor } ); - } - - for ( size_t i = 0; i < platformKeysLen; i++ ) { - auto& e = m_platformKeyMap[platformKeys[i].scancode]; - e.push_back( { platformKeys[i].mask, platformKeys[i].string, platformKeys[i].appkey, - platformKeys[i].appcursor } ); - } - - for ( size_t i = 0; i < shortcutsLen; i++ ) { - auto& e = m_shortcuts[shortcuts[i].keysym]; - e.push_back( { shortcuts[i].mask, shortcuts[i].action, shortcuts[i].appkey, - shortcuts[i].appcursor } ); - } -} - -static TerminalShortcut shortcuts[] = { - { KEY_INSERT, KEYMOD_SHIFT, TerminalShortcutAction::PASTE, 0, 0 }, - { KEY_V, KEYMOD_SHIFT | KEYMOD_CTRL, TerminalShortcutAction::PASTE, 0, 0 }, - { KEY_C, KEYMOD_SHIFT | KEYMOD_CTRL, TerminalShortcutAction::COPY, 0, 0 } }; - -static TerminalKey keys[] = { - /* keysym mask string appkey appcursor */ - { KEY_KP_ENTER, KEYMOD_CTRL_SHIFT_ALT_META, "\033OM", +2, 0 }, - { KEY_KP_ENTER, KEYMOD_CTRL_SHIFT_ALT_META, "\r", -1, 0 }, - - { KEY_UP, KEYMOD_SHIFT, "\033[1;2A", 0, 0 }, - { KEY_UP, KEYMOD_LALT, "\033[1;3A", 0, 0 }, - { KEY_UP, KEYMOD_SHIFT | KEYMOD_LALT, "\033[1;4A", 0, 0 }, - { KEY_UP, KEYMOD_CTRL, "\033[1;5A", 0, 0 }, - { KEY_UP, KEYMOD_SHIFT | KEYMOD_CTRL, "\033[1;6A", 0, 0 }, - { KEY_UP, KEYMOD_CTRL | KEYMOD_LALT, "\033[1;7A", 0, 0 }, - { KEY_UP, KEYMOD_SHIFT | KEYMOD_CTRL | KEYMOD_LALT, "\033[1;8A", 0, 0 }, - { KEY_UP, KEYMOD_CTRL_SHIFT_ALT_META, "\033[A", 0, -1 }, - { KEY_UP, KEYMOD_CTRL_SHIFT_ALT_META, "\033OA", 0, +1 }, - { KEY_DOWN, KEYMOD_SHIFT, "\033[1;2B", 0, 0 }, - { KEY_DOWN, KEYMOD_LALT, "\033[1;3B", 0, 0 }, - { KEY_DOWN, KEYMOD_SHIFT | KEYMOD_LALT, "\033[1;4B", 0, 0 }, - { KEY_DOWN, KEYMOD_CTRL, "\033[1;5B", 0, 0 }, - { KEY_DOWN, KEYMOD_SHIFT | KEYMOD_CTRL, "\033[1;6B", 0, 0 }, - { KEY_DOWN, KEYMOD_CTRL | KEYMOD_LALT, "\033[1;7B", 0, 0 }, - { KEY_DOWN, KEYMOD_SHIFT | KEYMOD_CTRL | KEYMOD_LALT, "\033[1;8B", 0, 0 }, - { KEY_DOWN, KEYMOD_CTRL_SHIFT_ALT_META, "\033[B", 0, -1 }, - { KEY_DOWN, KEYMOD_CTRL_SHIFT_ALT_META, "\033OB", 0, +1 }, - { KEY_LEFT, KEYMOD_SHIFT, "\033[1;2D", 0, 0 }, - { KEY_LEFT, KEYMOD_LALT, "\033[1;3D", 0, 0 }, - { KEY_LEFT, KEYMOD_SHIFT | KEYMOD_LALT, "\033[1;4D", 0, 0 }, - { KEY_LEFT, KEYMOD_CTRL, "\033[1;5D", 0, 0 }, - { KEY_LEFT, KEYMOD_SHIFT | KEYMOD_CTRL, "\033[1;6D", 0, 0 }, - { KEY_LEFT, KEYMOD_CTRL | KEYMOD_LALT, "\033[1;7D", 0, 0 }, - { KEY_LEFT, KEYMOD_SHIFT | KEYMOD_CTRL | KEYMOD_LALT, "\033[1;8D", 0, 0 }, - { KEY_LEFT, KEYMOD_CTRL_SHIFT_ALT_META, "\033[D", 0, -1 }, - { KEY_LEFT, KEYMOD_CTRL_SHIFT_ALT_META, "\033OD", 0, +1 }, - { KEY_RIGHT, KEYMOD_SHIFT, "\033[1;2C", 0, 0 }, - { KEY_RIGHT, KEYMOD_LALT, "\033[1;3C", 0, 0 }, - { KEY_RIGHT, KEYMOD_SHIFT | KEYMOD_LALT, "\033[1;4C", 0, 0 }, - { KEY_RIGHT, KEYMOD_CTRL, "\033[1;5C", 0, 0 }, - { KEY_RIGHT, KEYMOD_SHIFT | KEYMOD_CTRL, "\033[1;6C", 0, 0 }, - { KEY_RIGHT, KEYMOD_CTRL | KEYMOD_LALT, "\033[1;7C", 0, 0 }, - { KEY_RIGHT, KEYMOD_SHIFT | KEYMOD_CTRL | KEYMOD_LALT, "\033[1;8C", 0, 0 }, - { KEY_RIGHT, KEYMOD_CTRL_SHIFT_ALT_META, "\033[C", 0, -1 }, - { KEY_RIGHT, KEYMOD_CTRL_SHIFT_ALT_META, "\033OC", 0, +1 }, - { KEY_TAB, KEYMOD_SHIFT, "\033[Z", 0, 0 }, - { KEY_TAB, KEYMOD_CTRL_SHIFT_ALT_META, "\t", 0, 0 }, - { KEY_RETURN, KEYMOD_LALT, "\033\r", 0, 0 }, - { KEY_RETURN, KEYMOD_CTRL_SHIFT_ALT_META, "\r", 0, 0 }, - { KEY_INSERT, KEYMOD_SHIFT, "\033[4l", -1, 0 }, - { KEY_INSERT, KEYMOD_SHIFT, "\033[2;2~", +1, 0 }, - { KEY_INSERT, KEYMOD_CTRL, "\033[L", -1, 0 }, - { KEY_INSERT, KEYMOD_CTRL, "\033[2;5~", +1, 0 }, - { KEY_INSERT, KEYMOD_CTRL_SHIFT_ALT_META, "\033[4h", -1, 0 }, - { KEY_INSERT, KEYMOD_CTRL_SHIFT_ALT_META, "\033[2~", +1, 0 }, - { KEY_DELETE, KEYMOD_CTRL, "\033[M", -1, 0 }, - { KEY_DELETE, KEYMOD_CTRL, "\033[3;5~", +1, 0 }, - { KEY_DELETE, KEYMOD_SHIFT, "\033[2K", -1, 0 }, - { KEY_DELETE, KEYMOD_SHIFT, "\033[3;2~", +1, 0 }, - { KEY_DELETE, KEYMOD_CTRL_SHIFT_ALT_META, "\033[P", -1, 0 }, - { KEY_DELETE, KEYMOD_CTRL_SHIFT_ALT_META, "\033[3~", +1, 0 }, - { KEY_BACKSPACE, KEYMOD_NONE, "\177", 0, 0 }, - { KEY_BACKSPACE, KEYMOD_LALT, "\033\177", 0, 0 }, - { KEY_HOME, KEYMOD_SHIFT, "\033[2J", 0, -1 }, - { KEY_HOME, KEYMOD_SHIFT, "\033[1;2H", 0, +1 }, - { KEY_HOME, KEYMOD_CTRL_SHIFT_ALT_META, "\033[H", 0, -1 }, - { KEY_HOME, KEYMOD_CTRL_SHIFT_ALT_META, "\033[1~", 0, +1 }, - { KEY_END, KEYMOD_CTRL, "\033[J", -1, 0 }, - { KEY_END, KEYMOD_CTRL, "\033[1;5F", +1, 0 }, - { KEY_END, KEYMOD_SHIFT, "\033[K", -1, 0 }, - { KEY_END, KEYMOD_SHIFT, "\033[1;2F", +1, 0 }, - { KEY_END, KEYMOD_CTRL_SHIFT_ALT_META, "\033[4~", 0, 0 }, - { KEY_ESCAPE, KEYMOD_CTRL_SHIFT_ALT_META, "\033", 0, 0 }, - - { KEY_PAGEUP, KEYMOD_NONE, "\033[5~", 0, 0 }, - { KEY_PAGEDOWN, KEYMOD_NONE, "\033[6~", 0, 0 }, -}; - -static TerminalScancode platformKeys[] = { - { SCANCODE_PRIOR, KEYMOD_CTRL, "\033[5;5~", 0, 0 }, - - { SCANCODE_PRIOR, KEYMOD_CTRL, "\033[5;5~", 0, 0 }, - { SCANCODE_PRIOR, KEYMOD_SHIFT, "\033[5;2~", 0, 0 }, - { SCANCODE_PRIOR, KEYMOD_CTRL_SHIFT_ALT_META, "\033[5~", 0, 0 }, - - { SCANCODE_KP_BACKSPACE, KEYMOD_CTRL, "\033[M", -1, 0 }, - { SCANCODE_KP_BACKSPACE, KEYMOD_CTRL, "\033[3;5~", +1, 0 }, - { SCANCODE_KP_BACKSPACE, KEYMOD_SHIFT, "\033[2K", -1, 0 }, - { SCANCODE_KP_BACKSPACE, KEYMOD_SHIFT, "\033[3;2~", +1, 0 }, - { SCANCODE_KP_BACKSPACE, KEYMOD_CTRL_SHIFT_ALT_META, "\033[P", -1, 0 }, - { SCANCODE_KP_BACKSPACE, KEYMOD_CTRL_SHIFT_ALT_META, "\033[3~", +1, 0 }, - - { SCANCODE_KP_MINUS, KEYMOD_CTRL_SHIFT_ALT_META, "\033Om", +2, 0 }, - { SCANCODE_KP_DECIMAL, KEYMOD_CTRL_SHIFT_ALT_META, "\033On", +2, 0 }, - { SCANCODE_KP_DIVIDE, KEYMOD_CTRL_SHIFT_ALT_META, "\033Oo", +2, 0 }, - { SCANCODE_KP_MULTIPLY, KEYMOD_CTRL_SHIFT_ALT_META, "\033Oj", +2, 0 }, - { SCANCODE_KP_PLUS, KEYMOD_CTRL_SHIFT_ALT_META, "\033Ok", +2, 0 }, - - { SCANCODE_F1, KEYMOD_NONE, "\033OP", 0, 0 }, - { SCANCODE_F1, /* F13 */ KEYMOD_SHIFT, "\033[1;2P", 0, 0 }, - { SCANCODE_F1, /* F25 */ KEYMOD_CTRL, "\033[1;5P", 0, 0 }, - { SCANCODE_F1, /* F37 */ KEYMOD_META, "\033[1;6P", 0, 0 }, - { SCANCODE_F1, /* F49 */ KEYMOD_LALT, "\033[1;3P", 0, 0 }, - { SCANCODE_F1, /* F61 */ KEYMOD_RALT, "\033[1;4P", 0, 0 }, - { SCANCODE_F2, KEYMOD_NONE, "\033OQ", 0, 0 }, - { SCANCODE_F2, /* F14 */ KEYMOD_SHIFT, "\033[1;2Q", 0, 0 }, - { SCANCODE_F2, /* F26 */ KEYMOD_CTRL, "\033[1;5Q", 0, 0 }, - { SCANCODE_F2, /* F38 */ KEYMOD_META, "\033[1;6Q", 0, 0 }, - { SCANCODE_F2, /* F50 */ KEYMOD_LALT, "\033[1;3Q", 0, 0 }, - { SCANCODE_F2, /* F62 */ KEYMOD_RALT, "\033[1;4Q", 0, 0 }, - { SCANCODE_F3, KEYMOD_NONE, "\033OR", 0, 0 }, - { SCANCODE_F3, /* F15 */ KEYMOD_SHIFT, "\033[1;2R", 0, 0 }, - { SCANCODE_F3, /* F27 */ KEYMOD_CTRL, "\033[1;5R", 0, 0 }, - { SCANCODE_F3, /* F39 */ KEYMOD_META, "\033[1;6R", 0, 0 }, - { SCANCODE_F3, /* F51 */ KEYMOD_LALT, "\033[1;3R", 0, 0 }, - { SCANCODE_F3, /* F63 */ KEYMOD_RALT, "\033[1;4R", 0, 0 }, - { SCANCODE_F4, KEYMOD_NONE, "\033OS", 0, 0 }, - { SCANCODE_F4, /* F16 */ KEYMOD_SHIFT, "\033[1;2S", 0, 0 }, - { SCANCODE_F4, /* F28 */ KEYMOD_CTRL, "\033[1;5S", 0, 0 }, - { SCANCODE_F4, /* F40 */ KEYMOD_META, "\033[1;6S", 0, 0 }, - { SCANCODE_F4, /* F52 */ KEYMOD_LALT, "\033[1;3S", 0, 0 }, - { SCANCODE_F5, KEYMOD_NONE, "\033[15~", 0, 0 }, - { SCANCODE_F5, /* F17 */ KEYMOD_SHIFT, "\033[15;2~", 0, 0 }, - { SCANCODE_F5, /* F29 */ KEYMOD_CTRL, "\033[15;5~", 0, 0 }, - { SCANCODE_F5, /* F41 */ KEYMOD_META, "\033[15;6~", 0, 0 }, - { SCANCODE_F5, /* F53 */ KEYMOD_LALT, "\033[15;3~", 0, 0 }, - { SCANCODE_F6, KEYMOD_NONE, "\033[17~", 0, 0 }, - { SCANCODE_F6, /* F18 */ KEYMOD_SHIFT, "\033[17;2~", 0, 0 }, - { SCANCODE_F6, /* F30 */ KEYMOD_CTRL, "\033[17;5~", 0, 0 }, - { SCANCODE_F6, /* F42 */ KEYMOD_META, "\033[17;6~", 0, 0 }, - { SCANCODE_F6, /* F54 */ KEYMOD_LALT, "\033[17;3~", 0, 0 }, - { SCANCODE_F7, KEYMOD_NONE, "\033[18~", 0, 0 }, - { SCANCODE_F7, /* F19 */ KEYMOD_SHIFT, "\033[18;2~", 0, 0 }, - { SCANCODE_F7, /* F31 */ KEYMOD_CTRL, "\033[18;5~", 0, 0 }, - { SCANCODE_F7, /* F43 */ KEYMOD_META, "\033[18;6~", 0, 0 }, - { SCANCODE_F7, /* F55 */ KEYMOD_LALT, "\033[18;3~", 0, 0 }, - { SCANCODE_F8, KEYMOD_NONE, "\033[19~", 0, 0 }, - { SCANCODE_F8, /* F20 */ KEYMOD_SHIFT, "\033[19;2~", 0, 0 }, - { SCANCODE_F8, /* F32 */ KEYMOD_CTRL, "\033[19;5~", 0, 0 }, - { SCANCODE_F8, /* F44 */ KEYMOD_META, "\033[19;6~", 0, 0 }, - { SCANCODE_F8, /* F56 */ KEYMOD_LALT, "\033[19;3~", 0, 0 }, - { SCANCODE_F9, KEYMOD_NONE, "\033[20~", 0, 0 }, - { SCANCODE_F9, /* F21 */ KEYMOD_SHIFT, "\033[20;2~", 0, 0 }, - { SCANCODE_F9, /* F33 */ KEYMOD_CTRL, "\033[20;5~", 0, 0 }, - { SCANCODE_F9, /* F45 */ KEYMOD_META, "\033[20;6~", 0, 0 }, - { SCANCODE_F9, /* F57 */ KEYMOD_LALT, "\033[20;3~", 0, 0 }, - { SCANCODE_F10, KEYMOD_NONE, "\033[21~", 0, 0 }, - { SCANCODE_F10, /* F22 */ KEYMOD_SHIFT, "\033[21;2~", 0, 0 }, - { SCANCODE_F10, /* F34 */ KEYMOD_CTRL, "\033[21;5~", 0, 0 }, - { SCANCODE_F10, /* F46 */ KEYMOD_META, "\033[21;6~", 0, 0 }, - { SCANCODE_F10, /* F58 */ KEYMOD_LALT, "\033[21;3~", 0, 0 }, - { SCANCODE_F11, KEYMOD_NONE, "\033[23~", 0, 0 }, - { SCANCODE_F11, /* F23 */ KEYMOD_SHIFT, "\033[23;2~", 0, 0 }, - { SCANCODE_F11, /* F35 */ KEYMOD_CTRL, "\033[23;5~", 0, 0 }, - { SCANCODE_F11, /* F47 */ KEYMOD_META, "\033[23;6~", 0, 0 }, - { SCANCODE_F11, /* F59 */ KEYMOD_LALT, "\033[23;3~", 0, 0 }, - { SCANCODE_F12, KEYMOD_NONE, "\033[24~", 0, 0 }, - { SCANCODE_F12, /* F24 */ KEYMOD_SHIFT, "\033[24;2~", 0, 0 }, - { SCANCODE_F12, /* F36 */ KEYMOD_CTRL, "\033[24;5~", 0, 0 }, - { SCANCODE_F12, /* F48 */ KEYMOD_META, "\033[24;6~", 0, 0 }, - { SCANCODE_F12, /* F60 */ KEYMOD_LALT, "\033[24;3~", 0, 0 }, - { SCANCODE_F13, KEYMOD_NONE, "\033[1;2P", 0, 0 }, - { SCANCODE_F14, KEYMOD_NONE, "\033[1;2Q", 0, 0 }, - { SCANCODE_F15, KEYMOD_NONE, "\033[1;2R", 0, 0 }, - { SCANCODE_F16, KEYMOD_NONE, "\033[1;2S", 0, 0 }, - { SCANCODE_F17, KEYMOD_NONE, "\033[15;2~", 0, 0 }, - { SCANCODE_F18, KEYMOD_NONE, "\033[17;2~", 0, 0 }, - { SCANCODE_F19, KEYMOD_NONE, "\033[18;2~", 0, 0 }, - { SCANCODE_F20, KEYMOD_NONE, "\033[19;2~", 0, 0 }, - { SCANCODE_F21, KEYMOD_NONE, "\033[20;2~", 0, 0 }, - { SCANCODE_F22, KEYMOD_NONE, "\033[21;2~", 0, 0 }, - { SCANCODE_F23, KEYMOD_NONE, "\033[23;2~", 0, 0 }, - { SCANCODE_F24, KEYMOD_NONE, "\033[24;2~", 0, 0 }, - - { SCANCODE_KP_0, KEYMOD_CTRL_SHIFT_ALT_META, "\033Op", +2, 0 }, - { SCANCODE_KP_1, KEYMOD_CTRL_SHIFT_ALT_META, "\033Oq", +2, 0 }, - { SCANCODE_KP_2, KEYMOD_CTRL_SHIFT_ALT_META, "\033Or", +2, 0 }, - { SCANCODE_KP_3, KEYMOD_CTRL_SHIFT_ALT_META, "\033Os", +2, 0 }, - { SCANCODE_KP_4, KEYMOD_CTRL_SHIFT_ALT_META, "\033Ot", +2, 0 }, - { SCANCODE_KP_5, KEYMOD_CTRL_SHIFT_ALT_META, "\033Ou", +2, 0 }, - { SCANCODE_KP_6, KEYMOD_CTRL_SHIFT_ALT_META, "\033Ov", +2, 0 }, - { SCANCODE_KP_7, KEYMOD_CTRL_SHIFT_ALT_META, "\033Ow", +2, 0 }, - { SCANCODE_KP_8, KEYMOD_CTRL_SHIFT_ALT_META, "\033Ox", +2, 0 }, - { SCANCODE_KP_9, KEYMOD_CTRL_SHIFT_ALT_META, "\033Oy", +2, 0 } }; - -TerminalKeyMap terminalKeyMap{ keys, eeARRAY_SIZE( keys ), - platformKeys, eeARRAY_SIZE( platformKeys ), - shortcuts, eeARRAY_SIZE( shortcuts ) }; - -/* Terminal colors (16 first used in escape sequence) */ -// This is the customizable colorscheme -const char* colornames[256] = { "#1e2127", "#e06c75", "#98c379", "#d19a66", "#61afef", "#c678dd", - "#56b6c2", "#abb2bf", "#5c6370", "#e06c75", "#98c379", "#d19a66", - "#61afef", "#c678dd", "#56b6c2", "#ffffff", "#1e2127", "#abb2bf" }; - -// This is the default Xterm palette -static const Color colormapped[256] = { - Color( 0, 0, 0 ), Color( 128, 0, 0 ), Color( 0, 128, 0 ), - Color( 128, 128, 0 ), Color( 0, 0, 128 ), Color( 128, 0, 128 ), - Color( 0, 128, 128 ), Color( 192, 192, 192 ), Color( 128, 128, 128 ), - Color( 255, 0, 0 ), Color( 0, 255, 0 ), Color( 255, 255, 0 ), - Color( 0, 0, 255 ), Color( 255, 0, 255 ), Color( 0, 255, 255 ), - Color( 255, 255, 255 ), Color( 0, 0, 0 ), Color( 0, 0, 95 ), - Color( 0, 0, 135 ), Color( 0, 0, 175 ), Color( 0, 0, 215 ), - Color( 0, 0, 255 ), Color( 0, 95, 0 ), Color( 0, 95, 95 ), - Color( 0, 95, 135 ), Color( 0, 95, 175 ), Color( 0, 95, 215 ), - Color( 0, 95, 255 ), Color( 0, 135, 0 ), Color( 0, 135, 95 ), - Color( 0, 135, 135 ), Color( 0, 135, 175 ), Color( 0, 135, 215 ), - Color( 0, 135, 255 ), Color( 0, 175, 0 ), Color( 0, 175, 95 ), - Color( 0, 175, 135 ), Color( 0, 175, 175 ), Color( 0, 175, 215 ), - Color( 0, 175, 255 ), Color( 0, 215, 0 ), Color( 0, 215, 95 ), - Color( 0, 215, 135 ), Color( 0, 215, 175 ), Color( 0, 215, 215 ), - Color( 0, 215, 255 ), Color( 0, 255, 0 ), Color( 0, 255, 95 ), - Color( 0, 255, 135 ), Color( 0, 255, 175 ), Color( 0, 255, 215 ), - Color( 0, 255, 255 ), Color( 95, 0, 0 ), Color( 95, 0, 95 ), - Color( 95, 0, 135 ), Color( 95, 0, 175 ), Color( 95, 0, 215 ), - Color( 95, 0, 255 ), Color( 95, 95, 0 ), Color( 95, 95, 95 ), - Color( 95, 95, 135 ), Color( 95, 95, 175 ), Color( 95, 95, 215 ), - Color( 95, 95, 255 ), Color( 95, 135, 0 ), Color( 95, 135, 95 ), - Color( 95, 135, 135 ), Color( 95, 135, 175 ), Color( 95, 135, 215 ), - Color( 95, 135, 255 ), Color( 95, 175, 0 ), Color( 95, 175, 95 ), - Color( 95, 175, 135 ), Color( 95, 175, 175 ), Color( 95, 175, 215 ), - Color( 95, 175, 255 ), Color( 95, 215, 0 ), Color( 95, 215, 95 ), - Color( 95, 215, 135 ), Color( 95, 215, 175 ), Color( 95, 215, 215 ), - Color( 95, 215, 255 ), Color( 95, 255, 0 ), Color( 95, 255, 95 ), - Color( 95, 255, 135 ), Color( 95, 255, 175 ), Color( 95, 255, 215 ), - Color( 95, 255, 255 ), Color( 135, 0, 0 ), Color( 135, 0, 95 ), - Color( 135, 0, 135 ), Color( 135, 0, 175 ), Color( 135, 0, 215 ), - Color( 135, 0, 255 ), Color( 135, 95, 0 ), Color( 135, 95, 95 ), - Color( 135, 95, 135 ), Color( 135, 95, 175 ), Color( 135, 95, 215 ), - Color( 135, 95, 255 ), Color( 135, 135, 0 ), Color( 135, 135, 95 ), - Color( 135, 135, 135 ), Color( 135, 135, 175 ), Color( 135, 135, 215 ), - Color( 135, 135, 255 ), Color( 135, 175, 0 ), Color( 135, 175, 95 ), - Color( 135, 175, 135 ), Color( 135, 175, 175 ), Color( 135, 175, 215 ), - Color( 135, 175, 255 ), Color( 135, 215, 0 ), Color( 135, 215, 95 ), - Color( 135, 215, 135 ), Color( 135, 215, 175 ), Color( 135, 215, 215 ), - Color( 135, 215, 255 ), Color( 135, 255, 0 ), Color( 135, 255, 95 ), - Color( 135, 255, 135 ), Color( 135, 255, 175 ), Color( 135, 255, 215 ), - Color( 135, 255, 255 ), Color( 175, 0, 0 ), Color( 175, 0, 95 ), - Color( 175, 0, 135 ), Color( 175, 0, 175 ), Color( 175, 0, 215 ), - Color( 175, 0, 255 ), Color( 175, 95, 0 ), Color( 175, 95, 95 ), - Color( 175, 95, 135 ), Color( 175, 95, 175 ), Color( 175, 95, 215 ), - Color( 175, 95, 255 ), Color( 175, 135, 0 ), Color( 175, 135, 95 ), - Color( 175, 135, 135 ), Color( 175, 135, 175 ), Color( 175, 135, 215 ), - Color( 175, 135, 255 ), Color( 175, 175, 0 ), Color( 175, 175, 95 ), - Color( 175, 175, 135 ), Color( 175, 175, 175 ), Color( 175, 175, 215 ), - Color( 175, 175, 255 ), Color( 175, 215, 0 ), Color( 175, 215, 95 ), - Color( 175, 215, 135 ), Color( 175, 215, 175 ), Color( 175, 215, 215 ), - Color( 175, 215, 255 ), Color( 175, 255, 0 ), Color( 175, 255, 95 ), - Color( 175, 255, 135 ), Color( 175, 255, 175 ), Color( 175, 255, 215 ), - Color( 175, 255, 255 ), Color( 215, 0, 0 ), Color( 215, 0, 95 ), - Color( 215, 0, 135 ), Color( 215, 0, 175 ), Color( 215, 0, 215 ), - Color( 215, 0, 255 ), Color( 215, 95, 0 ), Color( 215, 95, 95 ), - Color( 215, 95, 135 ), Color( 215, 95, 175 ), Color( 215, 95, 215 ), - Color( 215, 95, 255 ), Color( 215, 135, 0 ), Color( 215, 135, 95 ), - Color( 215, 135, 135 ), Color( 215, 135, 175 ), Color( 215, 135, 215 ), - Color( 215, 135, 255 ), Color( 215, 175, 0 ), Color( 215, 175, 95 ), - Color( 215, 175, 135 ), Color( 215, 175, 175 ), Color( 215, 175, 215 ), - Color( 215, 175, 255 ), Color( 215, 215, 0 ), Color( 215, 215, 95 ), - Color( 215, 215, 135 ), Color( 215, 215, 175 ), Color( 215, 215, 215 ), - Color( 215, 215, 255 ), Color( 215, 255, 0 ), Color( 215, 255, 95 ), - Color( 215, 255, 135 ), Color( 215, 255, 175 ), Color( 215, 255, 215 ), - Color( 215, 255, 255 ), Color( 255, 0, 0 ), Color( 255, 0, 95 ), - Color( 255, 0, 135 ), Color( 255, 0, 175 ), Color( 255, 0, 215 ), - Color( 255, 0, 255 ), Color( 255, 95, 0 ), Color( 255, 95, 95 ), - Color( 255, 95, 135 ), Color( 255, 95, 175 ), Color( 255, 95, 215 ), - Color( 255, 95, 255 ), Color( 255, 135, 0 ), Color( 255, 135, 95 ), - Color( 255, 135, 135 ), Color( 255, 135, 175 ), Color( 255, 135, 215 ), - Color( 255, 135, 255 ), Color( 255, 175, 0 ), Color( 255, 175, 95 ), - Color( 255, 175, 135 ), Color( 255, 175, 175 ), Color( 255, 175, 215 ), - Color( 255, 175, 255 ), Color( 255, 215, 0 ), Color( 255, 215, 95 ), - Color( 255, 215, 135 ), Color( 255, 215, 175 ), Color( 255, 215, 215 ), - Color( 255, 215, 255 ), Color( 255, 255, 0 ), Color( 255, 255, 95 ), - Color( 255, 255, 135 ), Color( 255, 255, 175 ), Color( 255, 255, 215 ), - Color( 255, 255, 255 ), Color( 8, 8, 8 ), Color( 18, 18, 18 ), - Color( 28, 28, 28 ), Color( 38, 38, 38 ), Color( 48, 48, 48 ), - Color( 58, 58, 58 ), Color( 68, 68, 68 ), Color( 78, 78, 78 ), - Color( 88, 88, 88 ), Color( 98, 98, 98 ), Color( 108, 108, 108 ), - Color( 118, 118, 118 ), Color( 128, 128, 128 ), Color( 138, 138, 138 ), - Color( 148, 148, 148 ), Color( 158, 158, 158 ), Color( 168, 168, 168 ), - Color( 178, 178, 178 ), Color( 188, 188, 188 ), Color( 198, 198, 198 ), - Color( 208, 208, 208 ), Color( 218, 218, 218 ), Color( 228, 228, 228 ), - Color( 238, 238, 238 ) }; - -std::shared_ptr ETerminalDisplay::create( - EE::Window::Window* window, Font* font, const Float& fontSize, const Sizef& pixelsSize, - std::shared_ptr&& terminalEmulator, TerminalConfig* config ) { - std::shared_ptr terminal = std::shared_ptr( - new ETerminalDisplay( window, font, fontSize, pixelsSize, config ) ); - terminal->mTerminal = std::move( terminalEmulator ); - return terminal; -} - -static EE::System::IProcessFactory* g_processFactory = new EE::System::ProcessFactory(); - -static Sizei gridSizeFromTermDimensions( Font* font, const Float& fontSize, - const Sizef& pixelsSize ) { - auto fontHeight = (Float)font->getFontHeight( fontSize ); - auto spaceCharAdvanceX = font->getGlyph( 'A', fontSize, false ).advance; - auto clipColumns = - (int)std::floor( std::max( 1.0f, pixelsSize.getWidth() / spaceCharAdvanceX ) ); - auto clipRows = (int)std::floor( std::max( 1.0f, pixelsSize.getHeight() / fontHeight ) ); - return { clipColumns, clipRows }; -} - -std::shared_ptr -ETerminalDisplay::create( EE::Window::Window* window, Font* font, const Float& fontSize, - const Sizef& pixelsSize, const std::string& program, - const std::vector& args, const std::string& workingDir, - uint32_t options, EE::System::IProcessFactory* processFactory ) { - using namespace EE::System; - - TerminalConfig config{}; - config.options = options; - - if ( processFactory == nullptr ) { - processFactory = g_processFactory; - } - - Sizei termSize( gridSizeFromTermDimensions( font, fontSize, pixelsSize ) ); - std::unique_ptr pseudoTerminal = nullptr; - std::vector argsV( args.begin(), args.end() ); - auto process = processFactory->createWithPseudoTerminal( - program, argsV, workingDir, termSize.getWidth(), termSize.getHeight(), pseudoTerminal ); - - if ( !pseudoTerminal ) { - fprintf( stderr, "Failed to create pseudo terminal\n" ); - return nullptr; - } - - if ( !process ) { - fprintf( stderr, "Failed to spawn process\n" ); - return nullptr; - } - - std::shared_ptr terminal = std::shared_ptr( - new ETerminalDisplay( window, font, fontSize, pixelsSize, &config ) ); - - terminal->mTerminal = - TerminalEmulator::create( std::move( pseudoTerminal ), std::move( process ), terminal ); - return terminal; -} - -ETerminalDisplay::ETerminalDisplay( EE::Window::Window* window, Font* font, const Float& fontSize, - const Sizef& pixelsSize, TerminalConfig* config ) : - TerminalDisplay(), - mWindow( window ), - mFont( font ), - mFontSize( fontSize ), - mSize( pixelsSize ) { - - if ( config != nullptr ) { - if ( config->options & OPTION_COLOR_EMOJI ) - mUseColorEmoji = true; - if ( config->options & OPTION_PASTE_CRLF ) - mPasteNewlineFix = true; - } - - TerminalGlyph defaultGlyph; - defaultGlyph.mode = ATTR_INVISIBLE; - auto defaultColor = std::make_pair( 0U, "" ); - mCursorGlyph = defaultGlyph; - mColors.resize( eeARRAY_SIZE( colornames ), defaultColor ); - mBuffer.resize( mColumns * mRows, defaultGlyph ); - ( (int&)mMode ) |= MODE_FOCUSED; - - if ( config != nullptr ) { - if ( config->options & OPTION_COLOR_EMOJI ) - mUseColorEmoji = true; - if ( config->options & OPTION_PASTE_CRLF ) - mPasteNewlineFix = true; - } -} - -void ETerminalDisplay::resetColors() { - for ( Uint32 i = 0; i < eeARRAY_SIZE( colornames ); i++ ) { - resetColor( i, colornames[i] ); - } -} - -int ETerminalDisplay::resetColor( int index, const char* name ) { - if ( !name ) { - if ( index >= 0 && index < (int)mColors.size() ) { - Color col = 0x000000FF; - - if ( index < 256 ) - col = colormapped[index]; - - mColors[index].first = col; - mColors[index].second = ""; - return 0; - } - } - - if ( index >= 0 && index < (int)mColors.size() ) { - mColors[index].first = Color::fromString( name ); - mColors[index].second = name; - } - - return 1; -} - -bool ETerminalDisplay::isBlinkingCursor() { - return mCursorMode == EE::Terminal::BlinkingBlock || - mCursorMode == EE::Terminal::BlinkingBlockDefault || - mCursorMode == EE::Terminal::BlinkUnderline || mCursorMode == EE::Terminal::BlinkBar; -} - -void ETerminalDisplay::update() { - if ( mFocus && isBlinkingCursor() && mClock.getElapsedTime().asSeconds() > 0.7 ) { - mMode ^= MODE_BLINK; - mClock.restart(); - invalidate(); - } - if ( mTerminal ) - mTerminal->update(); -} - -void ETerminalDisplay::action( TerminalShortcutAction action ) { - switch ( action ) { - case TerminalShortcutAction::PASTE: { - auto clipboard = getClipboard(); - auto clipboardLen = strlen( clipboard ); - if ( clipboardLen > 0 ) { - mTerminal->write( clipboard, clipboardLen ); - } - break; - } - case TerminalShortcutAction::COPY: { - auto selection = mTerminal->getSelection(); - if ( !selection.empty() ) - setClipboard( selection.c_str() ); - break; - } - } -} - -bool ETerminalDisplay::hasTerminated() const { - return mTerminal->hasExited(); -} - -void ETerminalDisplay::setTitle( const char* ) {} - -void ETerminalDisplay::setIconTitle( const char* ) {} - -void ETerminalDisplay::setClipboard( const char* text ) { - if ( text == nullptr ) - return; - mClipboard = text; - mWindow->getClipboard()->setText( mClipboard ); -} - -const char* ETerminalDisplay::getClipboard() const { - mClipboard = mWindow->getClipboard()->getText(); -#ifdef _WIN32 - if ( mPasteNewlineFix ) { - size_t pos; - while ( ( pos = mClipboard.find( '\r' ) ) != std::string::npos ) - mClipboard.erase( pos, 1 ); - return mClipboard.c_str(); - } -#endif - return mClipboard.c_str(); -} - -bool ETerminalDisplay::drawBegin( int columns, int rows ) { - if ( columns != mColumns || rows != mRows ) { - TerminalGlyph defaultGlyph{}; - mBuffer.resize( columns * rows, defaultGlyph ); - mColumns = columns; - mRows = rows; - invalidate(); - } - - return ( ( mMode & MODE_VISIBLE ) != 0 ); -} - -void ETerminalDisplay::drawLine( Line line, int x1, int y, int x2 ) { - memcpy( &mBuffer[y * mColumns + x1], line, ( x2 - x1 ) * sizeof( TerminalGlyph ) ); - for ( int i = x1; i < x2; i++ ) { - if ( mTerminal->selected( i, y ) ) { - mBuffer[y * mColumns + i].mode |= ATTR_REVERSE; - } - } - invalidate(); -} - -void ETerminalDisplay::drawCursor( int cx, int cy, TerminalGlyph g, int, int, TerminalGlyph ) { - if ( mCursor != Vector2i( cx, cy ) || mCursorGlyph != g ) { - mCursor.x = cx; - mCursor.y = cy; - mCursorGlyph = g; - invalidate(); - } -} - -void ETerminalDisplay::drawEnd() {} - -void ETerminalDisplay::draw() { - draw( mPosition ); -} - -void ETerminalDisplay::onMouseDoubleClick( const Vector2i& pos, const Uint32& flags ) { - if ( flags & EE_BUTTON_LMASK ) - mLastDoubleClick.restart(); - - if ( ( flags & EE_BUTTON_LMASK ) && - ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_EMPTY || - mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) ) { - auto gridPos{ positionToGrid( pos ) }; - mTerminal->selstart( gridPos.x, gridPos.y, SNAP_WORD ); - invalidate(); - } -} - -void ETerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags ) { - if ( ( flags & EE_BUTTON_LMASK ) && - ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_EMPTY || - mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_READY ) ) { - auto gridPos{ positionToGrid( pos ) }; - mTerminal->selextend( - gridPos.x, gridPos.y, - mWindow->getInput()->getModState() & KEYMOD_SHIFT ? SEL_RECTANGULAR : SEL_REGULAR, 0 ); - invalidate(); - } - mTerminal->mousereport( TerminalMouseEventType::MouseMotion, positionToGrid( pos ), flags, - mWindow->getInput()->getModState() ); -} - -void ETerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) { - auto gridPos{ positionToGrid( pos ) }; - if ( ( flags & EE_BUTTON_LMASK ) && - mLastDoubleClick.getElapsedTime() < Milliseconds( 300.f ) ) { - mTerminal->selstart( gridPos.x, gridPos.y, SNAP_LINE ); - } else if ( flags & EE_BUTTON_LMASK ) { - if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) { - auto gridPos{ positionToGrid( pos ) }; - mTerminal->selstart( gridPos.x, gridPos.y, 0 ); - invalidate(); - } else if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_READY ) { - mTerminal->selclear(); - } - } else if ( flags & EE_BUTTON_MMASK ) { - auto selection = mTerminal->getSelection(); - if ( !selection.empty() ) { - for ( auto& chr : selection ) - onTextInput( chr ); - } - } - mTerminal->mousereport( TerminalMouseEventType::MouseButtonDown, positionToGrid( pos ), flags, - mWindow->getInput()->getModState() ); -} - -void ETerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) { - if ( ( flags & EE_BUTTON_LMASK ) ) { - auto selection = mTerminal->getSelection(); - if ( !selection.empty() && selection != "\n" ) - setClipboard( selection.c_str() ); - invalidate(); - } - mTerminal->mousereport( TerminalMouseEventType::MouseButtonRelease, positionToGrid( pos ), - flags, mWindow->getInput()->getModState() ); -} - -static inline Color termColor( unsigned int terminalColor, - const std::vector>& colors ) { - if ( ( terminalColor & ( 1 << 24 ) ) == 0 ) { - return colors[terminalColor & 0xFF].first; - } - return Color( ( terminalColor >> 16 ) & 0xFF, ( terminalColor >> 8 ) & 0xFF, - terminalColor & 0xFF, ( ~( ( terminalColor >> 25 ) & 0xFF ) ) & 0xFF ); -} - -Float ETerminalDisplay::getYOffset() const { - auto fontSize = (Float)mFont->getFontHeight( mFontSize ); - auto height = mRows * fontSize; - float y = 0; - if ( height < mSize.getHeight() ) - y = std::floor( mPosition.y + ( ( mSize.getHeight() - height ) / 2.0f ) ); - return y; -} - -#define BETWEEN( x, a, b ) ( ( a ) <= ( x ) && ( x ) <= ( b ) ) -#define IS_SET( flag ) ( ( mMode & ( flag ) ) != 0 ) -#define DIV( n, d ) ( ( ( n ) + ( d ) / 2.0f ) / ( d ) ) -#define DIVI( n, d ) ( ( ( n ) + ( d ) / 2 ) / ( d ) ) - -inline static void drawrect( const Color& col, const float& x, const float& y, const float& w, - const float& h, Primitives& p ) { - p.setColor( col ); - p.drawRectangle( { { eefloor( x ), eefloor( y ) }, { eeceil( w ), eeceil( h ) } } ); -} - -inline static void drawpoint( const Color& col, const float& x, const float& y, const float& w, - const float& h, Primitives& p ) { - p.setColor( col ); - p.drawPoint( { eefloor( x ), eefloor( y ) }, eemin( w / 2.f, h / 2.f ) ); -} - -inline static void drawboxlines( float x, float y, float w, float h, Color fg, ushort bd, - Primitives& pr ) { - /* s: stem thickness. width/8 roughly matches underscore thickness. */ - /* We draw bold as 1.5 * normal-stem and at least 1px thicker. */ - /* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */ - float mwh = eemin( w, h ); - float base_s = eemin( 1.0f, DIV( mwh, 8.0f ) ); - int bold = ( bd & BDB ) && mwh >= 6.0f; /* possibly ignore boldness */ - float s = bold ? eemax( base_s + 1.0f, DIV( 3.0f * base_s, 2.0f ) ) : base_s; - float w2 = DIV( w - s, 2.0f ), h2 = DIV( h - s, 2.0f ); - /* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */ - /* The base length (per direction till edge) includes this square. */ - - int light = bd & ( LL | LU | LR | LD ); - int double_ = bd & ( DL | DU | DR | DD ); - - if ( light ) { - /* d: additional (negative) length to not-draw the center */ - /* texel - at arcs and avoid drawing inside (some) doubles */ - int arc = bd & BDA; - int multi_light = light & ( light - 1 ); - int multi_double = double_ & ( double_ - 1 ); - /* light crosses double only at DH+LV, DV+LH (ref. shapes) */ - float d = arc || ( multi_double && !multi_light ) ? -s : 0.0f; - - if ( bd & LL ) - drawrect( fg, x, y + h2, w2 + s + d, s, pr ); - if ( bd & LU ) - drawrect( fg, x + w2, y, s, h2 + s + d, pr ); - if ( bd & LR ) - drawrect( fg, x + w2 - d, y + h2, w - w2 + d, s, pr ); - if ( bd & LD ) - drawrect( fg, x + w2, y + h2 - d, s, h - h2 + d, pr ); - } - - /* double lines - also align with light to form heavy when combined */ - if ( double_ ) { - /* - * going clockwise, for each double-ray: p is additional length - * to the single-ray nearer to the previous direction, and n to - * the next. p and n adjust from the base length to lengths - * which consider other doubles - shorter to avoid intersections - * (p, n), or longer to draw the far-corner texel (n). - */ - int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD; - if ( dl ) { - float p = dd ? -s : 0.0f, n = du ? -s : dd ? s : 0.0f; - drawrect( fg, x, y + h2 + s, w2 + s + p, s, pr ); - drawrect( fg, x, y + h2 - s, w2 + s + n, s, pr ); - } - if ( du ) { - float p = dl ? -s : 0.0f, n = dr ? -s : dl ? s : 0.0f; - drawrect( fg, x + w2 - s, y, s, h2 + s + p, pr ); - drawrect( fg, x + w2 + s, y, s, h2 + s + n, pr ); - } - if ( dr ) { - float p = du ? -s : 0.0f, n = dd ? -s : du ? s : 0.0f; - drawrect( fg, x + w2 - p, y + h2 - s, w - w2 + p, s, pr ); - drawrect( fg, x + w2 - n, y + h2 + s, w - w2 + n, s, pr ); - } - if ( dd ) { - float p = dr ? -s : 0.0f, n = dl ? -s : dr ? s : 0.0f; - drawrect( fg, x + w2 + s, y + h2 - p, s, h - h2 + p, pr ); - drawrect( fg, x + w2 - s, y + h2 - n, s, h - h2 + n, pr ); - } - } -} - -inline static void drawbox( float x, float y, float w, float h, Color fg, Color bg, ushort bd, - Primitives& p ) { - ushort cat = bd & ~( BDB | 0xff ); /* mask out bold and data */ - if ( bd & ( BDL | BDA ) ) { - /* lines (light/double/heavy/arcs) */ - drawboxlines( x, y, w, h, fg, bd, p ); - } else if ( cat == BBD ) { - /* lower (8-X)/8 block */ - float d = DIV( ( bd & 0xFF ) * h, 8.0f ); - drawrect( fg, x, y + d, w, h - d, p ); - } else if ( cat == BBU ) { - /* upper X/8 block */ - drawrect( fg, x, y, w, DIV( ( bd & 0xFF ) * h, 8 ), p ); - } else if ( cat == BBL ) { - /* left X/8 block */ - drawrect( fg, x, y, DIV( ( bd & 0xFF ) * w, 8 ), h, p ); - } else if ( cat == BBR ) { - /* right (8-X)/8 block */ - float d = DIV( ( bd & 0xFF ) * w, 8.0f ); - drawrect( fg, x + d, y, w - d, h, p ); - } else if ( cat == BBQ ) { - /* Quadrants */ - float w2 = DIV( w, 2.0f ), h2 = DIV( h, 2.0f ); - if ( bd & TL ) - drawrect( fg, x, y, w2, h2, p ); - if ( bd & TR ) - drawrect( fg, x + w2, y, w - w2, h2, p ); - if ( bd & BL ) - drawrect( fg, x, y + h2, w2, h - h2, p ); - if ( bd & BR ) - drawrect( fg, x + w2, y + h2, w - w2, h - h2, p ); - } else if ( bd & BBS ) { - /* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */ - int d = ( bd & 0xFF ); - - Uint8 red = DIVI( ( ( fg.getValue() >> 24 ) & 0xFF ) * d + - ( ( bg.getValue() >> 24 ) & 0xFF ) * ( 4 - d ), - 4 ); - Uint8 green = DIVI( ( ( fg.getValue() >> 16 ) & 0xFF ) * d + - ( ( bg.getValue() >> 16 ) & 0xFF ) * ( 4 - d ), - 4 ); - Uint8 blue = DIVI( ( ( fg.getValue() >> 8 ) & 0xFF ) * d + - ( ( bg.getValue() >> 8 ) & 0xFF ) * ( 4 - d ), - 4 ); - Color drawcol = Color( red, green, blue, 0xFF ); - - drawrect( drawcol, x, y, w, h, p ); - } else if ( cat == BRL ) { - /* braille, each data bit corresponds to one dot at 2x4 grid */ - float w1 = DIV( w, 2.0f ); - float h1 = DIV( h, 4.0f ), h2 = DIV( h, 2.0f ), h3 = DIV( 3.0f * h, 4.0f ); - - if ( bd & 1 ) - drawpoint( fg, x, y, w1, h1, p ); - if ( bd & 2 ) - drawpoint( fg, x, y + h1, w1, h2 - h1, p ); - if ( bd & 4 ) - drawpoint( fg, x, y + h2, w1, h3 - h2, p ); - if ( bd & 8 ) - drawpoint( fg, x + w1, y, w - w1, h1, p ); - if ( bd & 16 ) - drawpoint( fg, x + w1, y + h1, w - w1, h2 - h1, p ); - if ( bd & 32 ) - drawpoint( fg, x + w1, y + h2, w - w1, h3 - h2, p ); - if ( bd & 64 ) - drawpoint( fg, x, y + h3, w1, h - h3, p ); - if ( bd & 128 ) - drawpoint( fg, x + w1, y + h3, w - w1, h - h3, p ); - } -} - -void ETerminalDisplay::draw( Vector2f pos ) { - mDrawing = true; - - auto fontSize = (Float)mFont->getFontHeight( mFontSize ); - auto spaceCharAdvanceX = mFont->getGlyph( 'A', mFontSize, false ).advance; - - auto width = mColumns * spaceCharAdvanceX; - auto height = mRows * fontSize; - - if ( width < mSize.getWidth() ) { - pos.x = std::floor( pos.x + ( ( mSize.getWidth() - width ) / 2.0f ) ); - } - if ( height < mSize.getHeight() ) { - pos.y = std::floor( pos.y + ( ( mSize.getHeight() - height ) / 2.0f ) ); - } - - float x = 0.0f; - float y = std::floor( pos.y ); - const float lineHeight = fontSize; - auto defaultFg = termColor( mEmulator->getDefaultForeground(), mColors ); - auto defaultBg = termColor( mEmulator->getDefaultBackground(), mColors ); - auto borderPx = eeceil( PixelDensity::dpToPx( 1.f ) ); - auto cursorThickness = eeceil( PixelDensity::dpToPx( 1.f ) ); - - Primitives p; - p.setForceDraw( false ); - p.setColor( defaultBg ); - p.drawRectangle( Rectf( mPosition.asFloat(), mSize.asFloat() ) ); - - for ( int j = 0; j < mRows; j++ ) { - x = std::floor( pos.x ); - - if ( pos.y + lineHeight * j > mSize.getWidth() ) - break; - - for ( int i = 0; i < mColumns; i++ ) { - auto& glyph = mBuffer[j * mColumns + i]; - auto fg = termColor( glyph.fg, mColors ); - auto bg = termColor( glyph.bg, mColors ); - - if ( IS_SET( MODE_REVERSE ) ) { - fg = fg == defaultFg ? defaultBg : fg.invert(); - bg = bg == defaultBg ? defaultFg : bg.invert(); - } - - if ( ( glyph.mode & ATTR_BOLD_FAINT ) == ATTR_FAINT ) - fg = fg.div( 2 ); - - if ( glyph.mode & ATTR_REVERSE ) - bg = fg; - - bool isWide = glyph.mode & ATTR_WIDE; - - auto advanceX = spaceCharAdvanceX * ( isWide ? 2.0f : 1.0f ); - - if ( glyph.mode & ATTR_WDUMMY ) { - continue; - } - - p.setColor( bg ); - p.drawRectangle( Rectf( { x, y }, { advanceX, lineHeight } ) ); - - x += advanceX; - } - - y += lineHeight; - } - - y = std::floor( pos.y ); - - for ( int j = 0; j < mRows; j++ ) { - x = std::floor( pos.x ); - - if ( pos.y + lineHeight * j > mSize.getWidth() ) - break; - - for ( int i = 0; i < mColumns; i++ ) { - auto& glyph = mBuffer[j * mColumns + i]; - auto fg = termColor( glyph.fg, mColors ); - auto bg = termColor( glyph.bg, mColors ); - Color temp{ Color::Transparent }; - - if ( ( glyph.mode & ATTR_BOLD_FAINT ) == ATTR_BOLD && BETWEEN( glyph.fg, 0, 7 ) ) - fg = termColor( glyph.fg + 8, mColors ); - - if ( IS_SET( MODE_REVERSE ) ) { - fg = fg == defaultFg ? defaultBg : fg.invert(); - bg = bg == defaultBg ? defaultFg : bg.invert(); - } - - if ( ( glyph.mode & ATTR_BOLD_FAINT ) == ATTR_FAINT ) - fg = fg.div( 2 ); - - if ( glyph.mode & ATTR_REVERSE ) { - temp = fg; - fg = bg; - bg = temp; - } - - if ( glyph.mode & ATTR_BLINK && ( mMode & MODE_BLINK ) ) - fg = bg; - - if ( glyph.mode & ATTR_INVISIBLE ) - fg = bg; - - bool isWide = glyph.mode & ATTR_WIDE; - - auto advanceX = spaceCharAdvanceX * ( isWide ? 2.0f : 1.0f ); - - if ( glyph.mode & ATTR_WDUMMY ) - continue; - - if ( glyph.mode & ATTR_BOXDRAW ) { - auto bd = TerminalEmulator::boxdrawindex( &glyph ); - drawbox( x, y, advanceX, lineHeight, fg, bg, bd, p ); - } else { - auto* gd = mFont->getGlyphDrawable( glyph.u, mFontSize, glyph.mode & ATTR_BOLD ); - gd->setColor( fg ); - gd->setDrawMode( glyph.mode & ATTR_ITALIC ? GlyphDrawable::DrawMode::TextItalic - : GlyphDrawable::DrawMode::Text ); - gd->draw( { x, y } ); - - if ( glyph.mode & ATTR_UNDERLINE ) { - p.setColor( fg ); - p.drawRectangle( Rectf( { x, y + borderPx + lineHeight - cursorThickness }, - { advanceX, cursorThickness } ) ); - } - - if ( glyph.mode & ATTR_STRUCK ) { - p.setColor( fg ); - p.drawRectangle( Rectf( { x, y + borderPx + eefloor( lineHeight / 2.f ) }, - { advanceX, cursorThickness } ) ); - } - } - - x += advanceX; - } - - y += lineHeight; - } - - if ( !IS_SET( MODE_HIDE ) ) { - Color drawcol; - if ( IS_SET( MODE_REVERSE ) ) { - if ( mEmulator->isSelected( mCursor.x, mCursor.y ) ) { - drawcol = termColor( mEmulator->getDefaultCursorColor(), mColors ); - } else { - drawcol = termColor( mEmulator->getDefaultReverseCursorColor(), mColors ); - } - } else { - drawcol = termColor( mEmulator->isSelected( mCursor.x, mCursor.y ) - ? mEmulator->getDefaultReverseCursorColor() - : mEmulator->getDefaultCursorColor(), - mColors ); - } - - Vector2f a{}, b{}, c{}, d{}; - - p.setColor( drawcol ); - /* draw the new one */ - if ( IS_SET( MODE_FOCUSED ) ) { - switch ( mCursorMode ) { - case 7: /* st extension */ - mCursorGlyph.u = 0x2603; /* snowman (U+2603) */ - /* FALLTHROUGH */ - case 0: /* Blinking Block */ - case 1: { /* Blinking Block (Default) */ - if ( !( mMode & MODE_BLINK ) ) - break; - } - case 2: { /* Steady Block */ - auto* gd = mFont->getGlyphDrawable( mCursorGlyph.u, mFontSize ); - gd->setColor( termColor( mCursorGlyph.fg, mColors ) ); - gd->setDrawMode( GlyphDrawable::DrawMode::Text ); - gd->draw( { pos.x + borderPx + mCursor.x * spaceCharAdvanceX, - pos.y + borderPx + mCursor.y * lineHeight } ); - break; - } - case 3: { /* Blinking Underline */ - if ( !( mMode & MODE_BLINK ) ) - break; - } - case 4: /* Steady Underline */ - p.drawRectangle( Rectf( - { pos.x + borderPx + mCursor.x * spaceCharAdvanceX, - pos.y + borderPx + ( mCursor.y + 1 ) * lineHeight - cursorThickness }, - { spaceCharAdvanceX, cursorThickness } ) ); - break; - case 5: { /* Blinking bar */ - if ( !( mMode & MODE_BLINK ) ) - break; - } - case 6: /* Steady bar */ - case TerminalCursorMode::MAX_CURSOR: - p.drawRectangle( Rectf( { pos.x + borderPx + mCursor.x * spaceCharAdvanceX, - pos.y + mCursor.y * lineHeight }, - { spaceCharAdvanceX, lineHeight } ) ); - break; - } - } else { - p.setFillMode( PrimitiveFillMode::DRAW_LINE ); - p.drawRectangle( Rectf( { pos.x + borderPx + mCursor.x * spaceCharAdvanceX, - pos.y + borderPx + mCursor.y * lineHeight }, - { spaceCharAdvanceX, lineHeight } ) ); - } - } - - mDrawing = false; - mDirty = false; -} - -Vector2i ETerminalDisplay::positionToGrid( const Vector2i& pos ) { - Vector2f relPos = { pos.x - mPosition.x, pos.y - mPosition.y - getYOffset() }; - int mouseX = 0; - int mouseY = 0; - - auto fontSize = (Float)mFont->getFontHeight( mFontSize ); - auto spaceCharAdvanceX = mFont->getGlyph( 'A', mFontSize, false ).advance; - - auto clipColumns = (int)std::floor( std::max( 1.0f, mSize.getWidth() / spaceCharAdvanceX ) ); - auto clipRows = (int)std::floor( std::max( 1.0f, mSize.getHeight() / fontSize ) ); - - if ( pos.x <= 0.0f || pos.y <= 0.0f ) { - mouseX = 0; - mouseY = 0; - } else if ( relPos.x >= 0.0f && relPos.y >= 0.0f ) { - mouseX = eeclamp( (int)std::floor( relPos.x / spaceCharAdvanceX ), 0, clipColumns ); - mouseY = eeclamp( (int)std::floor( relPos.y / fontSize ), 0, clipRows ); - } - - return { mouseX, mouseY }; -} - -void ETerminalDisplay::onSizeChange() { - Sizei gridSize( gridSizeFromTermDimensions( mFont, mFontSize, mSize ) ); - if ( gridSize.getWidth() != mTerminal->getNumColumns() || - gridSize.getHeight() != mTerminal->getNumRows() ) { - mTerminal->resize( gridSize.getWidth(), gridSize.getHeight() ); - } -} - -void ETerminalDisplay::onTextInput( const Uint32& chr ) { - if ( !mTerminal ) - return; - String input; - input.push_back( chr ); - std::string utf8Input( input.toUtf8() ); - mTerminal->write( utf8Input.c_str(), utf8Input.size() ); -} - -static Uint32 sanitizeMod( const Uint32& mod ) { - Uint32 smod = 0; - if ( mod & KEYMOD_CTRL ) - smod |= KEYMOD_CTRL; - if ( mod & KEYMOD_SHIFT ) - smod |= KEYMOD_SHIFT; - if ( mod & KEYMOD_META ) - smod |= KEYMOD_META; - if ( mod & KEYMOD_LALT ) - smod |= KEYMOD_LALT; - if ( mod & KEYMOD_RALT ) - smod |= KEYMOD_RALT; - return smod; -} - -void ETerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/, const Uint32& mod, - const Scancode& scancode ) { - Uint32 smod = sanitizeMod( mod ); - - auto scIt = terminalKeyMap.Shortcuts().find( keyCode ); - if ( scIt != terminalKeyMap.Shortcuts().end() ) { - for ( auto& k : scIt->second ) { - if ( k.mask == KEYMOD_CTRL_SHIFT_ALT_META || k.mask == smod ) { - if ( IS_SET( MODE_APPKEYPAD ) ? k.appkey < 0 : k.appkey > 0 ) - continue; - - if ( IS_SET( MODE_NUMLOCK ) && k.appkey == 2 ) - continue; - - if ( IS_SET( MODE_APPCURSOR ) ? k.appcursor < 0 : k.appcursor > 0 ) - continue; - - action( k.action ); - return; - } - } - } - - if ( mod & KEYMOD_CTRL ) { - // I really dont like this, as it depends on the undelying backend implementation (SDL in - // this case) - if ( ( scancode >= SCANCODE_A && scancode <= SCANCODE_0 ) || - SCANCODE_LEFTBRACKET == scancode || SCANCODE_RIGHTBRACKET == scancode ) { - char tmp = 0; - for ( size_t i = 0; i < eeARRAY_SIZE( asciiScancodeTable ); ++i ) { - if ( asciiScancodeTable[i] == scancode ) { - tmp = i + 1; - break; - } - } - - mTerminal->write( &tmp, 1 ); - return; - } - } - - auto kvIt = terminalKeyMap.KeyMap().find( keyCode ); - if ( kvIt != terminalKeyMap.KeyMap().end() ) { - for ( auto& k : kvIt->second ) { - if ( k.mask == KEYMOD_CTRL_SHIFT_ALT_META || k.mask == smod ) { - if ( IS_SET( MODE_APPKEYPAD ) ? k.appkey < 0 : k.appkey > 0 ) - continue; - - if ( IS_SET( MODE_NUMLOCK ) && k.appkey == 2 ) - continue; - - if ( IS_SET( MODE_APPCURSOR ) ? k.appcursor < 0 : k.appcursor > 0 ) - continue; - - if ( k.string.size() > 0 ) { - mTerminal->write( k.string.c_str(), k.string.size() ); - return; - } - break; - } - } - } - - auto pkmIt = terminalKeyMap.PlatformKeyMap().find( scancode ); - if ( pkmIt != terminalKeyMap.PlatformKeyMap().end() ) { - for ( auto& k : pkmIt->second ) { - if ( k.mask == KEYMOD_CTRL_SHIFT_ALT_META || k.mask == smod ) { - if ( IS_SET( MODE_APPKEYPAD ) ? k.appkey < 0 : k.appkey > 0 ) - continue; - - if ( IS_SET( MODE_NUMLOCK ) && k.appkey == 2 ) - continue; - - if ( IS_SET( MODE_APPCURSOR ) ? k.appcursor < 0 : k.appcursor > 0 ) - continue; - - if ( k.string.size() > 0 ) { - mTerminal->write( k.string.c_str(), k.string.size() ); - return; - } - break; - } - } - } -} - -Float ETerminalDisplay::getFontSize() const { - return mFontSize; -} - -void ETerminalDisplay::setFontSize( const Float& fontSize ) { - if ( mFontSize != fontSize ) { - mFontSize = fontSize; - onSizeChange(); - } -} - -const Vector2f& ETerminalDisplay::getPosition() const { - return mPosition; -} - -void ETerminalDisplay::setPosition( const Vector2f& position ) { - mPosition = position; - invalidate(); -} - -const Sizef& ETerminalDisplay::getSize() const { - return mSize; -} - -void ETerminalDisplay::setSize( const Sizef& size ) { - if ( mSize != size ) { - mSize = size; - onSizeChange(); - } -} - -void ETerminalDisplay::invalidate() { - mDirty = true; -} - -void ETerminalDisplay::setFocus( bool focus ) { - if ( focus == mFocus ) - return; - mFocus = focus; - bool modeFocus = mMode & MODE_FOCUSED; - if ( mFocus != modeFocus ) { - if ( mFocus ) { - mMode |= MODE_FOCUSED | MODE_FOCUS; - } else { - mMode ^= MODE_FOCUS | MODE_FOCUSED; - } - } else { - mMode ^= MODE_FOCUS; - } - invalidate(); -} diff --git a/src/tools/eterm/eterminaldisplay.hpp b/src/tools/eterm/eterminaldisplay.hpp deleted file mode 100644 index e30cd4849..000000000 --- a/src/tools/eterm/eterminaldisplay.hpp +++ /dev/null @@ -1,215 +0,0 @@ -#ifndef ETERMINALDISPLAY_HPP -#define ETERMINALDISPLAY_HPP - -#include "system/iprocessfactory.hpp" -#include "terminal/terminaldisplay.hpp" -#include "terminal/terminalemulator.hpp" -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace EE; -using namespace EE::Terminal; -using namespace EE::Window; -using namespace EE::System; - -enum class TerminalShortcutAction { PASTE, COPY }; - -enum TerminalOptions { - OPTION_NONE = 0, - OPTION_COLOR_EMOJI = 1 << 0, - OPTION_PASTE_CRLF = 1 << 1 -}; - -struct TerminalConfig { - int options; -}; - -struct TerminalKey { - Keycode keysym; - Uint32 mask; - const char* string; - int appkey; - int appcursor; -}; - -struct TerminalScancode { - Scancode scancode; - Uint32 mask; - std::string string; - int appkey; - int appcursor; -}; - -struct TerminalShortcut { - Keycode keysym; - Uint32 mask; - TerminalShortcutAction action; - int appkey; - int appcursor; -}; - -struct TerminalKeyMapEntry { - Uint32 mask; - std::string string; - int appkey; - int appcursor; -}; - -struct TerminalKeyMapShortcut { - Uint32 mask; - TerminalShortcutAction action; - int appkey; - int appcursor; -}; - -class TerminalKeyMap { - private: - std::unordered_map> m_keyMap; - std::unordered_map> m_platformKeyMap; - std::unordered_map> m_shortcuts; - - public: - TerminalKeyMap( const TerminalKey keys[], size_t keysLen, const TerminalScancode platformKeys[], - size_t platformKeysLen, const TerminalShortcut shortcuts[], - size_t shortcutsLen ); - - inline const std::unordered_map>& KeyMap() const { - return m_keyMap; - } - - inline const std::unordered_map>& - PlatformKeyMap() const { - return m_platformKeyMap; - } - - inline const std::unordered_map>& - Shortcuts() const { - return m_shortcuts; - } -}; - -constexpr int TerminalKeyModFlags_Any = 0xFFFFFFFF; - -extern TerminalKeyMap terminalKeyMap; - -static const Scancode asciiScancodeTable[] = { - SCANCODE_A, SCANCODE_B, SCANCODE_C, SCANCODE_D, SCANCODE_E, SCANCODE_F, - SCANCODE_G, SCANCODE_H, SCANCODE_I, SCANCODE_J, SCANCODE_K, SCANCODE_L, - SCANCODE_M, SCANCODE_N, SCANCODE_O, SCANCODE_P, SCANCODE_Q, SCANCODE_R, - SCANCODE_S, SCANCODE_T, SCANCODE_U, SCANCODE_V, SCANCODE_W, SCANCODE_X, - SCANCODE_Y, SCANCODE_Z, SCANCODE_LEFTBRACKET, SCANCODE_SLASH, SCANCODE_RIGHTBRACKET }; - -class ETerminalDisplay : public TerminalDisplay { - public: - static std::shared_ptr - create( EE::Window::Window* window, Font* font, const Float& fontSize, const Sizef& pixelsSize, - std::shared_ptr&& terminalEmulator, TerminalConfig* config = 0 ); - - static std::shared_ptr - create( EE::Window::Window* window, Font* font, const Float& fontSize, const Sizef& pixelsSize, - const std::string& program, const std::vector& args, - const std::string& workingDir, uint32_t options = 0, - EE::System::IProcessFactory* processFactory = nullptr ); - - virtual void resetColors(); - virtual int resetColor( int index, const char* name ); - - virtual void setTitle( const char* title ); - virtual void setIconTitle( const char* title ); - - virtual void setClipboard( const char* text ); - virtual const char* getClipboard() const; - - virtual bool drawBegin( int columns, int rows ); - virtual void drawLine( Line line, int x1, int y, int x2 ); - virtual void drawCursor( int cx, int cy, TerminalGlyph g, int ox, int oy, TerminalGlyph og ); - virtual void drawEnd(); - - virtual void update(); - - void action( TerminalShortcutAction action ); - - bool hasTerminated() const; - - void draw(); - - virtual void onMouseDoubleClick( const Vector2i& pos, const Uint32& flags ); - - virtual void onMouseMotion( const Vector2i& pos, const Uint32& flags ); - - virtual void onMouseDown( const Vector2i& pos, const Uint32& flags ); - - virtual void onMouseUp( const Vector2i& pos, const Uint32& flags ); - - virtual void onTextInput( const Uint32& chr ); - - virtual void onKeyDown( const Keycode& keyCode, const Uint32& chr, const Uint32& mod, - const Scancode& scancode ); - - Float getFontSize() const; - - void setFontSize( const Float& FontSize ); - - const Vector2f& getPosition() const; - - void setPosition( const Vector2f& position ); - - const Sizef& getSize() const; - - void setSize( const Sizef& size ); - - bool isDirty() const { return mDirty; } - - void invalidate(); - - bool hasFocus() const { return mFocus; } - - void setFocus( bool focus ); - - bool isBlinkingCursor(); - - protected: - EE::Window::Window* mWindow; - std::vector mBuffer; - std::vector> mColors; - std::shared_ptr mTerminal; - mutable std::string mClipboard; - - Font* mFont{ nullptr }; - Float mFontSize{ 12 }; - Vector2f mPosition; - Sizef mSize; - int mColumns{ 0 }; - int mRows{ 0 }; - std::atomic mDirty{ true }; - std::atomic mDrawing{ false }; - Vector2i mCursor; - TerminalGlyph mCursorGlyph; - bool mUseColorEmoji{ true }; - bool mPasteNewlineFix{ true }; - bool mFocus{ true }; - Clock mClock; - Clock mLastDoubleClick; - - ETerminalDisplay( EE::Window::Window* window, Font* font, const Float& fontSize, - const Sizef& pixelsSize, TerminalConfig* config ); - - void draw( Vector2f pos ); - - Vector2i positionToGrid( const Vector2i& pos ); - - void onSizeChange(); - - Float getYOffset() const; -}; - -#endif // ETERMINALDISPLAY_HPP diff --git a/src/tools/eterm/system/process.cpp b/src/tools/eterm/system/process.cpp index e0632ff6e..4c2e2f80b 100644 --- a/src/tools/eterm/system/process.cpp +++ b/src/tools/eterm/system/process.cpp @@ -22,6 +22,7 @@ #ifndef _WIN32 #include "process.hpp" +#include #include #include #include @@ -31,8 +32,6 @@ #include #include -#define DEFAULT( a, b ) ( a ) = ( a ) ? ( a ) : ( b ) - #if defined( __linux ) #include #elif defined( __OpenBSD__ ) || defined( __NetBSD__ ) || defined( __APPLE__ ) @@ -102,8 +101,9 @@ int Process::getExitCode() const { Process::Process( int pid ) : m_pid( pid ) {} -static void execshell( const char* cmd, const char* const* args ) { +static void execshell( const char* cmd, const char* const* args, std::string workingDirectory ) { const struct passwd* pw; + const char* sh; errno = 0; if ( ( pw = getpwuid( getuid() ) ) == NULL ) { @@ -116,12 +116,20 @@ static void execshell( const char* cmd, const char* const* args ) { } } + if ( ( sh = getenv( "SHELL" ) ) == NULL ) + sh = ( pw->pw_shell[0] ) ? pw->pw_shell : cmd; + + if ( workingDirectory.empty() ) + workingDirectory = pw->pw_dir; + + FileSystem::changeWorkingDirectory( workingDirectory ); + unsetenv( "COLUMNS" ); unsetenv( "LINES" ); unsetenv( "TERMCAP" ); setenv( "LOGNAME", pw->pw_name, 1 ); setenv( "USER", pw->pw_name, 1 ); - // setenv( "SHELL", sh, 1 ); + setenv( "SHELL", sh, 1 ); setenv( "HOME", pw->pw_dir, 1 ); setenv( "TERM", "st-256color", 1 ); @@ -147,7 +155,7 @@ std::unique_ptr Process::createWithPipe( const std::string& /*program*/ std::unique_ptr Process::createWithPseudoTerminal( const std::string& program, const std::vector& args, - const std::string& /*workingDirectory*/, + const std::string& workingDirectory, Terminal::PseudoTerminal& pseudoTerminal ) { int pid = fork(); if ( pid == -1 ) { @@ -181,7 +189,7 @@ Process::createWithPseudoTerminal( const std::string& program, const std::vector argsV.push_back( a.c_str() ); } argsV.push_back( nullptr ); - execshell( program.c_str(), argsV.data() ); + execshell( program.c_str(), argsV.data(), workingDirectory ); } else { pseudoTerminal.m_slave.release(); return std::unique_ptr( new Process( pid ) ); diff --git a/src/tools/eterm/terminal/terminaldisplay.cpp b/src/tools/eterm/terminal/iterminaldisplay.cpp similarity index 70% rename from src/tools/eterm/terminal/terminaldisplay.cpp rename to src/tools/eterm/terminal/iterminaldisplay.cpp index 18cf2a8db..acea9238c 100644 --- a/src/tools/eterm/terminal/terminaldisplay.cpp +++ b/src/tools/eterm/terminal/iterminaldisplay.cpp @@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -#include "../terminal/terminaldisplay.hpp" +#include "../terminal/iterminaldisplay.hpp" #include "../terminal/terminalemulator.hpp" #include @@ -27,28 +27,28 @@ using namespace EE::Terminal; -TerminalDisplay::TerminalDisplay() : +ITerminalDisplay::ITerminalDisplay() : mMode( MODE_VISIBLE ), mCursorMode( SteadyBar ), mEmulator( nullptr ) {} -void TerminalDisplay::attach( TerminalEmulator* terminal ) { +void ITerminalDisplay::attach( TerminalEmulator* terminal ) { assert( mEmulator == nullptr ); mEmulator = terminal; } -void TerminalDisplay::detach( TerminalEmulator* terminal ) { +void ITerminalDisplay::detach( TerminalEmulator* terminal ) { assert( mEmulator == terminal ); mEmulator = nullptr; } -void TerminalDisplay::bell() {} +void ITerminalDisplay::bell() {} -void TerminalDisplay::resetColors() {} +void ITerminalDisplay::resetColors() {} -int TerminalDisplay::resetColor( int /*index*/, const char* /*name*/ ) { +int ITerminalDisplay::resetColor( int /*index*/, const char* /*name*/ ) { return 0; } -void TerminalDisplay::setMode( TerminalWinMode mode, int set ) { +void ITerminalDisplay::setMode( TerminalWinMode mode, int set ) { int m = mMode; MODBIT( ( (int&)mMode ), set, mode ); if ( ( mMode & MODE_REVERSE ) != ( m & MODE_REVERSE ) && mEmulator ) { @@ -56,20 +56,20 @@ void TerminalDisplay::setMode( TerminalWinMode mode, int set ) { } } -void TerminalDisplay::setCursorMode( TerminalCursorMode cursor ) { +void ITerminalDisplay::setCursorMode( TerminalCursorMode cursor ) { mCursorMode = cursor; } -TerminalCursorMode TerminalDisplay::getCursorMode() const { +TerminalCursorMode ITerminalDisplay::getCursorMode() const { return mCursorMode; } -void TerminalDisplay::setTitle( const char* ) {} +void ITerminalDisplay::setTitle( const char* ) {} -void TerminalDisplay::setIconTitle( const char* ) {} +void ITerminalDisplay::setIconTitle( const char* ) {} -void TerminalDisplay::setClipboard( const char* ) {} +void ITerminalDisplay::setClipboard( const char* ) {} -const char* TerminalDisplay::getClipboard() const { +const char* ITerminalDisplay::getClipboard() const { return ""; } diff --git a/src/tools/eterm/terminal/terminaldisplay.hpp b/src/tools/eterm/terminal/iterminaldisplay.hpp similarity index 87% rename from src/tools/eterm/terminal/terminaldisplay.hpp rename to src/tools/eterm/terminal/iterminaldisplay.hpp index ca31575b9..301387b0f 100644 --- a/src/tools/eterm/terminal/terminaldisplay.hpp +++ b/src/tools/eterm/terminal/iterminaldisplay.hpp @@ -27,19 +27,19 @@ namespace EE { namespace Terminal { class TerminalEmulator; -class TerminalDisplay { +class ITerminalDisplay { public: - TerminalDisplay(); + ITerminalDisplay(); - virtual ~TerminalDisplay() = default; + virtual ~ITerminalDisplay() = default; - TerminalDisplay( const TerminalDisplay& ) = delete; + ITerminalDisplay( const ITerminalDisplay& ) = delete; - TerminalDisplay( TerminalDisplay&& ) = delete; + ITerminalDisplay( ITerminalDisplay&& ) = delete; - TerminalDisplay& operator=( const TerminalDisplay& ) = delete; + ITerminalDisplay& operator=( const ITerminalDisplay& ) = delete; - TerminalDisplay& operator=( TerminalDisplay&& ) = delete; + ITerminalDisplay& operator=( ITerminalDisplay&& ) = delete; virtual void attach( TerminalEmulator* terminal ); diff --git a/src/tools/eterm/terminal/terminalemulator.cpp b/src/tools/eterm/terminal/terminalemulator.cpp index f775021d8..0b0f4977e 100644 --- a/src/tools/eterm/terminal/terminalemulator.cpp +++ b/src/tools/eterm/terminal/terminalemulator.cpp @@ -77,7 +77,7 @@ const static unsigned int worddelimiters[] = { ' ', 0 }; */ static const unsigned int tabspaces = 4; -#ifdef WIN32 +#ifdef _WIN32 #include #endif @@ -1268,7 +1268,7 @@ void TerminalEmulator::csihandle( void ) { char buf[40]; int len; - std::shared_ptr dpy{}; + std::shared_ptr dpy{}; switch ( mCsiescseq.mode[0] ) { default: @@ -1509,7 +1509,7 @@ void TerminalEmulator::strhandle( void ) { strparse(); par = ( narg = mStrescseq.narg ) ? atoi( mStrescseq.args[0] ) : 0; - std::shared_ptr dpy = mDpy.lock(); + std::shared_ptr dpy = mDpy.lock(); switch ( mStrescseq.type ) { case ']': /* OSC -- Operating System Command */ @@ -2222,7 +2222,7 @@ void TerminalEmulator::resettitle( void ) { dpy->setTitle( NULL ); } -void TerminalEmulator::drawregion( TerminalDisplay& dpy, int x1, int y1, int x2, int y2 ) { +void TerminalEmulator::drawregion( ITerminalDisplay& dpy, int x1, int y1, int x2, int y2 ) { int y; for ( y = y1; y < y2; y++ ) { @@ -2369,7 +2369,7 @@ void TerminalEmulator::xsetpointermotion( int ) { std::unique_ptr TerminalEmulator::create( PtyPtr&& pty, ProcPtr&& process, - const std::shared_ptr& display ) { + const std::shared_ptr& display ) { if ( !pty || !process ) { fprintf( stderr, "Must provide valid pseudoterminal and process" ); return nullptr; @@ -2380,7 +2380,7 @@ TerminalEmulator::create( PtyPtr&& pty, ProcPtr&& process, } TerminalEmulator::TerminalEmulator( PtyPtr&& pty, ProcPtr&& process, - const std::shared_ptr& display ) : + const std::shared_ptr& display ) : mDpy( display ), mPty( std::move( pty ) ), mProcess( std::move( process ) ), diff --git a/src/tools/eterm/terminal/terminalemulator.hpp b/src/tools/eterm/terminal/terminalemulator.hpp index 2e7bc1be7..14f3361a1 100644 --- a/src/tools/eterm/terminal/terminalemulator.hpp +++ b/src/tools/eterm/terminal/terminalemulator.hpp @@ -37,7 +37,7 @@ #include "../system/iprocess.hpp" #include "ipseudoterminal.hpp" -#include "terminaldisplay.hpp" +#include "iterminaldisplay.hpp" #include "types.hpp" #include #include @@ -103,7 +103,7 @@ enum class TerminalMouseEventType { MouseMotion, MouseButtonDown, MouseButtonRel class TerminalEmulator final { public: - using DpyPtr = std::weak_ptr; + using DpyPtr = std::weak_ptr; using PtyPtr = std::unique_ptr; using ProcPtr = std::unique_ptr; @@ -120,7 +120,7 @@ class TerminalEmulator final { TerminalEmulator& operator=( TerminalEmulator&& ) = delete; static std::unique_ptr - create( PtyPtr&& pty, ProcPtr&& process, const std::shared_ptr& display ); + create( PtyPtr&& pty, ProcPtr&& process, const std::shared_ptr& display ); void resize( int columns, int rows ); @@ -266,7 +266,7 @@ class TerminalEmulator final { void selsnap( int*, int*, int ); void _die( const char*, ... ); - void drawregion( TerminalDisplay& dpy, int, int, int, int ); + void drawregion( ITerminalDisplay& dpy, int, int, int, int ); void draw(); int tattrset( int ); @@ -296,7 +296,7 @@ class TerminalEmulator final { void xximspot( int, int ); TerminalEmulator( PtyPtr&& pty, ProcPtr&& process, - const std::shared_ptr& display ); + const std::shared_ptr& display ); }; }} // namespace EE::Terminal