Commit: ff73f9bc324170725e679b93f9d20c0599dba62c
Parent: 157e7b8e182a21d809e6578a0a88f2ee4ebb021d
Author: Randy Palamar
Date: Sat, 6 Jul 2024 17:13:55 -0600
start handling some escapes used by vis
Diffstat:
M | terminal.c | | | 94 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
M | util.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 {