vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: ff73f9bc324170725e679b93f9d20c0599dba62c
Parent: 157e7b8e182a21d809e6578a0a88f2ee4ebb021d
Author: Randy Palamar
Date:   Sat,  6 Jul 2024 17:13:55 -0600

start handling some escapes used by vis

Diffstat:
Mterminal.c | 94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mutil.h | 3++-
2 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/terminal.c b/terminal.c @@ -156,6 +156,14 @@ cursor_step_column(Term *t, i32 step) } static void +term_reset(Term *t) +{ + cursor_reset(t); + cursor_move_to(t, 0, 0); + fb_clear_region(t, 0, t->size.h, 0, t->size.w); +} + +static void dump_csi(CSI *csi) { fputs("raw: ESC[", stderr); @@ -239,6 +247,14 @@ set_mode(Term *t, CSI *csi, b32 set) if (set) t->gl.mode |= WIN_MODE_APPCURSOR; else t->gl.mode &= ~WIN_MODE_APPCURSOR; break; + case PRIV(3): /* DECCOLM: 132/80 Column Mode */ + case PRIV(4): /* DECSCLM: Fast/Slow Scroll */ + /* IGNORED */ + break; + case PRIV(25): /* DECTCEM: Show/Hide Cursor */ + if (set) t->gl.mode |= WIN_MODE_HIDECURSOR; + else t->gl.mode &= ~WIN_MODE_HIDECURSOR; + break; case PRIV(1049): /* TODO: save cursor and switch to alt screen */ break; default: @@ -249,11 +265,50 @@ set_mode(Term *t, CSI *csi, b32 set) #undef PRIV } +enum { + DCR_FAILURE, + DCR_SUCCESS +}; + +struct direct_colour_result { + i32 status; + Colour colour; +}; + +static struct direct_colour_result +direct_colour(i32 *argv, i32 argc, i32 *idx) +{ + struct direct_colour_result result = {.status = DCR_FAILURE}; + switch (argv[*idx + 1]) { + case 2: /* define RGB colour */ + if (*idx + 4 >= argc) { + fprintf(stderr, "direct_colour: wrong paramater count: %d\n", argc); + break; + } + u32 r = (u32)argv[*idx + 2]; + u32 g = (u32)argv[*idx + 3]; + u32 b = (u32)argv[*idx + 4]; + *idx += 4; + if (r > 0xFF || g > 0xFF || b > 0xFF) { + fprintf(stderr, "direct_colour: bad rgb colour: (%u, %u, %u)\n", r, g, b); + break; + } + result.colour = (Colour){.r = r, .g = g, .b = b, .a = 0xFF}; + result.status = DCR_SUCCESS; + break; + case 5: /* TODO: indexed colour */ + default: + fprintf(stderr, "define_colour: unknown argument: %d\n", argv[*idx + 1]); + } + return result; +} + /* SGR: Select Graphic Rendition */ static void set_colours(Term *t, CSI *csi) { CellStyle *cs = &t->cursor.state; + struct direct_colour_result dcr; for (i32 i = 0; i < csi->argc; i++) { switch (csi->argv[i]) { case 0: cursor_reset(t); break; @@ -272,8 +327,28 @@ set_colours(Term *t, CSI *csi) case 27: cs->attr &= ~ATTR_INVERSE; break; case 28: cs->attr &= ~ATTR_INVISIBLE; break; case 29: cs->attr &= ~ATTR_STRUCK; break; + case 38: + dcr = direct_colour(csi->argv, csi->argc, &i); + if (dcr.status == DCR_SUCCESS) { + cs->fg = dcr.colour; + } else { + fputs("set_colours: ", stderr); + dump_csi(csi); + } + break; case 39: cs->fg = g_colours.data[g_colours.fgidx]; break; + + case 48: + dcr = direct_colour(csi->argv, csi->argc, &i); + if (dcr.status == DCR_SUCCESS) { + cs->bg = dcr.colour; + } else { + fputs("set_colours: ", stderr); + dump_csi(csi); + } + break; + case 49: cs->bg = g_colours.data[g_colours.bgidx]; break; default: @@ -281,6 +356,10 @@ set_colours(Term *t, CSI *csi) cs->fg = g_colours.data[csi->argv[i] - 30]; } else if (BETWEEN(csi->argv[i], 40, 47)) { cs->bg = g_colours.data[csi->argv[i] - 40]; + } else if (BETWEEN(csi->argv[i], 90, 97)) { + cs->fg = g_colours.data[csi->argv[i] - 82]; + } else if (BETWEEN(csi->argv[i], 100, 107)) { + cs->bg = g_colours.data[csi->argv[i] - 92]; } else { fprintf(stderr, "unhandled colour arg: %d\n", csi->argv[i]); dump_csi(csi); @@ -344,6 +423,7 @@ handle_csi(Term *t, s8 *raw) CSI csi = parse_csi(raw); ASSERT(csi.argc != -1); + u8 next; switch (csi.mode) { case 'H': cursor_move_to(t, csi.argv[0] - 1, csi.argv[1] - 1); break; case 'J': erase_in_display(t, &csi); break; @@ -352,6 +432,12 @@ handle_csi(Term *t, s8 *raw) case 'l': set_mode(t, &csi, 0); break; case 'm': set_colours(t, &csi); break; case 't': window_manipulation(t, &csi); break; + case '!': + next = get_ascii(raw); + ASSERT(next == 'p'); + /* NOTE: DECSTR: soft terminal reset (if next == p) */ + /* IGNORED */ + break; default: fputs("unknown csi: ", stderr); dump_csi(&csi); @@ -375,7 +461,10 @@ handle_escape(Term *t, s8 *raw) case '>': /* DECPNM -- normal keypad mode */ /* TODO: MODE_APPKEYPAD */ break; - case 'M': /* RI -- Reverse Index */ + case 'c': /* RIS -- Reset to Initial State */ + term_reset(t); + break; + case 'M': /* RI -- Reverse Index */ if (t->cursor.row == 0) { fb_scroll_down(t, 0, 1); } else { @@ -429,6 +518,9 @@ check_if_escape_moves_cursor(Term *t, s8 *raw) case '%': /* utf-8 mode */ get_ascii(raw); break; + case 'c': /* RIS -- Reset to Initial State */ + result = EMC_CURSOR_MOVED; + break; case 'M': /* RI -- Reverse Index */ if (t->cursor.row != 0) result = EMC_CURSOR_MOVED; diff --git a/util.h b/util.h @@ -163,7 +163,8 @@ enum gl_flags { }; enum win_mode { - WIN_MODE_APPCURSOR = 1 << 0, + WIN_MODE_APPCURSOR = 1 << 0, + WIN_MODE_HIDECURSOR = 1 << 1, }; enum shader_stages {