diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bebbdb..33ed3d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,7 @@ set(SOURCE_FILES user/apars_osc.c user/apars_osc.h user/apars_dcs.c - user/apars_dcs.h user/uart_buffer.c user/uart_buffer.h user/jstring.c user/jstring.h) + user/apars_dcs.h user/uart_buffer.c user/uart_buffer.h user/jstring.c user/jstring.h user/character_sets.h) include_directories(include) include_directories(user) diff --git a/build_web.sh b/build_web.sh index b794ccd..72ad0eb 100755 --- a/build_web.sh +++ b/build_web.sh @@ -19,3 +19,8 @@ rm html/css/app.css.map cp html_orig/img/* html/img/ cp html_orig/favicon.ico html/favicon.ico + +# cleanup +find html/ -name "*.orig" -delete +find html/ -name "*.xcf" -delete +find html/ -name "*~" -delete diff --git a/html_orig/_debug_replacements.php b/html_orig/_debug_replacements.php index e154ce0..b02463f 100644 --- a/html_orig/_debug_replacements.php +++ b/html_orig/_debug_replacements.php @@ -15,10 +15,9 @@ return [ 'btn5' => '5', 'labels_seq' => 'TESPTerm local debug1235', - 'screenData' => 'HELLOxNRE3',//'\u000b\u0001\u001b\u0001\u0001\u0001\u0001\u0001\f\u0005\u0001\u0010\u0003HELLOx\u0002\u000b\u0001\u0001N\u0001RE\u00023\u0001', //, - 'parser_tout_ms' => 10, - 'display_tout_ms' => 20, + 'display_tout_ms' => 15, + 'display_cooldown_ms' => 35, 'fn_alt_mode' => '1', 'opmode' => '2', @@ -61,6 +60,8 @@ return [ 'term_height' => '10', 'default_bg' => '0', 'default_fg' => '7', + 'show_buttons' => '1', + 'show_config_links' => '1', 'uart_baud' => 115200, 'uart_stopbits' => 1, diff --git a/html_orig/base.php b/html_orig/base.php index 925d057..c4531b1 100644 --- a/html_orig/base.php +++ b/html_orig/base.php @@ -69,3 +69,78 @@ function include_str($code) fclose($tmp); return $ret; } + +if (!function_exists('utf8')) { + function utf8($num) + { + if($num<=0x7F) return chr($num); + if($num<=0x7FF) return chr(($num>>6)+192).chr(($num&63)+128); + if($num<=0xFFFF) return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128); + if($num<=0x1FFFFF) return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128).chr(($num&63)+128); + return ''; + } +} + +if (!function_exists('load_esp_charsets')) { + function load_esp_charsets() { + $chsf = __DIR__ . '/../user/character_sets.h'; + $re_table = '/\/\/ %%BEGIN:(.)%%\s*(.*?)\s*\/\/ %%END:\1%%/s'; + preg_match_all($re_table, file_get_contents($chsf), $m_tbl); + + $re_bounds = '/#define CODEPAGE_(.)_BEGIN\s+(\d+)\n#define CODEPAGE_\1_END\s+(\d+)/'; + preg_match_all($re_bounds, file_get_contents($chsf), $m_bounds); + + $cps = []; + + foreach ($m_tbl[2] as $i => $str) { + $name = $m_tbl[1][$i]; + $start = intval($m_bounds[2][$i]); + $table = []; + $str = preg_replace('/,\s*\/\/[^\n]*/', '', $str); + $rows = explode("\n", $str); + $rows = array_map('trim', $rows); + + foreach($rows as $j => $v) { + if (strpos($v, '0x') === 0) { + $v = substr($v, 2); + $v = hexdec($v); + } else { + $v = intval($v); + } + $ascii = $start+$j; + $table[] = [ + $ascii, + chr($ascii), + utf8($v==0? $ascii :$v), + ]; + } + $cps[$name] = $table; + } + return $cps; + } +} + +if (!function_exists('tplSubs')) { + function tplSubs($str, $reps) + { + return preg_replace_callback('/%(j:|js:|h:|html:)?([a-z0-9-_.]+)%/i', function ($m) use ($reps) { + $key = $m[2]; + if (array_key_exists($key, $reps)) { + $val = $reps[$key]; + } else { + $val = ''; + } + switch ($m[1]) { + case 'j:': + case 'js:': + $v = json_encode($val); + return substr($v, 1, strlen($v) - 2); + case 'h:': + case 'html:': + return htmlspecialchars($val); + default: + return $val; + } + }, $str); + } +} diff --git a/html_orig/css/app.css b/html_orig/css/app.css index 2c759a8..0518663 100644 --- a/html_orig/css/app.css +++ b/html_orig/css/app.css @@ -570,10 +570,13 @@ ul { #loader.show { opacity: 1; } +.botpad { + display: block; + height: 5em; } + .Box { display: block; max-width: 900px; - line-height: 1.35em; margin-top: 1rem; padding: 0.61805rem 1rem; border-radius: 3px; @@ -904,6 +907,7 @@ form { vertical-align: middle; margin: 12px auto; text-align: left; + line-height: 1.35em; display: flex; flex-direction: row; align-items: center; } @@ -1147,50 +1151,58 @@ body.term #content { @media screen and (max-width: 544px) { body.term #content h1 { font-size: 1.42383em; } } -body.term #screen { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - font-family: monospace; - font-size: 20px; + +#screen { white-space: nowrap; background: #111213; padding: 6px; display: inline-block; - border: 2px solid #3983CD; } - body.term #screen span { - white-space: pre; - cursor: pointer; - display: inline-block; - line-height: 1.15em; - width: 0.6em; - overflow: visible; } -body.term #buttons { + border: 2px solid #3983CD; + font-size: 24px; + font-family: "DejaVu Sans Mono", "Liberation Mono", "Inconsolata", monospace; } + #screen span { + white-space: pre; } + #screen > span { + position: relative; + cursor: pointer; } + #screen > span::before { + content: " "; } + #screen > span > span { + position: absolute; + left: 0; + z-index: 1; } + #screen.noselect { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +#action-buttons { margin-top: 10px; white-space: nowrap; } - body.term #buttons button { + #action-buttons button { margin: 0 3px; padding: 8px 5px; min-width: 62px; cursor: pointer; font-weight: bold; } -body.term #botnav { + +#term-nav { padding-top: 1.5em; text-align: center; } - body.term #botnav a { + #term-nav a { padding: 0 0.38198rem; text-decoration: underline; } - body.term #botnav a, body.term #botnav a:visited, body.term #botnav a:link { + #term-nav a, #term-nav a:visited, #term-nav a:link { color: #336085; } - body.term #botnav a:hover { + #term-nav a:hover { color: #5abfff; } - body.term #botnav .icn-keyboard { + #term-nav .icn-keyboard { text-decoration: none; font-size: 150%; vertical-align: middle; } -#termwrap { +#term-wrap { text-align: center; } #softkb-input { @@ -1677,6 +1689,39 @@ body.term #botnav { .tscroll { overflow-x: auto; } +.charset { + line-height: 1; } + .charset div { + display: inline-block; + width: 2.5em; + border: 1px solid #666; + height: 3em; + margin: 1px; + position: relative; } + .charset div span { + display: block; + position: absolute; } + .charset div span:nth-child(1) { + left: .2em; + top: .2em; + height: 1em; + font-size: 85%; + color: #999; } + .charset div span:nth-child(2) { + right: .2em; + top: .2em; + height: 1em; + font-size: 85%; + color: #999; } + .charset div span:nth-child(3) { + width: 100%; + font-size: 105%; + text-align: center; + bottom: .4em; + font-family: "DejaVu Sans Mono", "Liberation Mono", "Inconsolata", monospace; } + .charset div.none { + opacity: .4; } + @media screen and (min-width: 545px) { .mq-phone { display: none !important; } } diff --git a/html_orig/dump_js_lang.php b/html_orig/dump_js_lang.php index 14b0db6..ab2f976 100755 --- a/html_orig/dump_js_lang.php +++ b/html_orig/dump_js_lang.php @@ -8,6 +8,7 @@ $selected = [ 'wifi.connected_ip_is', 'wifi.not_conn', 'wifi.enter_passwd', + 'wifi.passwd_saved', ]; $out = []; diff --git a/html_orig/img/adapter.jpg b/html_orig/img/adapter.jpg.orig similarity index 100% rename from html_orig/img/adapter.jpg rename to html_orig/img/adapter.jpg.orig diff --git a/html_orig/img/vt100.jpg b/html_orig/img/vt100.jpg index 909461a..7046042 100644 Binary files a/html_orig/img/vt100.jpg and b/html_orig/img/vt100.jpg differ diff --git a/html_orig/img/vt100.jpg.orig b/html_orig/img/vt100.jpg.orig new file mode 100644 index 0000000..909461a Binary files /dev/null and b/html_orig/img/vt100.jpg.orig differ diff --git a/html_orig/index.php b/html_orig/index.php index 2ce2622..fbd94a4 100644 --- a/html_orig/index.php +++ b/html_orig/index.php @@ -7,46 +7,35 @@ if (!isset($_GET['page'])) $_GET['page'] = 'term'; $_GET['PAGE_TITLE'] = $_pages[$_GET['page']]->title . ' :: ' . APP_NAME; $_GET['BODYCLASS'] = $_pages[$_GET['page']]->bodyclass; -if (!function_exists('tplSubs')) { - function tplSubs($str, $reps) - { - return preg_replace_callback('/%(j:|js:|h:|html:)?([a-z0-9-_.]+)%/i', function ($m) use ($reps) { - $key = $m[2]; - if (array_key_exists($key, $reps)) { - $val = $reps[$key]; - } else { - $val = ''; - } - switch ($m[1]) { - case 'j:': - case 'js:': - $v = json_encode($val); - return substr($v, 1, strlen($v) - 2); - case 'h:': - case 'html:': - return htmlspecialchars($val); - default: - return $val; - } - }, $str); - } -} - require __DIR__ . '/pages/_head.php'; $_pf = __DIR__ . '/pages/'.$_GET['page'].'.php'; + +$include_re = '/<\?php\s*(require|include)\s*\(?\s*?(?:__DIR__\s*\.)?\s*(["\'])(.*?)\2\s*\)?;\s*\?>/'; + if (file_exists($_pf)) { $f = file_get_contents($_pf); + // Resolve requires inline - they wont work after dumping the resulting file to /tmp for eval + $f = preg_replace_callback($include_re, function ($m) use ($_pf) { + $n = dirname($_pf).'/'.$m[3]; + if (file_exists($n)) { + return file_get_contents($n); + } else { + return "
NOT FOUND: $n
"; + } + }, $f); + if (DEBUG) $str = tplSubs($f, require(__DIR__ . '/_debug_replacements.php')); else $str = $f; // special symbols $str = str_replace('\,', ' ', $str); - $str = preg_replace('/(?<=[^ ])~(?=[^ ])/', ' ', $str); - $str = preg_replace('/(?$1', $str); - $str = preg_replace('/(?$1', $str); - $str = preg_replace('/(?$1', $str); + $str = preg_replace('/(?<=[^ \\\\])~(?=[^ ])/', ' ', $str); + $str = str_replace('\~', '~', $str); + $str = preg_replace('/(?$1', $str); + $str = preg_replace('/(?$1', $str); + $str = preg_replace('/(?$1', $str); $str = preg_replace("/\s*(\\\\\\\\)[\n \t]+/", '- ESPTerm emulates VT102 (pictured) with some additions from later VT models and Xterm. - All commonly used attributes and commands are supported. - ESPTerm is capable of displaying ncurses applications such as _Midnight Commander_ using _agetty_. -
- -- ESPTerm accepts UTF-8 characters received on the communication UART and displays them on the screen, - interpreting some codes as Control Characters. Those are e.g. _Carriage Return_ (13), _Line Feed_ (10), - _Tab_ (9), _Backspace_ (8) and _Bell_ (7). -
- -- Escape sequences start with the control character _ESC_ (27), - followed by any number of ASCII characters forming the body of the command. -
- -- Examples on this help page use the following symbols for special characters and command types:\\ - (spaces are for clarity only, _DO NOT_ include them in the commands!) -
- -Name | Symbol | ASCII | C string | Function |
---|---|---|---|---|
*ESC* | -`\e` | -`ESC` (27) | -`"\e"`, `"\x1b"`, `"\033"` | -Introduces an escape sequence. _(Note: `\e` is a GCC extension)_ | -
*Bell* | -`\a` | -`BEL`~(7) | -`"\a"`, `"\x7"`, `"\07"` | -Audible beep | -
*String Terminator* | -`ST` | -`ESC \`~(27~92) _or_~`\a`~(7) |
- `"\x1b\\"`, `"\a"` | -Terminates a string command (`\a` can be used as an alternative) | -
*Control Sequence Introducer* | -`CSI` | -`ESC [` | -`"\x1b["` | -Starts a CSI command. Examples: `\e[?7;10h`, `\e[2J` | -
*Operating System Command* | -`OSC` | -`ESC ]` | -`"\x1b]"` | -Starts an OSC command. Is followed by a command string terminated by `ST`. Example: `\e]0;My Screen Title\a` | -
*Select Graphic Rendition* | -`SGR` | -`CSI n;n;nm` | -`"\x1b[1;2;3m"` | -Set text attributes, like color or style. 0 to 10 numbers can be used, `\e[m` is treated as `\e[0m` | -
There are also some other commands that don't follow the CSI, SGR or OSC pattern, such as `\e7` or - `\e#8`. A list of the most important escape sequences is presented in the following sections.
-- The initial screen size, title text and button labels can be configured in Terminal Settings. -
- -- Screen updates are sent to the browser through a WebSocket after some time of inactivity on the communication UART - (called "Redraw Delay"). After an update is sent, at least a time of "Redraw Cooldown" must elapse before the next - update can be sent. Those delays are used is to avoid burdening the server with tiny updates during a large screen - repaint. If you experience issues (broken image due to dropped bytes), try adjusting those config options. It may also - be useful to try different baud rates. -
-- All text attributes are set using SGR commands like `\e[10;20;30m`, with up to 10 numbers separated by semicolons. - To restore all attributes to their default states, use SGR 0: `\e[0m` or `\e[m`. -
- -Those are the supported text attributes SGR codes:
- -Style | Enable | Disable |
---|---|---|
Bold | 1 | 21, 22 |
Faint | 2 | 22 |
Italic | 3 | 23 |
Underlined | 4 | 24 |
Blink | 5 | 25 |
Inverse | 7 | 27 |
9 | 29 | |
๐๐ฏ๐๐จ๐ฑ๐ฒ๐ฏ | 20 | 23 |
- Colors are set using SGR commands (like `\e[10;20;30m`). The following tables list the SGR codes to use. - Selected colors are used for any new text entered, as well as for empty space when using line and screen clearing commands. - The configured default colors can be restored using SGR 39 for foreground and SGR 49 for background. -
- -- The actual color representation depends on a color theme which - can be selected in Terminal Settings. -
- -- The user can input text using their keyboard, or on Android, using the on-screen keyboard which is open using - a button beneath the screen. Supported are all printable characters, as well as many control keys, such as arrows, _Ctrl+letters_ - and function keys. Sequences sent by function keys are based on VT102 and Xterm. -
- -- The codes sent by _Home_, _End_, _F1-F4_ and cursor keys are affected by various keyboard modes (_Application Cursor Keys_, - _Application Numpad Mode_, _SS3 Fn Keys Mode_). - Some can be set in the Terminal Settings, others via commands. -
- -- Here are some examples of control key codes: -
- -Key | Code | Key | Code |
---|---|---|---|
Up | -`\e[A` | -F1 | -`\eOP` | -
Down | -`\e[B` | -F2 | -`\eOQ` | -
Right | -`\e[C` | -F3 | -`\eOR` | -
Left | -`\e[D` | -F4 | -`\eOS` | -
Home | -`\eOH` | -F5 | -`\e[15~` | -
End | -`\eOF` | -F6 | -`\e[17~` | -
Insert | -`\e[2~` | -F7 | -`\e[18~` | -
Delete | -`\e[3~` | -F8 | -`\e[19~` | -
Page Up | -`\e[5~` | -F9 | -`\e[20~` | -
Page Down | -`\e[6~` | -F10 | -`\e[21~` | -
Enter | -`\r` (13) | -F11 | -`\e[23~` | -
Ctrl+Enter | -`\n` (10) | -F12 | -`\e[24~` | -
Tab | -`\t` (9) | -ESC | -`\e` (27) | -
Backspace | -`\b` (8) | -Ctrl+A..Z | -ASCII 1-26 | -
- The blue buttons under the screen send ASCII codes 1, 2, 3, 4, 5, which incidentally - correspond to _Ctrl+A,B,C,D,E_. This choice was made to make button press parsing as simple as possible. -
- -- ESPTerm implements standard mouse tracking modes based on Xterm. Mouse tracking can be used to implement - powerful user interactions such as on-screen buttons, draggable sliders or dials, menus etc. ESPTerm's - mouse tracking was tested using VTTest and should be compatible with all terminal applications - that request mouse tracking. -
- -- Mouse can be tracked in different ways; some are easier to parse, others more powerful. The coordinates - can also be encoded in different ways. All mouse tracking options are set using option commands: - `CSI ? _n_ h` to enable, `CSI ? _n_ l` to disable option _n_. -
- -- All tracking modes produce three numbers which are then encoded and send to the application. - First is the _event number_ N, then the _X and Y coordinates_, 1-based. -
- -- Mouse buttons are numbered: 1=left, 2=middle, 3=right. - Wheel works as two buttons (4 and 5) which generate only press events (no release). -
- -Option | Name | Description |
---|---|---|
`9` | -*X10~mode* | -- This is the most basic tracking mode, in which only button presses are reported. - N = button - 1: (0 left, 1 middle, 2 right, 3, 4 wheel). - | -
`1000` | -*Normal~mode* | -- In Normal mode, both button presses and releases are reported. - The lower two bits of N indicate the button pressed: - `00b` (0) left, `01b` (1) middle, `10b` (2) right, `11b` (3) button release. - Wheel buttons are reported as 0 and 1 with added 64 (e.g. 64 and 65). - Normal mode also supports tracking of modifier keys, which are added to N as bit masks: - 4=_Shift_, 8=_Meta/Alt_, 16=_Control/Cmd_. Example: middle button with _Shift_ = 1 + 4 = `101b` (5). - | -
`1002` | -*Button-Event tracking* | -- This is similar to Normal mode (`1000`), but mouse motion with a button held is also reported. - A motion event is generated when the mouse cursor moves between screen character cells. - A motion event has the same N as a press event, but 32 is added. - For example, drag-drop event with the middle button will produce N = 1 (press), 33 (dragging) and 3 (release). - | -
`1003` | -*Any-Event tracking* | -- This mode is almost identical to Button Event tracking (1002), but motion events - are sent even when no mouse buttons are held. This could be used to draw on-screen mouse cursor, for example. - Motion events with no buttons will use N = 32 + _11b_ (35). - | -
`1004` | -*Focus~tracking* | -- Focus tracking is a separate function from the other mouse tracking modes, therefore they can be enabled together. - Focus tracking reports when the terminal window (in Xterm) gets or loses focus, or in ESPTerm's case, when any - user is connected. This can be used to pause/resume a game or on-screen animations. - Focus tracking mode sends `CSI I` when the terminal receives, and `CSI O` when it loses focus. - | -
- The following encoding schemes can be used with any of the tracking modes (except Focus tracking, which is not affected). -
- -Option | Name | Description |
---|---|---|
-- | -*Normal~encoding* | -- This is the default encoding scheme used when no other option is selected. - In this mode, a mouse report has the format `CSI M _n_ _x_ _y_`, - where _n_, _x_ and _y_ are characters with ASCII value = 32 (space) + the respective number, e.g. - 0 becomes 32 (space), 1 becomes 33 (!). The reason for adding 32 is to avoid producing control characters. - Example: `\e[M !!` - left button press at coordinates 1,1 when using X10 mode. - | -
`1005` | -*UTF-8~encoding* | -- This scheme should encode each of the numbers as a UTF-8 code point, expanding the maximum possible value. - Since ESPTerm's screen size is limited and this has no practical benefit, this serves simply as an alias - to the normal scheme. - | -
`1006` | -*SGR~encoding* | -- In SGR encoding, the response looks like a SGR sequence with the three numbers as semicolon-separated - ASCII values. In this case 32 is not added like in the Normal and UTF-8 schemes, because - it would serve nor purpose here. Also, button release is not reported as 11b, - but using the normal button code while changing the final SGR character: `M` for button press - and `m` for button release. Example: `\e[2;80;24m` - the right button was released - at row 80, column 24. - | -
`1015` | -*URXVT~encoding* | -- This is similar to SGR encoding, but the final character is always `M` and the numbers are - like in the Normal scheme, with 32 added. This scheme has no real advantage over the previous schemes and - was added solely for completeness. - | -
- The coordinates are 1-based, origin is top left. The cursor can move within the entire screen, - or in the active Scrolling Region if Origin Mode is enabled. -
- -After writing a character, the cursor advances to the right. If it has reached the end of the row, - it stays on the same line, but writing the next character makes it jump to the start of the next - line first, scrolling up if needed. If Auto-wrap mode is disabled, the cursor never wraps or scrolls - the screen. -
- -- *Legend:* - Italic letters such as _n_ are ASCII numbers that serve as arguments, separated with a semicolon. - If an argument is left out, it's treated as 0 or 1, depending on what makes sense for the command. -
- -Code | Meaning |
---|---|
-
- \e[nA \\
- \e[nB \\
- \e[nC \\
- \e[nD
-
- |
- Move cursor up (`A`), down (`B`), right (`C`), left (`D`) | -
-
- \e[nF \\
- \e[nE
-
- |
- Go _n_ lines up (`F`) or down (`E`), start of line | -
-
- \e[rd \\
- \e[cG \\
- \e[r;cH
-
- |
- - Go to absolute position - row (`d`), column (`G`), or both (`H`). Use `\e[H` to go to 1,1. - | -
- `\e[6n` - | -- Query cursor position. Sent back as `\e[r;cR`. - | -
Code | Meaning |
---|---|
-
- \e[s \\
- \e[u
-
- |
- Save (`s`) or restore (`u`) cursor position | -
-
- \e7 \\
- \e8
-
- |
- Save (`7`) or restore (`8`) cursor position and attributes | -
Code | Meaning |
---|---|
- `\e[a;br` - | -- Set scrolling region to rows _a_ through _b_ and go to 1,1. By default, the - scrolling region spans the entire screen height. The cursor can leave the region using - absolute position commands, unless Origin Mode (see below) is active. - | -
-
- \e[?6h \\
- \e[?6l
-
- |
- - Enable (`h`) or disable (`l`) Origin Mode and go to 1,1. In Origin Mode, all coordinates - are relative to the Scrolling Region and the cursor can't leave the region. - | -
-
- \e[nS \\
- \e[nT
-
- |
- - Move contents of the Scrolling Region up (`S`) or down (`T`), pad with empty - lines of the current background color. - | -
Code | Meaning |
---|---|
- `\eH` - | -- Set tab stop at the current column. There are, by default, tabs every 8 columns. - | -
-
- \e[nI \\
- \e[nZ
-
- |
- Advance (`I`) or go back (`Z`) _n_ tab stops or end/start of line. ASCII _TAB_ (9) is equivalent to \e[1I |
-
-
- \e[0g \\
- \e[3g \\
-
- |
- Clear tab stop at the current column (`0`), or all columns (`3`). | -
Code | Meaning |
---|---|
-
- \e[?7h \\
- \e[?7l
-
- |
- Enable (`h`) or disable (`l`) cursor auto-wrap and screen auto-scroll | -
-
- \e[?25h \\
- \e[?25l
-
- |
- Show (`h`) or hide (`l`) the cursor | -
- Legend: - Italic letters such as _n_ are ASCII numbers that serve as arguments, separated with a semicolon. - If an argument is left out, it's treated as 0 or 1, depending on what makes sense for the command. -
- -Code | Meaning |
---|---|
- `\e[mJ` - | -- Clear part of screen. _m_: 0 - from cursor, 1 - to cursor, 2 - all - | -
- `\e[mK` - | -- Erase part of line. _m_: 0 - from cursor, 1 - to cursor, 2 - all - | -
- `\e[nX` | -- Erase _n_ characters in line. - | -
-
- \e[nL \\
- \e[nM
-
- |
- - Insert (`L`) or delete (`M`) _n_ lines. Following lines are pulled up or pushed down. - | -
-
- \e[n@ \\
- \e[nP
-
- |
- - Insert (`@`) or delete (`P`) _n_ characters. The rest of the line is pulled left or pushed right. - Characters going past the end of line are lost. - | -
- ESPTerm implements Alternate Character Sets as a way to print box drawing characters - and special symbols. A character set can change what each received ASCII character - is printed as on the screen (eg. "{" is "ฯ" in codepage `0`). The implementation is based - on the original VT devices. - Since ESPTerm also fully supports UTF-8, you can probably ignore this feature and use - Unicode directly. It's added for compatibility with some programs that use this. -
- -The following codepages are implemented:
- -To see what character maps to which symbol, look in the source code or try it. All codepages use codes 32-127, 32 being space.
- -
- There are two character set slots, G0 and G1.
- Those slots are selected as active using ASCII codes Shift In and Shift Out (those originally served for shifting
- a red-black typewriter tape). Each slot (G0 and G1) can have a different codepage assigned. G0 and G1 and the active slot number are
- saved and restored with the cursor and cleared with a screen reset (\ec
).
-
The following commands are used:
- -Code | Meaning |
---|---|
`\e(x` | -Set G0 = codepage x | -
`\e)x` | -Set G1 = codepage x | -
_SO_ (14) | -Activate G0 | -
_SI_ (15) | -Activate G1 | -
- It's possible to dynamically change the screen title text and action button labels. - Setting an empty label to a button makes it look disabled. The buttons send ASCII 1-5 when clicked. - Those changes are not retained after restart. -
- -Code | Meaning |
---|---|
`\ec` | -- Clear screen, reset attributes and cursor. - The screen size, title and button labels remain unchanged. - | -
`\e[5n` | -- Query device status, ESPTerm replies with `\e[0n` "device is OK". - Can be used to check if the terminal has booted up and is ready to receive commands. - | -
_CAN_ (24) | -- This ASCII code is not a command, but is sent by ESPTerm when it becomes ready to receive commands. - When this code is received on the UART, it means ESPTerm has restarted and is ready. Use this to detect - spontaneous restarts which require a full screen repaint. - | -
`\e]0;title\a` | -Set screen title (this is a standard OSC command) | -
-
- \e]81;btn1\a \\
- \e]82;btn2\a \\
- \e]83;btn3\a \\
- \e]84;btn4\a \\
- \e]85;btn5\a \\
-
- |
- - Set button 1-5 label - eg.`\e]81;Yes\a` - sets the first button text to "Yes". - | -
`\e[8;r;ct` | -Set screen size (this is a command borrowed from xterm) | -
+ ESPTerm implements Alternate Character Sets as a way to print box drawing characters + and special symbols. A character set can change what each received ASCII character + is printed as on the screen (eg. "{" is "ฯ" in codepage `0`). The implementation is based + on the original VT devices. +
+ ++ Since ESPTerm also supports UTF-8, this feature is the most useful for applications + which can't print UTF-8 or already use alternate character sets for historical reasons. +
+ ++ All codepages use codes 32-127, 32 being space. A character with no entry in the active codepage + stays unchanged. +
+ + $cp) { + echo "+ There are two character set slots, G0 and G1. + Those slots are selected as active using ASCII codes Shift In and Shift Out (those originally served for shifting + a red-black typewriter tape). Often only G0 is used for simplicity. +
+ +
+ Each slot (G0 and G1) can have a different codepage assigned. G0 and G1 and the active slot number are
+ saved and restored with the cursor and cleared with a screen reset (\ec
).
+
The following commands are used:
+ +Code | Meaning |
---|---|
`\e(x` | +Set G0 = codepage x | +
`\e)x` | +Set G1 = codepage x | +
_SO_ (14) | +Activate G0 | +
_SI_ (15) | +Activate G1 | +
+ The coordinates are 1-based, origin is top left. The cursor can move within the entire screen, + or in the active Scrolling Region if Origin Mode is enabled. +
+ +After writing a character, the cursor advances to the right. If it has reached the end of the row, + it stays on the same line, but writing the next character makes it jump to the start of the next + line first, scrolling up if needed. If Auto-wrap mode is disabled, the cursor never wraps or scrolls + the screen. +
+ ++ *Legend:* + Italic letters such as _n_ are ASCII numbers that serve as arguments, separated with a semicolon. + If an argument is left out, it's treated as 0 or 1, depending on what makes sense for the command. +
+ +Code | Meaning |
---|---|
+
+ \e[nA \\
+ \e[nB \\
+ \e[nC \\
+ \e[nD
+
+ |
+ Move cursor up (`A`), down (`B`), right (`C`), left (`D`) | +
+
+ \e[nF \\
+ \e[nE
+
+ |
+ Go _n_ lines up (`F`) or down (`E`), start of line | +
+
+ \e[rd \\
+ \e[cG \\
+ \e[r;cH
+
+ |
+ + Go to absolute position - row (`d`), column (`G`), or both (`H`). Use `\e[H` to go to 1,1. + | +
+ `\e[6n` + | ++ Query cursor position. Sent back as `\e[r;cR`. + | +
Code | Meaning |
---|---|
+
+ \e[s \\
+ \e[u
+
+ |
+ Save (`s`) or restore (`u`) cursor position | +
+
+ \e7 \\
+ \e8
+
+ |
+ Save (`7`) or restore (`8`) cursor position and attributes | +
Code | Meaning |
---|---|
+ `\e[a;br` + | ++ Set scrolling region to rows _a_ through _b_ and go to 1,1. By default, the + scrolling region spans the entire screen height. The cursor can leave the region using + absolute position commands, unless Origin Mode (see below) is active. + | +
+
+ \e[?6h \\
+ \e[?6l
+
+ |
+ + Enable (`h`) or disable (`l`) Origin Mode and go to 1,1. In Origin Mode, all coordinates + are relative to the Scrolling Region and the cursor can't leave the region. + | +
+
+ \e[nS \\
+ \e[nT
+
+ |
+ + Move contents of the Scrolling Region up (`S`) or down (`T`), pad with empty + lines of the current background color. This is similar to what happens when AutoWrap + is enabled and some text is printed at the very end of the screen. + | +
Code | Meaning |
---|---|
+ `\eH` + | ++ Set tab stop at the current column. There are, by default, tabs every 8 columns. + | +
+
+ \e[nI \\
+ \e[nZ
+
+ |
+ Advance (`I`) or go back (`Z`) _n_ tab stops or end/start of line. ASCII _TAB_ (9) is equivalent to \e[1I |
+
+
+ \e[0g \\
+ \e[3g \\
+
+ |
+ Clear tab stop at the current column (`0`), or all columns (`3`). | +
Code | Meaning |
---|---|
+
+ \e[?7h \\
+ \e[?7l
+
+ |
+ Enable (`h`) or disable (`l`) cursor auto-wrap and screen auto-scroll | +
+
+ \e[?25h \\
+ \e[?25l
+
+ |
+ Show (`h`) or hide (`l`) the cursor | +
+ Legend: + Italic letters such as _n_ are ASCII numbers that serve as arguments, separated with a semicolon. + If an argument is left out, it's treated as 0 or 1, depending on what makes sense for the command. +
+ +Code | Meaning |
---|---|
+ `\e[mJ` + | ++ Clear part of screen. _m_: 0 - from cursor, 1 - to cursor, 2 - all + | +
+ `\e[mK` + | ++ Erase part of line. _m_: 0 - from cursor, 1 - to cursor, 2 - all + | +
+ `\e[nX` | ++ Erase _n_ characters in line. + | +
+
+ \e[nL \\
+ \e[nM
+
+ |
+ + Insert (`L`) or delete (`M`) _n_ lines. Following lines are pulled up or pushed down. + | +
+
+ \e[n@ \\
+ \e[nP
+
+ |
+ + Insert (`@`) or delete (`P`) _n_ characters. The rest of the line is pulled left or pushed right. + Characters going past the end of line are lost. + | +
+ It's possible to dynamically change the screen title text and action button labels. + Setting an empty label to a button makes it look disabled. The buttons send ASCII 1-5 when clicked. + Those changes are not retained after restart. +
+ +Code | Meaning |
---|---|
`\ec` | ++ Clear screen, reset attributes and cursor. + The screen size, title and button labels remain unchanged. + | +
`\e[5n` | ++ Query device status, ESPTerm replies with `\e[0n` "device is OK". + Can be used to check if the terminal has booted up and is ready to receive commands. + | +
_CAN_ (24) | ++ This ASCII code is not a command, but is sent by ESPTerm when it becomes ready to receive commands. + When this code is received on the UART, it means ESPTerm has restarted and is ready. Use this to detect + spontaneous restarts which require a full screen repaint. + | +
`\e]0;title\a` | +Set screen title (this is a standard OSC command) | +
+
+ \e]81;btn1\a \\
+ \e]82;btn2\a \\
+ \e]83;btn3\a \\
+ \e]84;btn4\a \\
+ \e]85;btn5\a \\
+
+ |
+ + Set button 1-5 label - eg.`\e]81;Yes\a` + sets the first button text to "Yes". + | +
+
+ \e[?800h \\
+ \e[?800l
+
+ |
+ + Show (`h`) or hide (`l`) action buttons (the blue buttons under the screen). + | +
+
+ \e[?801h \\
+ \e[?801l
+
+ |
+ + Show (`h`) or hide (`l`) menu/help links under the screen. + | +
`\e[8;r;ct` | +Set screen size (this is a command borrowed from xterm) | +
+ The user can input text using their keyboard, or on Android, using the on-screen keyboard which is open using + a button beneath the screen. Supported are all printable characters, as well as many control keys, such as arrows, _Ctrl+letters_ + and function keys. Sequences sent by function keys are based on VT102 and Xterm. +
+ ++ The codes sent by _Home_, _End_, _F1-F4_ and cursor keys are affected by various keyboard modes (_Application Cursor Keys_, + _Application Numpad Mode_, _SS3 Fn Keys Mode_). Some can be set in the Terminal Settings, + others via commands. +
+ ++ Here are some examples of control key codes: +
+ +Key | Code | Key | Code |
---|---|---|---|
Up | +`\e[A`,~`\eOA` | +F1 | +`\eOP`,~`\e[11\~` | +
Down | +`\e[B`,~`\eOB` | +F2 | +`\eOQ`,~`\e[12\~` | +
Right | +`\e[C`,~`\eOC` | +F3 | +`\eOR`,~`\e[13\~` | +
Left | +`\e[D`,~`\eOD` | +F4 | +`\eOS`,~`\e[14\~` | +
Home | +`\eOH`,~`\e[H`,~`\e[1\~` | +F5 | +`\e[15~` | +
End | +`\eOF`,~`\e[F`,~`\e[4\~` | +F6 | +`\e[17\~` | +
Insert | +`\e[2\~` | +F7 | +`\e[18\~` | +
Delete | +`\e[3\~` | +F8 | +`\e[19\~` | +
Page Up | +`\e[5\~` | +F9 | +`\e[20\~` | +
Page Down | +`\e[6\~` | +F10 | +`\e[21\~` | +
Enter | +`\r` (13) | +F11 | +`\e[23\~` | +
Ctrl+Enter | +`\n` (10) | +F12 | +`\e[24\~` | +
Tab | +`\t` (9) | +ESC | +`\e` (27) | +
Backspace | +`\b` (8) | +Ctrl+A..Z | +ASCII 1-26 | +
+ The blue buttons under the screen send ASCII codes 1, 2, 3, 4, 5, which incidentally + correspond to _Ctrl+A,B,C,D,E_. This choice was made to make button press parsing as simple as possible. +
+ ++ ESPTerm implements standard mouse tracking modes based on Xterm. Mouse tracking can be used to implement + powerful user interactions such as on-screen buttons, draggable sliders or dials, menus etc. ESPTerm's + mouse tracking was tested using VTTest and should be compatible with all terminal applications + that request mouse tracking. +
+ ++ Mouse can be tracked in different ways; some are easier to parse, others more powerful. The coordinates + can also be encoded in different ways. All mouse tracking options are set using option commands: + `CSI ? _n_ h` to enable, `CSI ? _n_ l` to disable option _n_. +
+ ++ All tracking modes produce three numbers which are then encoded and send to the application. + First is the _event number_ N, then the _X and Y coordinates_, 1-based. +
+ ++ Mouse buttons are numbered: 1=left, 2=middle, 3=right. + Wheel works as two buttons (4 and 5) which generate only press events (no release). +
+ +Option | Name | Description |
---|---|---|
`9` | +*X10~mode* | ++ This is the most basic tracking mode, in which only button presses are reported. + N = button - 1: (0 left, 1 middle, 2 right, 3, 4 wheel). + | +
`1000` | +*Normal~mode* | ++ In Normal mode, both button presses and releases are reported. + The lower two bits of N indicate the button pressed: + `00b` (0) left, `01b` (1) middle, `10b` (2) right, `11b` (3) button release. + Wheel buttons are reported as 0 and 1 with added 64 (e.g. 64 and 65). + Normal mode also supports tracking of modifier keys, which are added to N as bit masks: + 4=_Shift_, 8=_Meta/Alt_, 16=_Control/Cmd_. Example: middle button with _Shift_ = 1 + 4 = `101b` (5). + | +
`1002` | +*Button-Event tracking* | ++ This is similar to Normal mode (`1000`), but mouse motion with a button held is also reported. + A motion event is generated when the mouse cursor moves between screen character cells. + A motion event has the same N as a press event, but 32 is added. + For example, drag-drop event with the middle button will produce N = 1 (press), 33 (dragging) and 3 (release). + | +
`1003` | +*Any-Event tracking* | ++ This mode is almost identical to Button Event tracking (1002), but motion events + are sent even when no mouse buttons are held. This could be used to draw on-screen mouse cursor, for example. + Motion events with no buttons will use N = 32 + _11b_ (35). + | +
`1004` | +*Focus~tracking* | ++ Focus tracking is a separate function from the other mouse tracking modes, therefore they can be enabled together. + Focus tracking reports when the terminal window (in Xterm) gets or loses focus, or in ESPTerm's case, when any + user is connected. This can be used to pause/resume a game or on-screen animations. + Focus tracking mode sends `CSI I` when the terminal receives, and `CSI O` when it loses focus. + | +
+ The following encoding schemes can be used with any of the tracking modes (except Focus tracking, which is not affected). +
+ +Option | Name | Description |
---|---|---|
-- | +*Normal~encoding* | ++ This is the default encoding scheme used when no other option is selected. + In this mode, a mouse report has the format `CSI M _n_ _x_ _y_`, + where _n_, _x_ and _y_ are characters with ASCII value = 32 (space) + the respective number, e.g. + 0 becomes 32 (space), 1 becomes 33 (!). The reason for adding 32 is to avoid producing control characters. + Example: `\e[M !!` - left button press at coordinates 1,1 when using X10 mode. + | +
`1005` | +*UTF-8~encoding* | ++ This scheme should encode each of the numbers as a UTF-8 code point, expanding the maximum possible value. + Since ESPTerm's screen size is limited and this has no practical benefit, this serves simply as an alias + to the normal scheme. + | +
`1006` | +*SGR~encoding* | ++ In SGR encoding, the response looks like a SGR sequence with the three numbers as semicolon-separated + ASCII values. In this case 32 is not added like in the Normal and UTF-8 schemes, because + it would serve nor purpose here. Also, button release is not reported as 11b, + but using the normal button code while changing the final SGR character: `M` for button press + and `m` for button release. Example: `\e[2;80;24m` - the right button was released + at row 80, column 24. + | +
`1015` | +*URXVT~encoding* | ++ This is similar to SGR encoding, but the final character is always `M` and the numbers are + like in the Normal scheme, with 32 added. This scheme has no real advantage over the previous schemes and + was added solely for completeness. + | +
+ ESPTerm emulates VT102 (pictured) with some additions from later VT models and Xterm. + All commonly used attributes and commands are supported. + ESPTerm is capable of displaying ncurses applications such as _Midnight Commander_ using _agetty_. +
+ ++ ESPTerm accepts UTF-8 characters received on the communication UART and displays them on the screen, + interpreting some codes as Control Characters. Those are e.g. _Carriage Return_ (13), _Line Feed_ (10), + _Tab_ (9), _Backspace_ (8) and _Bell_ (7). +
+ ++ Escape sequences start with the control character _ESC_ (27), + followed by any number of ASCII characters forming the body of the command. +
+ ++ Examples on this help page use the following symbols for special characters and command types:\\ + (spaces are for clarity only, _DO NOT_ include them in the commands!) +
+ +Name | Symbol | ASCII | C string | Function |
---|---|---|---|---|
*ESC* | +`\e` | +`ESC` (27) | +`"\e"`, `"\x1b"`, `"\033"` | +Introduces an escape sequence. _(Note: `\e` is a GCC extension)_ | +
*Bell* | +`\a` | +`BEL`~(7) | +`"\a"`, `"\x7"`, `"\07"` | +Audible beep | +
*String Terminator* | +`ST` | +`ESC \`~(27~92) _or_~`\a`~(7) |
+ `"\x1b\\"`, `"\a"` | +Terminates a string command (`\a` can be used as an alternative) | +
*Control Sequence Introducer* | +`CSI` | +`ESC [` | +`"\x1b["` | +Starts a CSI command. Examples: `\e[?7;10h`, `\e[2J` | +
*Operating System Command* | +`OSC` | +`ESC ]` | +`"\x1b]"` | +Starts an OSC command. Is followed by a command string terminated by `ST`. Example: `\e]0;My Screen Title\a` | +
*Select Graphic Rendition* | +`SGR` | +`CSI n;n;nm` | +`"\x1b[1;2;3m"` | +Set text attributes, like color or style. 0 to 10 numbers can be used, `\e[m` is treated as `\e[0m` | +
There are also some other commands that don't follow the CSI, SGR or OSC pattern, such as `\e7` or + `\e#8`. A list of the most important escape sequences is presented in the following sections.
++ The initial screen size, title text and button labels can be configured in Terminal Settings. +
+ ++ Screen updates are sent to the browser through a WebSocket after some time of inactivity on the communication UART + (called "Redraw Delay"). After an update is sent, at least a time of "Redraw Cooldown" must elapse before the next + update can be sent. Those delays are used is to avoid burdening the server with tiny updates during a large screen + repaint. If you experience issues (broken image due to dropped bytes), try adjusting those config options. It may also + be useful to try different baud rates. +
++ Colors are set using SGR commands (like `\e[10;20;30m`). The following tables list the SGR codes to use. + Selected colors are used for any new text entered, as well as for empty space when using line and screen clearing commands. + The configured default colors can be restored using SGR 39 for foreground and SGR 49 for background. +
+ ++ The actual color representation depends on a color theme which + can be selected in Terminal Settings. +
+ ++ All text attributes are set using SGR commands like `\e[10;20;30m`, with up to 10 numbers separated by semicolons. + To restore all attributes to their default states, use SGR 0: `\e[0m` or `\e[m`. +
+ +Those are the supported text attributes SGR codes:
+ +Style | Enable | Disable |
---|---|---|
Bold | 1 | 21, 22 |
Faint | 2 | 22 |
Italic | 3 | 23 |
Underlined | 4 | 24 |
Blink | 5 | 25 |
Inverse | 7 | 27 |
9 | 29 | |
๐๐ฏ๐๐จ๐ฑ๐ฒ๐ฏ | 20 | 23 |