implemented a couple new ESC codes and stubs for 4 others

pull/111/merge
Ondřej Hruška 8 years ago
parent c8067122d5
commit 7b94eef448
  1. 318
      user/ansi_parser.c
  2. 18
      user/ansi_parser.rl
  3. 124
      user/ansi_parser_callbacks.c
  4. 56
      user/screen.c
  5. 31
      user/screen.h

@ -11,23 +11,25 @@ static const char _ansi_actions[] = {
0, 1, 0, 1, 1, 1, 2, 1, 0, 1, 0, 1, 1, 1, 2, 1,
3, 1, 4, 1, 5, 1, 6, 1, 3, 1, 4, 1, 5, 1, 6, 1,
7, 1, 8, 1, 9, 1, 10, 1, 7, 1, 8, 1, 9, 1, 10, 1,
11, 1, 12, 1, 13, 2, 9, 10, 11, 1, 12, 1, 13, 1, 14, 2,
2, 9, 11 10, 11, 2, 10, 12
}; };
static const char _ansi_eof_actions[] = { static const char _ansi_eof_actions[] = {
0, 13, 13, 13, 13, 13, 13, 13, 0, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 0, 0, 0, 0, 0 13, 13, 13, 13, 0, 0, 0, 0,
0, 0, 0
}; };
static const int ansi_start = 1; static const int ansi_start = 1;
static const int ansi_first_final = 25; static const int ansi_first_final = 28;
static const int ansi_error = 0; static const int ansi_error = 0;
static const int ansi_en_CSI_body = 4; static const int ansi_en_CSI_body = 4;
static const int ansi_en_OSC_body = 6; static const int ansi_en_OSC_body = 6;
static const int ansi_en_TITLE_body = 26;
static const int ansi_en_main = 1; static const int ansi_en_main = 1;
@ -80,7 +82,7 @@ ansi_parser(const char *newdata, size_t len)
// Init Ragel on the first run // Init Ragel on the first run
if (cs == -1) { if (cs == -1) {
/* #line 84 "user/ansi_parser.c" */ /* #line 86 "user/ansi_parser.c" */
{ {
cs = ansi_start; cs = ansi_start;
} }
@ -97,7 +99,7 @@ ansi_parser(const char *newdata, size_t len)
// The parser // The parser
/* #line 101 "user/ansi_parser.c" */ /* #line 103 "user/ansi_parser.c" */
{ {
const char *_acts; const char *_acts;
unsigned int _nacts; unsigned int _nacts;
@ -117,6 +119,7 @@ case 2:
case 35: goto tr3; case 35: goto tr3;
case 91: goto tr5; case 91: goto tr5;
case 93: goto tr6; case 93: goto tr6;
case 107: goto tr7;
} }
if ( (*p) < 65 ) { if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 ) if ( 48 <= (*p) && (*p) <= 57 )
@ -131,146 +134,169 @@ case 0:
goto _out; goto _out;
case 3: case 3:
if ( 48 <= (*p) && (*p) <= 57 ) if ( 48 <= (*p) && (*p) <= 57 )
goto tr7; goto tr8;
goto tr2; goto tr2;
case 25: case 28:
if ( (*p) == 27 ) if ( (*p) == 27 )
goto tr1; goto tr1;
goto tr0; goto tr0;
case 4: case 4:
if ( (*p) == 59 ) if ( (*p) == 59 )
goto tr10; goto tr11;
if ( (*p) < 60 ) { if ( (*p) < 60 ) {
if ( (*p) > 47 ) { if ( (*p) > 47 ) {
if ( 48 <= (*p) && (*p) <= 57 ) if ( 48 <= (*p) && (*p) <= 57 )
goto tr9; goto tr10;
} else if ( (*p) >= 32 ) } else if ( (*p) >= 32 )
goto tr8; goto tr9;
} else if ( (*p) > 64 ) { } else if ( (*p) > 64 ) {
if ( (*p) > 90 ) { if ( (*p) > 90 ) {
if ( 97 <= (*p) && (*p) <= 122 ) if ( 97 <= (*p) && (*p) <= 122 )
goto tr11; goto tr12;
} else if ( (*p) >= 65 ) } else if ( (*p) >= 65 )
goto tr11; goto tr12;
} else } else
goto tr8; goto tr9;
goto tr2; goto tr2;
case 5: case 5:
if ( (*p) == 59 ) if ( (*p) == 59 )
goto tr10; goto tr11;
if ( (*p) < 65 ) { if ( (*p) < 65 ) {
if ( 48 <= (*p) && (*p) <= 57 ) if ( 48 <= (*p) && (*p) <= 57 )
goto tr9; goto tr10;
} else if ( (*p) > 90 ) { } else if ( (*p) > 90 ) {
if ( 97 <= (*p) && (*p) <= 122 ) if ( 97 <= (*p) && (*p) <= 122 )
goto tr11; goto tr12;
} else } else
goto tr11; goto tr12;
goto tr2; goto tr2;
case 26: case 29:
goto tr2; goto tr2;
case 6: case 6:
switch( (*p) ) { switch( (*p) ) {
case 66: goto tr12; case 48: goto tr13;
case 84: goto tr13; case 66: goto tr14;
case 87: goto tr14; case 84: goto tr15;
case 87: goto tr16;
} }
goto tr2; goto tr2;
case 7: case 7:
if ( (*p) == 84 ) if ( (*p) == 59 )
goto tr15;
goto tr2;
case 8:
if ( (*p) == 78 )
goto tr16;
goto tr2;
case 9:
if ( 48 <= (*p) && (*p) <= 57 )
goto tr17; goto tr17;
goto tr2; goto tr2;
case 10: case 8:
if ( (*p) == 61 )
goto tr18;
goto tr2;
case 11:
switch( (*p) ) { switch( (*p) ) {
case 7: goto tr20; case 7: goto tr19;
case 27: goto tr21; case 27: goto tr20;
} }
goto tr19; goto tr18;
case 27: case 30:
switch( (*p) ) { switch( (*p) ) {
case 7: goto tr20; case 7: goto tr19;
case 27: goto tr21; case 27: goto tr20;
} }
goto tr19; goto tr18;
case 12: case 9:
if ( (*p) == 92 ) if ( (*p) == 92 )
goto tr22; goto tr21;
goto tr2; goto tr2;
case 28: case 31:
goto tr2;
case 13:
if ( (*p) == 73 )
goto tr23;
goto tr2; goto tr2;
case 14: case 10:
if ( (*p) == 84 ) if ( (*p) == 84 )
goto tr24; goto tr22;
goto tr2; goto tr2;
case 15: case 11:
if ( (*p) == 76 ) if ( (*p) == 78 )
goto tr25; goto tr23;
goto tr2; goto tr2;
case 16: case 12:
if ( (*p) == 69 ) if ( 48 <= (*p) && (*p) <= 57 )
goto tr26; goto tr24;
goto tr2; goto tr2;
case 17: case 13:
if ( (*p) == 61 ) if ( (*p) == 61 )
goto tr27; goto tr25;
goto tr2; goto tr2;
case 18: case 14:
switch( (*p) ) { switch( (*p) ) {
case 7: goto tr29; case 7: goto tr27;
case 27: goto tr30; case 27: goto tr28;
} }
goto tr28; goto tr26;
case 29: case 32:
switch( (*p) ) { switch( (*p) ) {
case 7: goto tr29; case 7: goto tr27;
case 27: goto tr30; case 27: goto tr28;
} }
goto tr28; goto tr26;
case 19: case 15:
if ( (*p) == 92 ) if ( (*p) == 92 )
goto tr29;
goto tr2;
case 16:
if ( (*p) == 73 )
goto tr30;
goto tr2;
case 17:
if ( (*p) == 84 )
goto tr31; goto tr31;
goto tr2; goto tr2;
case 20: case 18:
if ( 48 <= (*p) && (*p) <= 57 ) if ( (*p) == 76 )
goto tr32; goto tr32;
goto tr2; goto tr2;
case 21: case 19:
if ( (*p) == 59 ) if ( (*p) == 69 )
goto tr33; goto tr33;
goto tr2;
case 20:
if ( (*p) == 61 )
goto tr34;
goto tr2;
case 21:
if ( 48 <= (*p) && (*p) <= 57 ) if ( 48 <= (*p) && (*p) <= 57 )
goto tr32; goto tr35;
goto tr2; goto tr2;
case 22: case 22:
if ( (*p) == 59 )
goto tr36;
if ( 48 <= (*p) && (*p) <= 57 ) if ( 48 <= (*p) && (*p) <= 57 )
goto tr34; goto tr35;
goto tr2; goto tr2;
case 23: case 23:
if ( 48 <= (*p) && (*p) <= 57 )
goto tr37;
goto tr2;
case 24:
switch( (*p) ) { switch( (*p) ) {
case 7: goto tr35; case 7: goto tr38;
case 27: goto tr36; case 27: goto tr39;
} }
if ( 48 <= (*p) && (*p) <= 57 ) if ( 48 <= (*p) && (*p) <= 57 )
goto tr34; goto tr37;
goto tr2; goto tr2;
case 24: case 25:
if ( (*p) == 92 ) if ( (*p) == 92 )
goto tr35; goto tr38;
goto tr2;
case 26:
switch( (*p) ) {
case 7: goto tr41;
case 27: goto tr42;
}
goto tr40;
case 33:
switch( (*p) ) {
case 7: goto tr41;
case 27: goto tr42;
}
goto tr40;
case 27:
if ( (*p) == 92 )
goto tr43;
goto tr2;
case 34:
goto tr2; goto tr2;
} }
@ -278,56 +304,64 @@ case 24:
tr0: cs = 1; goto f1; tr0: cs = 1; goto f1;
tr1: cs = 2; goto _again; tr1: cs = 2; goto _again;
tr3: cs = 3; goto _again; tr3: cs = 3; goto _again;
tr8: cs = 5; goto f6;
tr9: cs = 5; goto f7; tr9: cs = 5; goto f7;
tr10: cs = 5; goto f8; tr10: cs = 5; goto f8;
tr12: cs = 7; goto _again; tr11: cs = 5; goto f9;
tr15: cs = 8; goto _again; tr13: cs = 7; goto _again;
tr16: cs = 9; goto _again; tr17: cs = 8; goto _again;
tr17: cs = 10; goto f7; tr18: cs = 8; goto f11;
tr18: cs = 11; goto _again; tr20: cs = 9; goto _again;
tr19: cs = 11; goto f10; tr14: cs = 10; goto _again;
tr21: cs = 12; goto _again; tr22: cs = 11; goto _again;
tr13: cs = 13; goto _again; tr23: cs = 12; goto _again;
tr23: cs = 14; goto _again; tr24: cs = 13; goto f8;
tr24: cs = 15; goto _again; tr25: cs = 14; goto _again;
tr25: cs = 16; goto _again; tr26: cs = 14; goto f11;
tr26: cs = 17; goto _again; tr28: cs = 15; goto _again;
tr27: cs = 18; goto _again; tr15: cs = 16; goto _again;
tr28: cs = 18; goto f10; tr30: cs = 17; goto _again;
tr30: cs = 19; goto _again; tr31: cs = 18; goto _again;
tr14: cs = 20; goto _again; tr32: cs = 19; goto _again;
tr32: cs = 21; goto f7; tr33: cs = 20; goto _again;
tr33: cs = 22; goto f8; tr16: cs = 21; goto _again;
tr34: cs = 23; goto f7; tr35: cs = 22; goto f8;
tr36: cs = 24; goto _again; tr36: cs = 23; goto f9;
tr4: cs = 25; goto f2; tr37: cs = 24; goto f8;
tr5: cs = 25; goto f3; tr39: cs = 25; goto _again;
tr6: cs = 25; goto f4; tr40: cs = 26; goto f11;
tr7: cs = 25; goto f5; tr42: cs = 27; goto _again;
tr11: cs = 26; goto f9; tr4: cs = 28; goto f2;
tr20: cs = 27; goto f11; tr5: cs = 28; goto f3;
tr22: cs = 28; goto f12; tr6: cs = 28; goto f4;
tr31: cs = 28; goto f14; tr7: cs = 28; goto f5;
tr35: cs = 28; goto f15; tr8: cs = 28; goto f6;
tr29: cs = 29; goto f13; tr12: cs = 29; goto f10;
tr19: cs = 30; goto f12;
tr34: cs = 31; goto f5;
tr21: cs = 31; goto f13;
tr29: cs = 31; goto f15;
tr38: cs = 31; goto f16;
tr27: cs = 32; goto f14;
tr41: cs = 33; goto f12;
tr43: cs = 34; goto f13;
f1: _acts = _ansi_actions + 1; goto execFuncs; f1: _acts = _ansi_actions + 1; goto execFuncs;
f3: _acts = _ansi_actions + 3; goto execFuncs; f3: _acts = _ansi_actions + 3; goto execFuncs;
f6: _acts = _ansi_actions + 5; goto execFuncs; f7: _acts = _ansi_actions + 5; goto execFuncs;
f7: _acts = _ansi_actions + 7; goto execFuncs; f8: _acts = _ansi_actions + 7; goto execFuncs;
f8: _acts = _ansi_actions + 9; goto execFuncs; f9: _acts = _ansi_actions + 9; goto execFuncs;
f9: _acts = _ansi_actions + 11; goto execFuncs; f10: _acts = _ansi_actions + 11; goto execFuncs;
f0: _acts = _ansi_actions + 13; goto execFuncs; f0: _acts = _ansi_actions + 13; goto execFuncs;
f4: _acts = _ansi_actions + 15; goto execFuncs; f4: _acts = _ansi_actions + 15; goto execFuncs;
f15: _acts = _ansi_actions + 17; goto execFuncs; f5: _acts = _ansi_actions + 17; goto execFuncs;
f10: _acts = _ansi_actions + 19; goto execFuncs; f16: _acts = _ansi_actions + 19; goto execFuncs;
f14: _acts = _ansi_actions + 21; goto execFuncs; f11: _acts = _ansi_actions + 21; goto execFuncs;
f12: _acts = _ansi_actions + 23; goto execFuncs; f13: _acts = _ansi_actions + 23; goto execFuncs;
f5: _acts = _ansi_actions + 25; goto execFuncs; f15: _acts = _ansi_actions + 25; goto execFuncs;
f2: _acts = _ansi_actions + 27; goto execFuncs; f6: _acts = _ansi_actions + 27; goto execFuncs;
f13: _acts = _ansi_actions + 29; goto execFuncs; f2: _acts = _ansi_actions + 29; goto execFuncs;
f11: _acts = _ansi_actions + 32; goto execFuncs; f12: _acts = _ansi_actions + 31; goto execFuncs;
f14: _acts = _ansi_actions + 34; goto execFuncs;
execFuncs: execFuncs:
_nacts = *_acts++; _nacts = *_acts++;
@ -409,49 +443,57 @@ execFuncs:
} }
break; break;
case 8: case 8:
/* #line 150 "user/ansi_parser.rl" */ /* #line 151 "user/ansi_parser.rl" */
{
osc_bi = 0;
osc_buffer[0] = '\0';
{cs = 26;goto _again;}
}
break;
case 9:
/* #line 157 "user/ansi_parser.rl" */
{ {
apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]); apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
{cs = 1;goto _again;} {cs = 1;goto _again;}
} }
break; break;
case 9: case 10:
/* #line 155 "user/ansi_parser.rl" */ /* #line 162 "user/ansi_parser.rl" */
{ {
osc_buffer[osc_bi++] = (*p); osc_buffer[osc_bi++] = (*p);
} }
break; break;
case 10: case 11:
/* #line 159 "user/ansi_parser.rl" */ /* #line 166 "user/ansi_parser.rl" */
{ {
osc_buffer[osc_bi++] = '\0'; osc_buffer[osc_bi++] = '\0';
apars_handle_OSC_SetTitle(osc_buffer); apars_handle_OSC_SetTitle(osc_buffer);
{cs = 1;goto _again;} {cs = 1;goto _again;}
} }
break; break;
case 11: case 12:
/* #line 165 "user/ansi_parser.rl" */ /* #line 172 "user/ansi_parser.rl" */
{ {
osc_buffer[osc_bi++] = '\0'; osc_buffer[osc_bi++] = '\0';
apars_handle_OSC_SetButton(csi_n[0], osc_buffer); apars_handle_OSC_SetButton(csi_n[0], osc_buffer);
{cs = 1;goto _again;} {cs = 1;goto _again;}
} }
break; break;
case 12: case 13:
/* #line 193 "user/ansi_parser.rl" */ /* #line 204 "user/ansi_parser.rl" */
{ {
apars_handle_hashCode((*p)); apars_handle_hashCode((*p));
{cs = 1;goto _again;} {cs = 1;goto _again;}
} }
break; break;
case 13: case 14:
/* #line 198 "user/ansi_parser.rl" */ /* #line 209 "user/ansi_parser.rl" */
{ {
apars_handle_shortCode((*p)); apars_handle_shortCode((*p));
{cs = 1;goto _again;} {cs = 1;goto _again;}
} }
break; break;
/* #line 455 "user/ansi_parser.c" */ /* #line 497 "user/ansi_parser.c" */
} }
} }
goto _again; goto _again;
@ -477,7 +519,7 @@ _again:
goto _again;} goto _again;}
} }
break; break;
/* #line 481 "user/ansi_parser.c" */ /* #line 523 "user/ansi_parser.c" */
} }
} }
} }
@ -485,6 +527,8 @@ goto _again;}
_out: {} _out: {}
} }
/* #line 217 "user/ansi_parser.rl" */ /* #line 229 "user/ansi_parser.rl" */
} }
// 'ESC k blah OSC_end' is a shortcut for setting title (k is defined in GNU screen as Title Definition String)

