vtgl

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

Commit: fdcd02004956cbc600ecf952a5a19c9fe6a23cdb
Parent: 6554a03245002e17fcad62279eccf79c5ae1fdb4
Author: Randy Palamar
Date:   Sun,  1 Sep 2024 13:36:05 -0600

support DECOM (cursor origin mode)

Diffstat:
Mterminal.c | 67+++++++++++++++++++++++++++++++++++++++++++------------------------
Mutil.h | 3++-
2 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/terminal.c b/terminal.c @@ -235,12 +235,25 @@ cursor_reset(Term *t) static void cursor_move_to(Term *t, i32 row, i32 col) { - t->cursor.pos.y = CLAMP(row, 0, t->size.h - 1); + i32 minr = 0, maxr = t->size.h - 1; + if (t->cursor.state & CURSOR_ORIGIN) { + minr = t->top; + maxr = t->bot; + } + t->cursor.pos.y = CLAMP(row, minr, maxr); t->cursor.pos.x = CLAMP(col, 0, t->size.w - 1); t->cursor.state &= ~CURSOR_WRAP_NEXT; } static void +cursor_move_abs_to(Term *t, i32 row, i32 col) +{ + if (t->cursor.state & CURSOR_ORIGIN) + row += t->top; + cursor_move_to(t, row, col); +} + +static void cursor_alt(Term *t, b32 save) { i32 mode = t->view_idx; @@ -404,6 +417,11 @@ 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(6): /* DECOM: Cursor Origin Mode */ + if (set) t->cursor.state |= CURSOR_ORIGIN; + else t->cursor.state &= ~CURSOR_ORIGIN; + cursor_move_abs_to(t, 0, 0); + break; case PRIV(7): /* DECAWM: Auto-Wrap Mode */ if (set) t->mode |= TM_AUTO_WRAP; else t->mode &= ~TM_AUTO_WRAP; @@ -688,33 +706,34 @@ handle_csi(Term *t, CSI *csi) u8 next; switch (csi->mode) { - case 'A': cursor_step_raw(t, ORONE(csi->argv[0]), -1, 0); break; - case 'B': cursor_step_raw(t, ORONE(csi->argv[0]), 1, 0); break; - case 'C': cursor_step_raw(t, ORONE(csi->argv[0]), 0, 1); break; - case 'D': cursor_step_raw(t, ORONE(csi->argv[0]), 0, -1); break; - case 'E': cursor_move_to(t, p.y + ORONE(csi->argv[0]), 0); break; - case 'F': cursor_move_to(t, p.y - ORONE(csi->argv[0]), 0); break; - case 'G': cursor_move_to(t, p.y, csi->argv[0] - 1); break; - case 'H': cursor_move_to(t, csi->argv[0] - 1, csi->argv[1] - 1); break; - case 'J': erase_in_display(t, csi); break; - case 'K': erase_in_line(t, csi); break; - case 'L': insert_blank_lines(t, ORONE(csi->argv[0])); break; - case 'M': erase_lines(t, ORONE(csi->argv[0])); break; - case 'P': erase_characters(t, ORONE(csi->argv[0])); break; - case 'X': erase_characters(t, ORONE(csi->argv[0])); break; - case 'T': insert_blank_lines(t, ORONE(csi->argv[0])); break; - case 'Z': push_tab(t, -(ORONE(csi->argv[0]))); break; - case 'a': cursor_step_raw(t, ORONE(csi->argv[0]), 0, 1); break; - case 'd': cursor_move_to(t, csi->argv[0] - 1, p.x); break; - case 'e': cursor_step_raw(t, ORONE(csi->argv[0]), 1, 0); break; - case 'f': cursor_move_to(t, csi->argv[0] - 1, csi->argv[1] - 1); break; - case 'h': set_mode(t, csi, 1); break; - case 'l': set_mode(t, csi, 0); break; - case 'm': set_colours(t, csi); break; + case 'A': cursor_step_raw(t, ORONE(csi->argv[0]), -1, 0); break; + case 'B': cursor_step_raw(t, ORONE(csi->argv[0]), 1, 0); break; + case 'C': cursor_step_raw(t, ORONE(csi->argv[0]), 0, 1); break; + case 'D': cursor_step_raw(t, ORONE(csi->argv[0]), 0, -1); break; + case 'E': cursor_move_to(t, p.y + ORONE(csi->argv[0]), 0); break; + case 'F': cursor_move_to(t, p.y - ORONE(csi->argv[0]), 0); break; + case 'G': cursor_move_to(t, p.y, csi->argv[0] - 1); break; + case 'H': cursor_move_abs_to(t, csi->argv[0] - 1, csi->argv[1] - 1); break; + case 'J': erase_in_display(t, csi); break; + case 'K': erase_in_line(t, csi); break; + case 'L': insert_blank_lines(t, ORONE(csi->argv[0])); break; + case 'M': erase_lines(t, ORONE(csi->argv[0])); break; + case 'P': erase_characters(t, ORONE(csi->argv[0])); break; + case 'X': erase_characters(t, ORONE(csi->argv[0])); break; + case 'T': insert_blank_lines(t, ORONE(csi->argv[0])); break; + case 'Z': push_tab(t, -(ORONE(csi->argv[0]))); break; + case 'a': cursor_step_raw(t, ORONE(csi->argv[0]), 0, 1); break; + case 'd': cursor_move_abs_to(t, csi->argv[0] - 1, p.x); break; + case 'e': cursor_step_raw(t, ORONE(csi->argv[0]), 1, 0); break; + case 'f': cursor_move_abs_to(t, csi->argv[0] - 1, csi->argv[1] - 1); break; + case 'h': set_mode(t, csi, 1); break; + case 'l': set_mode(t, csi, 0); break; + case 'm': set_colours(t, csi); break; case 'r': if (csi->priv) goto unknown; set_scrolling_region(t, csi); + cursor_move_abs_to(t, 0, 0); break; case 't': window_manipulation(t, csi); break; case '!': diff --git a/util.h b/util.h @@ -123,7 +123,8 @@ typedef struct { enum cursor_state { CURSOR_NORMAL = 0 << 0, - CURSOR_WRAP_NEXT = 1 << 1, + CURSOR_WRAP_NEXT = 1 << 0, + CURSOR_ORIGIN = 1 << 1, }; typedef struct {