CSI split to subroutines

pull/111/merge
Ondřej Hruška 7 years ago
parent 87e0030be8
commit 3355295aa3
  1. 307
      user/apars_csi.c

@ -31,43 +31,24 @@
// TODO simplify file - split to subroutines // TODO simplify file - split to subroutines
// data tables for the DECREPTPARM command response
struct DECREPTPARM_parity { int parity; const char * msg; };
static const struct DECREPTPARM_parity DECREPTPARM_parity_arr[] = {
{PARITY_NONE, "1"},
{PARITY_ODD, "4"},
{PARITY_EVEN, "5"},
{-1, 0}
};
struct DECREPTPARM_baud { int baud; const char * msg; };
static const struct DECREPTPARM_baud DECREPTPARM_baud_arr[] = {
{BIT_RATE_300, "48"},
{BIT_RATE_600, "56"},
{BIT_RATE_1200, "64"},
{BIT_RATE_2400, "88"},
{BIT_RATE_4800, "96"},
{BIT_RATE_9600 , "104"},
{BIT_RATE_19200 , "112"},
{BIT_RATE_38400 , "120"},
{BIT_RATE_57600 , "128"}, // this is the last in the spec, follow +8
{BIT_RATE_74880 , "136"},
{BIT_RATE_115200, "144"},
{BIT_RATE_230400, "152"},
{BIT_RATE_460800, "160"},
{BIT_RATE_921600, "168"},
{BIT_RATE_1843200, "176"},
{BIT_RATE_3686400, "184"},
{-1, 0}
};
static void warn_bad_csi() static void warn_bad_csi()
{ {
ansi_noimpl_r("Unknown CSI"); ansi_noimpl_r("Unknown CSI");
apars_show_context(); apars_show_context();
} }
typedef struct {
char lead;
const int *n;
int count;
char aug; // augmenting
char key;
} CSI_Data;
static void do_csi_privattr(CSI_Data *opts);
static void do_csi_sgr(CSI_Data *opts);
static void do_csi_decreqtparm(CSI_Data *opts);
/** /**
* Handle fully received CSI ANSI sequence * Handle fully received CSI ANSI sequence
* @param leadchar - private range leading character, 0 if none * @param leadchar - private range leading character, 0 if none
@ -77,18 +58,23 @@ static void warn_bad_csi()
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
apars_handle_csi(char leadchar, const int *params, int count, char keychar) apars_handle_csi(char leadchar, const int *params, int count, char keychar)
{ {
CSI_Data opts = {leadchar, params, count, NUL, keychar};
char buf[32];
bool yn = false; // for ? l h
int n1 = params[0]; int n1 = params[0];
int n2 = params[1]; int n2 = params[1];
int n3 = params[2]; int n3 = params[2];
char buf[32];
bool yn = false; // for ? l h
// defaults - FIXME this may inadvertently affect some variants that should be left unchanged // defaults - FIXME this may inadvertently affect some variants that should be left unchanged
switch (keychar) { switch (keychar) {
case 'A': // move case 'A': // move
case 'a':
case 'e':
case 'B': case 'B':
case 'C': case 'C':
case 'D': case 'D':
case 'b':
case 'E': case 'E':
case 'F': case 'F':
case 'G': // set X case 'G': // set X
@ -103,7 +89,6 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
case 'P': case 'P':
case 'I': case 'I':
case 'Z': case 'Z':
case 'b':
if (n1 == 0) n1 = 1; if (n1 == 0) n1 = 1;
break; break;
@ -125,7 +110,6 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
switch (keychar) { switch (keychar) {
// CUU CUD CUF CUB // CUU CUD CUF CUB
case 'a':
case 'A': // Up case 'A': // Up
screen_cursor_move(-n1, 0, false); screen_cursor_move(-n1, 0, false);
break; break;
@ -135,6 +119,7 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
screen_cursor_move(n1, 0, false); screen_cursor_move(n1, 0, false);
break; break;
case 'a': // some archaic form of "Go Right"
case 'C': // Right (forward) case 'C': // Right (forward)
screen_cursor_move(0, n1, false); screen_cursor_move(0, n1, false);
break; break;
@ -206,21 +191,26 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
case 8: // set size case 8: // set size
screen_resize(n2, n3); screen_resize(n2, n3);
break; break;
case 18: // report size case 18: // report size
printf(buf, "\033[8;%d;%dt", termconf_scratch.height, termconf_scratch.width); printf(buf, "\033[8;%d;%dt", termconf_scratch.height, termconf_scratch.width);
apars_respond(buf); apars_respond(buf);
break; break;
case 11: // Report iconified -> is not iconified case 11: // Report iconified -> is not iconified
apars_respond("\033[1t"); apars_respond("\033[1t");
break; break;
case 21: // Report title case 21: // Report title
apars_respond("\033]L"); apars_respond("\033]L");
apars_respond(termconf_scratch.title); apars_respond(termconf_scratch.title);
apars_respond("\033\\"); apars_respond("\033\\");
break; break;
case 24: // Set Height only case 24: // Set Height only
screen_resize(n2, termconf_scratch.width); screen_resize(n2, termconf_scratch.width);
break; break;
default: default:
ansi_noimpl("CSI %d t", n1); ansi_noimpl("CSI %d t", n1);
break; break;
@ -276,6 +266,10 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
if (leadchar == NUL && count == 0) { if (leadchar == NUL && count == 0) {
screen_cursor_save(0); screen_cursor_save(0);
} }
else if (leadchar == '?') {
// Save private attributes (CSI ? Pm h/l)
ansi_noimpl("Save private attrs");
}
else { else {
// other: // other:
// CSI ? Pm s // CSI ? Pm s
@ -284,6 +278,22 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
} }
break; break;
case 'r':
if (leadchar == NUL && (count == 2 || count == 0)) {
screen_set_scrolling_region(n1, n2);
}
else if (leadchar == '?') {
// Restore private attributes (CSI ? Pm h/l)
ansi_noimpl("Restore private attrs");
}
else {
// other:
// CSI ? Pm r
// CSI Pt; Pl; Pb; Pr; Ps$ r
warn_bad_csi();
}
break;
case 'u': case 'u':
if (leadchar == NUL && count == 0) { if (leadchar == NUL && count == 0) {
screen_cursor_restore(0); screen_cursor_restore(0);
@ -293,6 +303,57 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
} }
break; break;
case 'h': // DEC feature enable
case 'l': // DEC feature disable
do_csi_privattr(&opts);
break;
case 'm': // SGR - set graphics rendition
do_csi_sgr(&opts);
break;
case 'L': // Insert lines (shove down)
screen_insert_lines(n1);
break;
case 'M': // Delete lines (pull up)
screen_delete_lines(n1);
break;
case '@': // Insert in line (shove right)
screen_insert_characters(n1);
break;
case 'P': // Delete in line (pull left)
screen_delete_characters(n1);
break;
case 'g': // Clear tabs
if (n1 == 3) {
screen_clear_all_tabs();
} else {
screen_clear_tab();
}
break;
case 'Z': // Tab backward
screen_tab_reverse(n1);
break;
case 'I': // Tab forward
screen_tab_forward(n1);
break;
case 'p':
if (leadchar == '!') { // RIS
/* On real VT there are differences between soft and hard reset, we treat both equally */
screen_reset();
}
else {
warn_bad_csi();
}
break;
case 'n': // Queries case 'n': // Queries
if (leadchar == '>') { if (leadchar == '>') {
// some xterm garbage - discard // some xterm garbage - discard
@ -317,13 +378,41 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
} }
break; break;
case 'h': // DEC feature enable case 'c': // CSI-c - report capabilities
yn = 1; if (leadchar == NUL) {
case 'l': // DEC feature disable apars_respond("\033[?64;9c"); // pretend we're vt400 with national character sets
// yn is 0 by default }
for (int i = 0; i < count; i++) { else if (leadchar == '>') {
int n = params[i]; // 41 - we're "VT400", 0 - ROM cartridge number
if (leadchar == '?') { sprintf(buf, "\033[>41;%d;0c", FIRMWARE_VERSION_NUM);
apars_respond(buf);
}
else {
warn_bad_csi();
}
break;
case 'x': // DECREQTPARM -> DECREPTPARM
do_csi_decreqtparm(&opts);
break;
default:
warn_bad_csi();
}
}
/**
* CSI [?] Pm {h|l}
* @param opts
*/
static void ICACHE_FLASH_ATTR do_csi_privattr(CSI_Data *opts)
{
bool yn = (opts->key == 'h');
if (opts->lead == '?') {
// --- DEC private attributes ---
for (int i = 0; i < opts->count; i++) {
int n = opts->n[i];
if (n == 1) { if (n == 1) {
screen_set_cursors_alt_mode(yn); screen_set_cursors_alt_mode(yn);
} }
@ -334,7 +423,7 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
} }
else if (n == 3) { else if (n == 3) {
// 132 column mode - not implemented due to RAM demands // 132 column mode - not implemented due to RAM demands
// ansi_noimpl("80->132"); ansi_noimpl("80->132");
} }
else if (n == 4) { else if (n == 4) {
// Smooth scroll - not implemented // Smooth scroll - not implemented
@ -352,7 +441,7 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
// Key auto-repeat // Key auto-repeat
// We don't implement this currently, but it could be added // We don't implement this currently, but it could be added
// - discard repeated keypress events between keydown and keyup. // - discard repeated keypress events between keydown and keyup.
// ansi_noimpl("Auto-repeat toggle"); ansi_noimpl("Auto-repeat toggle");
} }
else if (n == 9 || (n >= 1000 && n <= 1006)) { else if (n == 9 || (n >= 1000 && n <= 1006)) {
// TODO mouse // TODO mouse
@ -427,10 +516,15 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
screen_set_cursor_visible(yn); screen_set_cursor_visible(yn);
} }
else { else {
ansi_noimpl("CSI ? %d %c", n, keychar); ansi_noimpl("CSI ? %d %c", n, opts->key);
}
} }
} }
else { else {
// --- DEC standard attributes ---
for (int i = 0; i < opts->count; i++) {
int n = opts->n[i];
if (n == 4) { if (n == 4) {
screen_set_insert_mode(yn); screen_set_insert_mode(yn);
} }
@ -438,26 +532,33 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
screen_set_newline_mode(yn); screen_set_newline_mode(yn);
} }
else { else {
ansi_noimpl("CSI %d %c", n, keychar); ansi_noimpl("CSI %d %c", n, opts->key);
} }
} }
} }
break; }
/**
* CSI [ Pm m
* @param opts
*/
static void ICACHE_FLASH_ATTR do_csi_sgr(CSI_Data *opts)
{
int count = opts->count;
case 'm': // SGR - set graphics rendition
if (count == 0) { if (count == 0) {
count = 1; // this makes it work as 0 (reset) count = 1; // this makes it work as 0 (reset)
} }
if (leadchar == '>') { if (opts->lead != NUL) {
// some xterm garbage - discard // some xterm garbage - discard
// CSI > Ps; Ps m // CSI > Ps; Ps m
break; return;
} }
// iterate arguments // iterate arguments
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
int n = params[i]; int n = opts->n[i];
if (n == SGR_RESET) screen_reset_sgr(); if (n == SGR_RESET) screen_reset_sgr();
// -- set color -- // -- set color --
@ -489,66 +590,48 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
ansi_noimpl("SGR %d", n); ansi_noimpl("SGR %d", n);
} }
} }
break; }
case 'L': // Insert lines (shove down)
screen_insert_lines(n1);
break;
case 'M': // Delete lines (pull up)
screen_delete_lines(n1);
break;
case '@': // Insert in line (shove right)
screen_insert_characters(n1);
break;
case 'P': // Delete in line (pull left)
screen_delete_characters(n1);
break;
case 'r': // data tables for the DECREPTPARM command response
if (leadchar == NUL && (count == 2 || count == 0)) {
screen_set_scrolling_region(n1, n2);
}
else {
// other:
// CSI ? Pm r
// CSI Pt; Pl; Pb; Pr; Ps$ r
warn_bad_csi();
}
break;
case 'g': // Clear tabs
if (n1 == 3) {
screen_clear_all_tabs();
} else {
screen_clear_tab();
}
break;
case 'Z': // Tab backward struct DECREPTPARM_parity { int parity; const char * msg; };
screen_tab_reverse(n1); static const struct DECREPTPARM_parity DECREPTPARM_parity_arr[] = {
break; {PARITY_NONE, "1"},
{PARITY_ODD, "4"},
{PARITY_EVEN, "5"},
{-1, 0}
};
case 'I': // Tab forward struct DECREPTPARM_baud { int baud; const char * msg; };
screen_tab_forward(n1); static const struct DECREPTPARM_baud DECREPTPARM_baud_arr[] = {
break; {BIT_RATE_300, "48"},
{BIT_RATE_600, "56"},
{BIT_RATE_1200, "64"},
{BIT_RATE_2400, "88"},
{BIT_RATE_4800, "96"},
{BIT_RATE_9600 , "104"},
{BIT_RATE_19200 , "112"},
{BIT_RATE_38400 , "120"},
{BIT_RATE_57600 , "128"}, // this is the last in the spec, follow +8
{BIT_RATE_74880 , "136"},
{BIT_RATE_115200, "144"},
{BIT_RATE_230400, "152"},
{BIT_RATE_460800, "160"},
{BIT_RATE_921600, "168"},
{BIT_RATE_1843200, "176"},
{BIT_RATE_3686400, "184"},
{-1, 0}
};
case 'c': // CSI-c - report capabilities /**
if (leadchar == NUL) { * CSI [ Ps x
apars_respond("\033[?64;9c"); // pretend we're vt400 with national character sets * @param opts
} */
else if (leadchar == '>') { static void ICACHE_FLASH_ATTR do_csi_decreqtparm(CSI_Data *opts)
// 41 - we're "VT400", 0 - ROM cartridge number {
sprintf(buf, "\033[>41;%d;0c", FIRMWARE_VERSION_NUM); const int n1 = opts->n[0];
apars_respond(buf);
} else {
warn_bad_csi();
}
break;
case 'x': // DECREQTPARM -> DECREPTPARM
// reference http://vt100.net/docs/vt100-ug/chapter3.html - search DECREPTPARM // reference http://vt100.net/docs/vt100-ug/chapter3.html - search DECREPTPARM
if (n1 <= 1) { if (n1 <= 1) {
apars_respond("\033["); // this is a response on request (2 would be gratuitous) apars_respond("\033["); // this is a response on request (2 would be gratuitous)
@ -579,18 +662,4 @@ apars_handle_csi(char leadchar, const int *params, int count, char keychar)
// multiplier 1, flags 0 // multiplier 1, flags 0
apars_respond(";1;0x"); // ROM cartridge number ?? apars_respond(";1;0x"); // ROM cartridge number ??
} }
break;
case 'p':
if (leadchar == '!') { // RIS
/* On real VT there are differences between soft and hard reset, we treat both equally */
screen_reset();
} else {
warn_bad_csi();
}
break;
default:
warn_bad_csi();
}
} }

Loading…
Cancel
Save