@ -147,6 +147,13 @@ ansi_parser(const char *newdata, size_t len)
fgoto OSC_body; fgoto OSC_body;
} }
# collecting title string; this can also be entered by ESC k
action SetTitle_start {
osc_bi = 0;
osc_buffer[0] = '\0';
fgoto TITLE_body;
}
action OSC_resize { action OSC_resize {
apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]); apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
fgoto main; fgoto main;
@ -168,12 +175,16 @@ ansi_parser(const char *newdata, size_t len)
fgoto main; fgoto main;
} }
# 0; is xterm title hack
OSC_body := ( OSC_body := (
("BTN" digit @CSI_digit '=' (NOESC @OSC_text_char)* OSC_END @OSC_button) | ("BTN" digit @CSI_digit '=' (NOESC @OSC_text_char)* OSC_END @OSC_button) |
("TITLE=" (NOESC @OSC_text_char)* OSC_END @OSC_title) | ("TITLE=" @SetTitle_start) |
("0;" (NOESC @OSC_text_char)* OSC_END @OSC_title) |
('W' (digit @CSI_digit)+ ';' @CSI_semi (digit @CSI_digit)+ OSC_END @OSC_resize) ('W' (digit @CSI_digit)+ ';' @CSI_semi (digit @CSI_digit)+ OSC_END @OSC_resize)
) $!errBadSeq; ) $!errBadSeq;
TITLE_body := (NOESC @OSC_text_char)* OSC_END @OSC_title $!errBadSeq;
action RESET_cmd { action RESET_cmd {
// Reset screen // Reset screen
apars_handle_RESET_cmd(); apars_handle_RESET_cmd();
@ -208,7 +219,8 @@ ansi_parser(const char *newdata, size_t len)
'[' @CSI_start | '[' @CSI_start |
']' @OSC_start | ']' @OSC_start |
'#' digit @HASH_code | '#' digit @HASH_code |
[a-zA-Z0-9] @SHORT_code 'k' @SetTitle_start |
[a-jl-zA-Z0-9] @SHORT_code
) )
)+ $!errBadSeq; )+ $!errBadSeq;
@ -216,3 +228,5 @@ ansi_parser(const char *newdata, size_t len)
#*/ #*/
}%% }%%
} }
// 'ESC k blah OSC_end' is a shortcut for setting title (k is defined in GNU screen as Title Definition String)

