diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | vt100.c | 404 | ||||
-rw-r--r-- | vt100.l | 487 |
4 files changed, 497 insertions, 405 deletions
@@ -1,2 +1,3 @@ *.o runes +vt100.c @@ -4,15 +4,23 @@ LIBS = cairo cairo-xlib libuv CFLAGS ?= -g -Wall -Wextra -Werror LDFLAGS ?= -g -Wall -Wextra -Werror +GENERATED = vt100.c + build: $(OUT) $(OUT): $(OBJ) $(CC) $(shell pkg-config --libs $(LIBS)) $(LDFLAGS) -o $@ $^ +vt100.o: vt100.c + $(CC) $(shell pkg-config --cflags $(LIBS)) $(CFLAGS) -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wno-unused-value -c -o $@ $^ + %.o: %.c $(CC) $(shell pkg-config --cflags $(LIBS)) $(CFLAGS) -c -o $@ $^ +%.c: %.l + $(LEX) -o $@ $^ + clean: - rm -f $(OUT) $(OBJ) + rm -f $(OUT) $(OBJ) $(GENERATED) .PHONY: build clean diff --git a/vt100.c b/vt100.c deleted file mode 100644 index c6b3206..0000000 --- a/vt100.c +++ /dev/null @@ -1,404 +0,0 @@ -#include <stdio.h> -#include <string.h> - -#include "runes.h" - -static const char *ctrl_chars = - /* XXX working with nul terminated strings for the moment... */ - /* "\000\001\002\003\004\005\006\007" */ - "\001\002\003\004\005\006\007" - "\010\011\012\013\014\015\016\017" - "\020\021\022\023\024\025\026\027" - "\030\031\032\033\034\035\036\037" - "\177"; - -static char *runes_vt100_handle_ctrl_char(RunesTerm *t, char *buf, size_t len); -static char *runes_vt100_handle_escape_sequence( - RunesTerm *t, char *buf, size_t len); -static char *runes_vt100_handle_csi(RunesTerm *t, char *buf, size_t len); -static char *runes_vt100_handle_osc(RunesTerm *t, char *buf, size_t len); -static void runes_vt100_unhandled_escape_sequence( - RunesTerm *t, char type); -static void runes_vt100_unhandled_csi( - RunesTerm *t, char dec, int p[3], char type); -static void runes_vt100_unhandled_osc( - RunesTerm *t, int type, char *arg, char terminator); - -void runes_vt100_process_string(RunesTerm *t, char *buf, size_t len) -{ - int found; - size_t prefix; - - buf[len] = '\0'; - do { - found = 0; - - prefix = strcspn(buf, ctrl_chars); - if (prefix) { - char tmp = buf[prefix]; - - buf[prefix] = '\0'; - runes_display_show_string(t, buf, strlen(buf)); - buf[prefix] = tmp; - buf += prefix; - found = 1; - } - - prefix = strspn(buf, ctrl_chars); - if (prefix) { - char *end = buf + prefix; - - while (buf < end) { - buf = runes_vt100_handle_ctrl_char(t, buf, strlen(buf)); - } - found = 1; - } - } while (found); -} - -static char *runes_vt100_handle_ctrl_char(RunesTerm *t, char *buf, size_t len) -{ - switch (buf[0]) { - case '\010': /* BS */ - runes_display_backspace(t); - buf++; - break; - case '\011': /* TAB */ - runes_display_move_to(t, t->row, t->col - (t->col % 8) + 8); - buf++; - break; - case '\012': /* LF */ - case '\013': /* VT */ - case '\014': /* FF */ - runes_display_move_to(t, t->row + 1, t->col); - buf++; - break; - case '\015': /* CR */ - runes_display_move_to(t, t->row, 0); - buf++; - break; - case '\033': - buf++; - buf = runes_vt100_handle_escape_sequence(t, buf, len); - break; - default: - buf++; - break; - } - - return buf; -} - -static char *runes_vt100_handle_escape_sequence( - RunesTerm *t, char *buf, size_t len) -{ - switch (buf[0]) { - case '[': /* CSI */ - buf++; - buf = runes_vt100_handle_csi(t, buf, len); - break; - case ']': /* OSC */ - buf++; - buf = runes_vt100_handle_osc(t, buf, len); - break; - case 'M': /* RI */ - buf++; - runes_display_move_to(t, t->row - 1, t->col); - break; - default: - runes_vt100_unhandled_escape_sequence(t, buf[0]); - buf++; - break; - } - - return buf; -} - -static char *runes_vt100_handle_csi(RunesTerm *t, char *buf, size_t len) -{ - int p[3] = { -1, -1, -1 }; - int paramlen; - char type, dec = 0; - - UNUSED(len); - - if (buf[0] == '?') { - dec = 1; - buf++; - } - - /* XXX stop hardcoding the max number of parameters */ - if (sscanf(buf, "%d;%d;%d%c%n", &p[0], &p[1], &p[2], &type, ¶mlen) == 4) { - /* nothing */ - } - else if (sscanf(buf, "%d;%d%c%n", &p[0], &p[1], &type, ¶mlen) == 3) { - /* nothing */ - } - else if (sscanf(buf, "%d%c%n", &p[0], &type, ¶mlen) == 2) { - /* nothing */ - } - else if (sscanf(buf, "%c%n", &type, ¶mlen) == 1) { - /* nothing */ - } - - switch (type) { - case 'D': /* CUB */ - runes_display_move_to(t, t->row, t->col - 1); - break; - case 'B': /* CUD */ - runes_display_move_to(t, t->row + 1, t->col); - break; - case 'C': /* CUF */ - runes_display_move_to(t, t->row, t->col + 1); - break; - case 'A': /* CUU */ - runes_display_move_to(t, t->row - 1, t->col); - break; - case 'H': /* CUP */ - if (p[0] == -1) { - p[0] = 0; - } - if (p[1] == -1) { - p[1] = 0; - } - runes_display_move_to(t, p[0], p[1]); - break; - case 'J': /* ED */ - /* XXX need to do something special when dec is set */ - switch (p[0]) { - case -1: - case 0: - runes_display_clear_screen_forward(t); - break; - case 1: - /* XXX */ - runes_vt100_unhandled_csi(t, dec, p, type); - break; - case 2: - runes_display_clear_screen(t); - break; - default: - runes_vt100_unhandled_csi(t, dec, p, type); - break; - } - break; - case 'K': /* EL */ - /* XXX need to do something special when dec is set */ - switch (p[0]) { - case -1: - case 0: - runes_display_kill_line_forward(t); - break; - case 1: - /* XXX */ - runes_vt100_unhandled_csi(t, dec, p, type); - break; - case 2: - /* XXX */ - runes_vt100_unhandled_csi(t, dec, p, type); - break; - default: - runes_vt100_unhandled_csi(t, dec, p, type); - break; - } - break; - case 'h': - if (dec) { - switch (p[0]) { - case 25: - runes_display_show_cursor(t); - break; - default: - runes_vt100_unhandled_csi(t, dec, p, type); - break; - } - } - else { - runes_vt100_unhandled_csi(t, dec, p, type); - } - break; - case 'l': - if (dec) { - switch (p[0]) { - case 25: - runes_display_hide_cursor(t); - break; - default: - runes_vt100_unhandled_csi(t, dec, p, type); - break; - } - } - else { - runes_vt100_unhandled_csi(t, dec, p, type); - } - break; - case 'm': { /* SGR */ - int i; - - if (p[0] == -1) { - p[0] = 0; - } - - for (i = 0; i < 3; ++i) { - switch (p[i]) { - case -1: - break; - case 0: - runes_display_reset_text_attributes(t); - break; - case 1: - runes_display_set_bold(t); - break; - case 3: - runes_display_set_italic(t); - break; - case 4: - runes_display_set_underline(t); - break; - case 22: - runes_display_reset_bold(t); - break; - case 23: - runes_display_reset_italic(t); - break; - case 24: - runes_display_reset_underline(t); - break; - case 30: case 31: case 32: case 33: - case 34: case 35: case 36: case 37: - runes_display_set_fg_color(t, t->colors[p[i] - 30]); - break; - case 39: - runes_display_reset_fg_color(t); - break; - case 40: case 41: case 42: case 43: - case 44: case 45: case 46: case 47: - runes_display_set_bg_color(t, t->colors[p[i] - 40]); - break; - case 49: - runes_display_reset_bg_color(t); - break; - /* XXX ... */ - default: - runes_vt100_unhandled_csi(t, dec, p, type); - break; - } - } - break; - } - default: - runes_vt100_unhandled_csi(t, dec, p, type); - break; - } - - return buf + paramlen; -} - -static char *runes_vt100_handle_osc(RunesTerm *t, char *buf, size_t len) -{ - int type, prefix; - - UNUSED(len); - - if (sscanf(buf, "%d%n", &type, &prefix) != 1) { - runes_vt100_unhandled_osc(t, -1, "", buf[0]); - return buf + 1; - } - - switch (type) { - case 0: - if (buf[prefix] == ';') { - size_t namelen; - - namelen = strcspn(&buf[prefix + 1], "\007"); - runes_window_backend_set_icon_name(t, &buf[prefix + 1], namelen); - runes_window_backend_set_window_title( - t, &buf[prefix + 1], namelen); - prefix += namelen + 2; - } - else { - runes_vt100_unhandled_osc(t, type, "", -1); - prefix++; - } - break; - case 1: - if (buf[prefix] == ';') { - size_t namelen; - - namelen = strcspn(&buf[prefix + 1], "\007"); - runes_window_backend_set_icon_name(t, &buf[prefix + 1], namelen); - prefix += namelen + 2; - } - else { - runes_vt100_unhandled_osc(t, type, "", -1); - prefix++; - } - break; - case 2: - if (buf[prefix] == ';') { - size_t namelen; - - namelen = strcspn(&buf[prefix + 1], "\007"); - runes_window_backend_set_window_title( - t, &buf[prefix + 1], namelen); - prefix += namelen + 2; - } - else { - runes_vt100_unhandled_osc(t, type, "", -1); - prefix++; - } - break; - default: - runes_vt100_unhandled_osc(t, type, "", -1); - prefix++; - break; - } - - return buf + prefix; -} - -static void runes_vt100_unhandled_escape_sequence( - RunesTerm *t, char type) -{ - UNUSED(t); - - fprintf(stderr, "unhandled escape sequence: \\033%c\n", type); -} - -static void runes_vt100_unhandled_csi( - RunesTerm *t, char dec, int p[3], char type) -{ - UNUSED(t); - - fprintf(stderr, "unhandled escape sequence: \\033["); - if (dec) { - fprintf(stderr, "?"); - } - if (p[0] != -1) { - fprintf(stderr, "%d", p[0]); - } - if (p[1] != -1) { - fprintf(stderr, ";%d", p[1]); - } - if (p[2] != -1) { - fprintf(stderr, ";%d", p[2]); - } - fprintf(stderr, "%c\n", type); -} - -static void runes_vt100_unhandled_osc( - RunesTerm *t, int type, char *arg, char terminator) -{ - UNUSED(t); - - fprintf(stderr, "unhandled escape sequence: \\033]"); - if (type == -1) { - fprintf(stderr, "\\%hho\n", terminator); - } - else if (terminator == -1) { - fprintf(stderr, "%d;<unknown>\n", type); - } - else { - fprintf(stderr, "%d;%s\\%hho\n", type, arg, terminator); - } -} @@ -0,0 +1,487 @@ +%{ +#include <string.h> + +#include "runes.h" + +#define RUNES_VT100_CSI_MAX_PARAMS 256 +%} + +%option reentrant noyywrap nodefault batch +%option prefix="runes_vt100_yy" +%option extra-type="RunesTerm *" + +CTRL [\000-\037\177] +TEXT [^\000-\037\177] + +ST \007 +BEL \007 +BS \010 +TAB \011 +LF \012 +VT \013 +FF \014 +CR \015 +ESC \033 + +CSI {ESC}\[ +OSC {ESC}\] +RI {ESC}M + +DECCSI {CSI}\? +CSIPARAM1 ([0-9]+)? +CSIPARAM2 ([0-9]+(;[0-9]+)?)? +CSIPARAMS ([0-9]+(;[0-9]+)*)? +SMPARAMS ([<=?]?[0-9]+(;[<=?]?[0-9]+)*)? + +CUU {CSI}{CSIPARAM1}A +CUD {CSI}{CSIPARAM1}B +CUF {CSI}{CSIPARAM1}C +CUB {CSI}{CSIPARAM1}D +CUP {CSI}{CSIPARAM2}H +ED {CSI}{CSIPARAM1}J +EL {CSI}{CSIPARAM1}K +SM {CSI}{SMPARAMS}h +RM {CSI}{SMPARAMS}l +SGR {CSI}{CSIPARAMS}m + +DECSED {DECCSI}{CSIPARAM1}J +DECSEL {DECCSI}{CSIPARAM1}K + +OSC0 {OSC}0;{TEXT}*{ST} +OSC1 {OSC}1;{TEXT}*{ST} +OSC2 {OSC}2;{TEXT}*{ST} + +%{ +static void runes_vt100_handle_text(RunesTerm *t, char *text, size_t len); +static void runes_vt100_handle_bel(RunesTerm *t); +static void runes_vt100_handle_bs(RunesTerm *t); +static void runes_vt100_handle_tab(RunesTerm *t); +static void runes_vt100_handle_lf(RunesTerm *t); +static void runes_vt100_handle_cr(RunesTerm *t); +static void runes_vt100_handle_ri(RunesTerm *t); +static void runes_vt100_extract_csi_params( + char *buf, size_t len, int *params, int *nparams); +static void runes_vt100_extract_sm_params( + char *buf, size_t len, char *modes, int *params, int *nparams); +static void runes_vt100_handle_cuu(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_cud(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_cuf(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_cub(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_cup(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_ed(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_el(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_sm(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_rm(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_sgr(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_decsed(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_decsel(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_osc0(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_osc1(RunesTerm *t, char *buf, size_t len); +static void runes_vt100_handle_osc2(RunesTerm *t, char *buf, size_t len); +%} + +%% + +{TEXT}+ runes_vt100_handle_text(yyextra, yytext, yyleng); + +{BEL} runes_vt100_handle_bel(yyextra); +{BS} runes_vt100_handle_bs(yyextra); +{TAB} runes_vt100_handle_tab(yyextra); +{LF} | +{VT} | +{FF} runes_vt100_handle_lf(yyextra); +{CR} runes_vt100_handle_cr(yyextra); + +{RI} runes_vt100_handle_ri(yyextra); + +{CUU} runes_vt100_handle_cuu(yyextra, yytext, yyleng); +{CUD} runes_vt100_handle_cud(yyextra, yytext, yyleng); +{CUF} runes_vt100_handle_cuf(yyextra, yytext, yyleng); +{CUB} runes_vt100_handle_cub(yyextra, yytext, yyleng); +{CUP} runes_vt100_handle_cup(yyextra, yytext, yyleng); +{ED} runes_vt100_handle_ed(yyextra, yytext, yyleng); +{EL} runes_vt100_handle_el(yyextra, yytext, yyleng); +{SM} runes_vt100_handle_sm(yyextra, yytext, yyleng); +{RM} runes_vt100_handle_rm(yyextra, yytext, yyleng); +{SGR} runes_vt100_handle_sgr(yyextra, yytext, yyleng); + +{DECSED} runes_vt100_handle_decsed(yyextra, yytext, yyleng); +{DECSEL} runes_vt100_handle_decsel(yyextra, yytext, yyleng); + +{OSC0} runes_vt100_handle_osc0(yyextra, yytext, yyleng); +{OSC1} runes_vt100_handle_osc1(yyextra, yytext, yyleng); +{OSC2} runes_vt100_handle_osc2(yyextra, yytext, yyleng); + +{CSI}\??{CSIPARAMS}(?s:.) { + fprintf( + stderr, "unhandled CSI sequence: \\033%*s\n", + (int)yyleng - 1, yytext + 1); +} + +{OSC}(?s:.) { + fprintf( + stderr, "unhandled OSC sequence: \\033%*s\n", + (int)yyleng - 1, yytext + 1); +} + +{ESC} { + fprintf(stderr, "unhandled escape sequence\n"); +} + +{CTRL} { + fprintf(stderr, "unhandled control character: \\%hho\n", yytext[0]); +} + +%% + +void runes_vt100_process_string(RunesTerm *t, char *buf, size_t len) +{ + YY_BUFFER_STATE state; + yyscan_t scanner; + + yylex_init_extra(t, &scanner); + state = runes_vt100_yy_scan_bytes(buf, len, scanner); + runes_vt100_yylex(scanner); + runes_vt100_yy_delete_buffer(state, scanner); + yylex_destroy(scanner); +} + +static void runes_vt100_handle_text(RunesTerm *t, char *text, size_t len) +{ + runes_display_show_string(t, text, len); +} + +static void runes_vt100_handle_bel(RunesTerm *t) +{ + /* XXX */ +} + +static void runes_vt100_handle_bs(RunesTerm *t) +{ + runes_display_backspace(t); +} + +static void runes_vt100_handle_tab(RunesTerm *t) +{ + runes_display_move_to(t, t->row, t->col - (t->col % 8) + 8); +} + +static void runes_vt100_handle_lf(RunesTerm *t) +{ + runes_display_move_to(t, t->row + 1, t->col); +} + +static void runes_vt100_handle_cr(RunesTerm *t) +{ + runes_display_move_to(t, t->row, 0); +} + +static void runes_vt100_handle_ri(RunesTerm *t) +{ + runes_display_move_to(t, t->row - 1, t->col); +} + +static void runes_vt100_extract_csi_params( + char *buf, size_t len, int *params, int *nparams) +{ + runes_vt100_extract_sm_params(buf, len, NULL, params, nparams); +} + +static void runes_vt100_extract_sm_params( + char *buf, size_t len, char *modes, int *params, int *nparams) +{ + char tmp = buf[len]; + char *pos = buf; + + /* this assumes that it will only ever be called on a fully matched CSI + * sequence: accessing one character beyond the end is safe because CSI + * sequences always have one character after the parameters (to determine + * the type of sequence), and the parameters can only ever be digits, + * separated by semicolons. */ + buf[len] = '\0'; + *nparams = 0; + for (;;) { + if (*nparams >= RUNES_VT100_CSI_MAX_PARAMS) { + fprintf(stderr, "max CSI parameter length exceeded\n"); + break; + } + + if (modes && (size_t)(pos - buf) < len) { + if (strstr(pos, "0123456789")) { + modes[*nparams] = '\0'; + } + else { + modes[*nparams] = *pos++; + } + } + + params[(*nparams)++] = atoi(pos); + + pos = strchr(pos, ';'); + if (pos) { + pos++; + } + else { + break; + } + } +} + +static void runes_vt100_handle_cuu(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 1 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + runes_display_move_to(t, t->row - params[0], t->col); +} + +static void runes_vt100_handle_cud(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 1 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + runes_display_move_to(t, t->row + params[0], t->col); +} + +static void runes_vt100_handle_cuf(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 1 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + runes_display_move_to(t, t->row, t->col + params[0]); +} + +static void runes_vt100_handle_cub(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 1 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + runes_display_move_to(t, t->row, t->col - params[0]); +} + +static void runes_vt100_handle_cup(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 1, 1 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + runes_display_move_to(t, params[0] - 1, params[1] - 1); +} + +static void runes_vt100_handle_ed(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 0 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + switch (params[0]) { + case 0: + runes_display_clear_screen_forward(t); + break; + case 1: + /* XXX */ + fprintf(stderr, "unhandled ED parameter 1\n"); + break; + case 2: + runes_display_clear_screen(t); + break; + default: + fprintf(stderr, "unknown ED parameter %d\n", params[0]); + break; + } +} + +static void runes_vt100_handle_el(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 0 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + switch (params[0]) { + case 0: + runes_display_kill_line_forward(t); + break; + case 1: + /* XXX */ + fprintf(stderr, "unhandled EL parameter 1\n"); + break; + case 2: + /* XXX */ + fprintf(stderr, "unhandled EL parameter 2\n"); + break; + default: + fprintf(stderr, "unknown EL parameter %d\n", params[0]); + break; + } +} + +static void runes_vt100_handle_sm(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS], nparams, i; + char modes[RUNES_VT100_CSI_MAX_PARAMS] = { 0 }; + + runes_vt100_extract_sm_params(buf + 2, len - 3, modes, params, &nparams); + for (i = 0; i < nparams; ++i) { + switch (modes[i]) { + case '?': + switch (params[i]) { + case 25: + runes_display_show_cursor(t); + break; + default: + fprintf( + stderr, "unknown SM parameter: %c%d\n", + modes[i], params[i]); + break; + } + break; + default: + fprintf( + stderr, "unknown SM parameter: %c%d\n", + modes[i], params[i]); + break; + } + } +} + +static void runes_vt100_handle_rm(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS], nparams, i; + char modes[RUNES_VT100_CSI_MAX_PARAMS] = { 0 }; + + runes_vt100_extract_sm_params(buf + 2, len - 3, modes, params, &nparams); + for (i = 0; i < nparams; ++i) { + switch (modes[i]) { + case '?': + switch (params[i]) { + case 25: + runes_display_hide_cursor(t); + break; + default: + fprintf( + stderr, "unknown RM parameter: %c%d\n", + modes[i], params[i]); + break; + } + break; + default: + fprintf( + stderr, "unknown RM parameter: %c%d\n", + modes[i], params[i]); + break; + } + } +} + +static void runes_vt100_handle_sgr(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 0 }, nparams, i; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + if (nparams < 1) { + nparams = 1; + } + for (i = 0; i < nparams; ++i) { + switch (params[i]) { + case 0: + runes_display_reset_text_attributes(t); + break; + case 1: + runes_display_set_bold(t); + break; + case 3: + runes_display_set_italic(t); + break; + case 4: + runes_display_set_underline(t); + break; + case 22: + runes_display_reset_bold(t); + break; + case 23: + runes_display_reset_italic(t); + break; + case 24: + runes_display_reset_underline(t); + break; + case 30: case 31: case 32: case 33: + case 34: case 35: case 36: case 37: + runes_display_set_fg_color(t, t->colors[params[i] - 30]); + break; + case 39: + runes_display_reset_fg_color(t); + break; + case 40: case 41: case 42: case 43: + case 44: case 45: case 46: case 47: + runes_display_set_bg_color(t, t->colors[params[i] - 40]); + break; + case 49: + runes_display_reset_bg_color(t); + break; + default: + fprintf(stderr, "unknown SGR parameter: %d\n", params[i]); + break; + } + } +} + +static void runes_vt100_handle_decsed(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 0 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + switch (params[0]) { + case 0: + /* XXX not quite correct */ + runes_display_clear_screen_forward(t); + break; + case 1: + /* XXX */ + fprintf(stderr, "unhandled DECSED parameter 1\n"); + break; + case 2: + /* XXX not quite correct */ + runes_display_clear_screen(t); + break; + default: + fprintf(stderr, "unknown DECSED parameter %d\n", params[0]); + break; + } +} + +static void runes_vt100_handle_decsel(RunesTerm *t, char *buf, size_t len) +{ + int params[RUNES_VT100_CSI_MAX_PARAMS] = { 0 }, nparams; + + runes_vt100_extract_csi_params(buf + 2, len - 3, params, &nparams); + switch (params[0]) { + case 0: + /* XXX not quite correct */ + runes_display_kill_line_forward(t); + break; + case 1: + /* XXX */ + fprintf(stderr, "unhandled DECSEL parameter 1\n"); + break; + case 2: + /* XXX */ + fprintf(stderr, "unhandled DECSEL parameter 2\n"); + break; + default: + fprintf(stderr, "unknown DECSEL parameter %d\n", params[0]); + break; + } +} + +static void runes_vt100_handle_osc0(RunesTerm *t, char *buf, size_t len) +{ + runes_window_backend_set_icon_name(t, buf + 4, len - 5); + runes_window_backend_set_window_title(t, buf + 4, len - 5); +} + +static void runes_vt100_handle_osc1(RunesTerm *t, char *buf, size_t len) +{ + runes_window_backend_set_icon_name(t, buf + 4, len - 5); +} + +static void runes_vt100_handle_osc2(RunesTerm *t, char *buf, size_t len) +{ + runes_window_backend_set_window_title(t, buf + 4, len - 5); +} |