@ -9,7 +9,8 @@
#include "screen.h" #include "screen.h"
#include "ansi_parser.h" #include "ansi_parser.h"
#include "uart_driver.h" #include "uart_driver.h"
#include "persist.h"
// screen manpage - https://www.gnu.org/software/screen/manual/html_node/Control-Sequences.html
static char utf_collect[4]; static char utf_collect[4];
static int utf_i = 0; static int utf_i = 0;
@ -93,6 +94,8 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
CSI u RCP Restore Cursor Position CSI u RCP Restore Cursor Position
CSI ?25l DECTCEM Hides the cursor CSI ?25l DECTCEM Hides the cursor
CSI ?25h DECTCEM Shows the cursor CSI ?25h DECTCEM Shows the cursor
and some others
*/ */
int n1 = params[0]; int n1 = params[0];
@ -101,15 +104,22 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
// defaults // defaults
switch (keychar) { switch (keychar) {
case 'A': case 'A': // move
case 'B': case 'B':
case 'C': case 'C':
case 'D': case 'D':
case 'E': case 'E':
case 'F': case 'F':
case 'G': case 'G': // set X
case 'S': case '`':
case 'S': // scrolling
case 'T': case 'T':
case 'X': // clear in line
case 'd': // set Y
case 'L':
case 'M':
case '@':
case 'P':
if (n1 == 0) n1 = 1; if (n1 == 0) n1 = 1;
break; break;
@ -127,35 +137,48 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
switch (keychar) { switch (keychar) {
// CUU CUD CUF CUB // CUU CUD CUF CUB
case 'A': screen_cursor_move(-n1, 0); break; case 'A': screen_cursor_move(-n1, 0, false); break;
case 'B': screen_cursor_move(n1, 0); break; case 'B': screen_cursor_move(n1, 0, false); break;
case 'C': screen_cursor_move(0, n1); break; case 'C': screen_cursor_move(0, n1, false); break;
case 'D': screen_cursor_move(0, -n1); break; case 'D': screen_cursor_move(0, -n1, false); break;
case 'E': // CNL case 'E': // CNL - Cursor Next Line
screen_cursor_move(n1, 0); screen_cursor_move(n1, 0, false);
screen_cursor_set_x(0); screen_cursor_set_x(0);
break; break;
case 'F': // CPL case 'F': // CPL - Cursor Prev Line
screen_cursor_move(-n1, 0); screen_cursor_move(-n1, 0, false);
screen_cursor_set_x(0); screen_cursor_set_x(0);
break; break;
// CHA // Set X
case 'G': case 'G':
screen_cursor_set_x(n1 - 1); break; // 1-based case '`': // alternate code
screen_cursor_set_x(n1 - 1);
break; // 1-based
// Set Y
case 'd':
screen_cursor_set_y(n1 - 1);
break; // 1-based
// clear in line
case 'X':
screen_clear_in_line(n1);
break; // 1-based
// SU, SD // SU, SD - scroll up/down
case 'S': screen_scroll_up(n1); break; case 'S': screen_scroll_up(n1); break;
case 'T': screen_scroll_down(n1); break; case 'T': screen_scroll_down(n1); break;
// CUP,HVP // CUP,HVP - set position
case 'H': case 'H':
case 'f': case 'f':
screen_cursor_set(n1-1, n2-1); break; // 1-based screen_cursor_set(n1-1, n2-1);
break; // 1-based
case 'J': // ED case 'J': // ED - clear screen
if (n1 == 0) { if (n1 == 0) {
screen_clear(CLEAR_TO_CURSOR); screen_clear(CLEAR_TO_CURSOR);
} else if (n1 == 1) { } else if (n1 == 1) {
@ -166,7 +189,7 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
} }
break; break;
case 'K': // EL case 'K': // EL - clear line
if (n1 == 0) { if (n1 == 0) {
screen_clear_line(CLEAR_TO_CURSOR); screen_clear_line(CLEAR_TO_CURSOR);
} else if (n1 == 1) { } else if (n1 == 1) {
@ -176,11 +199,11 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
} }
break; break;
// SCP, RCP // SCP, RCP - save/restore position
case 's': screen_cursor_save(0); break; case 's': screen_cursor_save(0); break;
case 'u': screen_cursor_restore(0); break; case 'u': screen_cursor_restore(0); break;
case 'n': case 'n': // queries
if (n1 == 6) { if (n1 == 6) {
// Query cursor position // Query cursor position
char buf[20]; char buf[20];
@ -197,7 +220,7 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
// DECTCEM feature enable / disable // DECTCEM feature enable / disable
case 'h': case 'h': // feature enable
if (leadchar == '?') { if (leadchar == '?') {
if (n1 == 25) { if (n1 == 25) {
screen_cursor_enable(1); screen_cursor_enable(1);
@ -207,7 +230,7 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
} }
break; break;
case 'l': case 'l': // feature disable
if (leadchar == '?') { if (leadchar == '?') {
if (n1 == 25) { if (n1 == 25) {
screen_cursor_enable(0); screen_cursor_enable(0);
@ -217,35 +240,61 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
} }
break; break;
case 'm': // SGR case 'm': // SGR - graphics rendition aka attributes
// iterate arguments // iterate arguments
for (int i = 0; i < CSI_N_MAX; i++) { for (int i = 0; i < CSI_N_MAX; i++) {
int n = params[i]; int n = params[i];
if (i == 0 && n == 0) { // reset SGR if (i == 0 && n == 0) { // reset SGR
screen_reset_cursor(); // resets colors, inverse and bold. screen_reset_cursor(); // resets colors, inverse and bold.
break; // cannot combine reset with others break; // cannot combine reset with others - discard
} }
else if (n >= 30 && n <= 37) screen_set_fg(n-30); // ANSI normal fg else if (n >= 30 && n <= 37) screen_set_fg((Color) (n - 30)); // ANSI normal fg
else if (n >= 40 && n <= 47) screen_set_bg(n-40); // ANSI normal bg else if (n >= 40 && n <= 47) screen_set_bg((Color) (n - 40)); // ANSI normal bg
else if (n == 39) screen_set_fg(7); // default fg else if (n == 39) screen_set_fg(termconf_scratch.default_fg); // default fg
else if (n == 49) screen_set_bg(false); // default bg else if (n == 49) screen_set_bg(termconf_scratch.default_bg); // default bg
else if (n == 7) screen_inverse(true); // inverse else if (n == 7) screen_inverse(true); // inverse
else if (n == 27) screen_inverse(false); // positive else if (n == 27) screen_inverse(false); // positive
else if (n == 1) screen_set_bold(true); // bold else if (n == 1) screen_set_bold(true); // bold
else if (n == 21 || n == 22) screen_set_bold(false); // bold off else if (n == 21 || n == 22) screen_set_bold(false); // bold off
else if (n >= 90 && n <= 97) screen_set_fg(n-90+8); // AIX bright fg else if (n >= 90 && n <= 97) screen_set_fg((Color) (n - 90 + 8)); // AIX bright fg
else if (n >= 100 && n <= 107) screen_set_bg(n-100+8); // AIX bright bg else if (n >= 100 && n <= 107) screen_set_bg((Color) (n - 100 + 8)); // AIX bright bg
} }
break; break;
case 't': // SunView code to set screen size (from GNU Screen)
screen_resize(n1, n2);
break;
case 'L':
// TODO insert line
break;
case 'M':
// TODO delete line
break;
case '@':
// TODO insert character (in line)
break;
case 'P':
// TODO delete character (in line)
break;
} }
} }
/** codes in the format ESC # n */
void ICACHE_FLASH_ATTR apars_handle_hashCode(char c) void ICACHE_FLASH_ATTR apars_handle_hashCode(char c)
{ {
// switch(c) {
case '8':
screen_fill_with_E();
break;
}
} }
/** those are single-character escape codes (ESC x) */
void ICACHE_FLASH_ATTR apars_handle_shortCode(char c) void ICACHE_FLASH_ATTR apars_handle_shortCode(char c)
{ {
switch(c) { switch(c) {
@ -253,19 +302,20 @@ void ICACHE_FLASH_ATTR apars_handle_shortCode(char c)
screen_reset(); screen_reset();
break; break;
case '7': // save cursor + attrs case '7': // save cursor + attrs
screen_cursor_save(1); screen_cursor_save(true);
break; break;
case '8': // restore cursor + attrs case '8': // restore cursor + attrs
screen_cursor_restore(1); screen_cursor_restore(false);
break; break;
case 'E': // same as CR LF case 'E': // same as CR LF
// TODO screen_cursor_move(1, 0, false);
screen_cursor_set_x(0);
break; break;
case 'D': // move cursor down, scroll screen up if needed case 'D': // move cursor down, scroll screen up if needed
// TODO screen_cursor_move(1, 0, true);
break; break;
case 'M': // move cursor up, scroll screen down if needed case 'M': // move cursor up, scroll screen down if needed
// TODO screen_cursor_move(-1, 0, true);
break; break;
} }
} }

@ -122,14 +122,18 @@ clear_range(unsigned int from, unsigned int to)
if (to >= W*H) to = W*H-1; if (to >= W*H) to = W*H-1;
Color fg = cursor.inverse ? cursor.bg : cursor.fg; Color fg = cursor.inverse ? cursor.bg : cursor.fg;
Color bg = cursor.inverse ? cursor.fg : cursor.bg; Color bg = cursor.inverse ? cursor.fg : cursor.bg;
Cell sample;
sample.c[0] = ' ';
sample.c[1] = 0;
sample.c[2] = 0;
sample.c[3] = 0;
sample.fg = fg;
sample.bg = bg;
sample.bold = false;
for (unsigned int i = from; i <= to; i++) { for (unsigned int i = from; i <= to; i++) {
screen[i].c[0] = ' '; memcpy(&screen[i], &sample, sizeof(Cell));
screen[i].c[1] = 0;
screen[i].c[2] = 0;
screen[i].c[3] = 0;
screen[i].fg = fg;
screen[i].bg = bg;
screen[i].bold = false;
} }
} }
@ -236,6 +240,36 @@ screen_clear_line(ClearMode mode)
NOTIFY_DONE(); NOTIFY_DONE();
} }
void ICACHE_FLASH_ATTR
screen_clear_in_line(unsigned int count)
{
if (cursor.x + count > W) {
screen_clear_line(CLEAR_FROM_CURSOR);
}
else {
NOTIFY_LOCK();
clear_range(cursor.y * W + cursor.x, cursor.y * W + cursor.x + count - 1);
NOTIFY_DONE();
}
}
void ICACHE_FLASH_ATTR
screen_fill_with_E(void)
{
Cell sample;
sample.c[0] = 'E';
sample.c[1] = 0;
sample.c[2] = 0;
sample.c[3] = 0;
sample.fg = termconf_scratch.default_fg;
sample.bg = termconf_scratch.default_fg;
sample.bold = false;
for (unsigned int i = 0; i <= W*H-1; i++) {
memcpy(&screen[i], &sample, sizeof(Cell));
}
}
//endregion //endregion
//region Screen manipulation //region Screen manipulation
@ -379,7 +413,7 @@ screen_cursor_set_y(int y)
* Relative cursor move * Relative cursor move
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_cursor_move(int dy, int dx) screen_cursor_move(int dy, int dx, bool scroll)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
int move; int move;
@ -392,13 +426,13 @@ screen_cursor_move(int dy, int dx)
if (cursor.y < 0) { if (cursor.y < 0) {
move = -cursor.y; move = -cursor.y;
cursor.y = 0; cursor.y = 0;
screen_scroll_down((unsigned int)move); if (scroll) screen_scroll_down((unsigned int)move);
} }
if (cursor.y >= H) { if (cursor.y >= H) {
move = cursor.y - (H - 1); move = cursor.y - (H - 1);
cursor.y = H - 1; cursor.y = H - 1;
screen_scroll_up((unsigned int)move); if (scroll) screen_scroll_up((unsigned int)move);
} }
NOTIFY_DONE(); NOTIFY_DONE();
@ -561,7 +595,7 @@ screen_putchar(const char *ch)
goto done; goto done;
case '\n': case '\n':
screen_cursor_move(1, 0); screen_cursor_move(1, 0, true); // can scroll
goto done; goto done;
case 8: // BS case 8: // BS

@ -90,7 +90,6 @@ httpd_cgi_state screenSerializeToBuffer(char *buffer, size_t buf_len, void **dat
void screenSerializeLabelsToBuffer(char *buffer, size_t buf_len); void screenSerializeLabelsToBuffer(char *buffer, size_t buf_len);
typedef struct { typedef struct {
u8 lsb; u8 lsb;
u8 msb; u8 msb;
@ -101,10 +100,8 @@ void encode2B(u16 number, WordB2 *stru);
/** Init the screen */ /** Init the screen */
void screen_init(void); void screen_init(void);
/** Change the screen size */ /** Change the screen size */
void screen_resize(int rows, int cols); void screen_resize(int rows, int cols);
/** Check if coord is valid */ /** Check if coord is valid */
bool screen_isCoordValid(int y, int x); bool screen_isCoordValid(int y, int x);
@ -112,48 +109,39 @@ bool screen_isCoordValid(int y, int x);
/** Screen reset to default state */ /** Screen reset to default state */
void screen_reset(void); void screen_reset(void);
/** Clear entire screen */
/** Clear entire screen, set all to 7 on 0 */
void screen_clear(ClearMode mode); void screen_clear(ClearMode mode);
/** Clear line */
/** Line reset to gray-on-white, empty */
void screen_clear_line(ClearMode mode); void screen_clear_line(ClearMode mode);
/** Clear part of line */
void screen_clear_in_line(unsigned int count);
/** Shift screen upwards */ /** Shift screen upwards */
void screen_scroll_up(unsigned int lines); void screen_scroll_up(unsigned int lines);
/** Shift screen downwards */ /** Shift screen downwards */
void screen_scroll_down(unsigned int lines); void screen_scroll_down(unsigned int lines);
/** esc # 8 - fill entire screen with E of default colors */
void screen_fill_with_E(void);
// --- Cursor control --- // --- Cursor control ---
/** Set cursor position */ /** Set cursor position */
void screen_cursor_set(int y, int x); void screen_cursor_set(int y, int x);
/** Read cursor pos to given vars */ /** Read cursor pos to given vars */
void screen_cursor_get(int *y, int *x); void screen_cursor_get(int *y, int *x);
/** Set cursor X position */ /** Set cursor X position */
void screen_cursor_set_x(int x); void screen_cursor_set_x(int x);
/** Set cursor Y position */ /** Set cursor Y position */
void screen_cursor_set_y(int y); void screen_cursor_set_y(int y);
/** Reset cursor attribs */ /** Reset cursor attribs */
void screen_reset_cursor(void); void screen_reset_cursor(void);
/** Relative cursor move */ /** Relative cursor move */
void screen_cursor_move(int dy, int dx); void screen_cursor_move(int dy, int dx, bool scroll);
/** Save the cursor pos */ /** Save the cursor pos */
void screen_cursor_save(bool withAttrs); void screen_cursor_save(bool withAttrs);
/** Restore the cursor pos */ /** Restore the cursor pos */
void screen_cursor_restore(bool withAttrs); void screen_cursor_restore(bool withAttrs);
/** Enable cursor display */ /** Enable cursor display */
void screen_cursor_enable(bool enable); void screen_cursor_enable(bool enable);
/** Enable auto wrap */ /** Enable auto wrap */
void screen_wrap_enable(bool enable); void screen_wrap_enable(bool enable);
@ -161,20 +149,15 @@ void screen_wrap_enable(bool enable);
/** Set cursor foreground color */ /** Set cursor foreground color */
void screen_set_fg(Color color); void screen_set_fg(Color color);
/** Set cursor background coloor */ /** Set cursor background coloor */
void screen_set_bg(Color color); void screen_set_bg(Color color);
/** make foreground bright */ /** make foreground bright */
void screen_set_bold(bool bold); void screen_set_bold(bool bold);
/** Set cursor foreground and background color */ /** Set cursor foreground and background color */
void screen_set_colors(Color fg, Color bg); void screen_set_colors(Color fg, Color bg);
/** Invert colors */ /** Invert colors */
void screen_inverse(bool inverse); void screen_inverse(bool inverse);
/** /**
* Set a character in the cursor color, move to right with wrap. * Set a character in the cursor color, move to right with wrap.
* The character may be ASCII (then only one char is used), or * The character may be ASCII (then only one char is used), or

Loading…
Cancel
Save