vtgl

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

Commit: 2d5c620da17f700f0c34fa0fcec0135a5df27465
Parent: dfbc514f0f6261e1ba71941176544b9750a92e2f
Author: Randy Palamar
Date:   Tue,  3 Sep 2024 18:17:25 -0600

implement -g for setting geometry on startup

Diffstat:
Mbuild.sh | 3++-
Mmain.c | 47+++++++++++++++++++++++++++++++++++++++++++++--
Mterminal.c | 24+++++++-----------------
Mutil.c | 28++++++++++++++++++++++++++++
Mutil.h | 7+++++++
Mvtgl.c | 11+++++------
6 files changed, 94 insertions(+), 26 deletions(-)

diff --git a/build.sh b/build.sh @@ -2,8 +2,9 @@ cc=${CC:-cc} debug=${DEBUG} +version=$(git describe --dirty --always) -cflags="-march=native -O3 -Wall" +cflags="-march=native -O3 -Wall -DVERSION=\"${version}\"" cflags="$cflags $(pkg-config --cflags glfw3 gl)" #cflags="${cflags} -fproc-stat-report" #cflags="${cflags} -Rpass-missed=.*" diff --git a/main.c b/main.c @@ -6,6 +6,10 @@ #include "util.h" +#ifndef VERSION +#define VERSION "unknown" +#endif + #ifndef _DEBUG #define do_debug(...) #include "vtgl.c" @@ -106,7 +110,7 @@ init_window(Term *t, Arena arena, iv2 requested_size) iv2 ws; glfwGetMonitorWorkarea(mon, NULL, NULL, &ws.w, &ws.h); - if (requested_size.w != -1 && requested_size.h != -1) { + if (requested_size.w > 0 && requested_size.h > 0) { t->gl.window_size = (v2){.w = requested_size.w, .h = requested_size.h}; glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); glfwWindowHint(GLFW_FLOATING, GLFW_TRUE); @@ -280,13 +284,52 @@ check_shaders(GLCtx *gl, Arena a) } } +static void +usage(char *argv0) +{ + die("usage: %s [-v] [-g COLxROW]\n", argv0); +} + i32 -main(void) +main(i32 argc, char *argv[]) { Arena memory = os_new_arena(16 * MEGABYTE); Term term = {0}; iv2 cells = {.x = -1, .y = -1}; + + char *argv0 = *argv++; + argc--; + struct conversion_result cres; + for (i32 i = 0; i < argc; i++) { + char *arg = argv[i]; + if (!arg || !arg[0]) + usage(argv0); + if (arg[0] != '-') + break; + arg++; + switch (arg[0]) { + case 'g': + if (!argv[i + 1]) + usage(argv0); + cres = i32_from_cstr(argv[i + 1], 'x'); + if (cres.status == CR_SUCCESS) + cells.w = cres.i; + cres = i32_from_cstr(cres.unparsed, 0); + if (cres.status == CR_SUCCESS) + cells.h = cres.i; + if (cells.w <= 0 || cells.h <= 0) + fprintf(stderr, "ignoring malformed geometry: %s\n", argv[i + 1]); + argv++; + argc--; + break; + case 'v': + die("%s " VERSION "\n", argv0); + default: + usage(argv0); + } + } + do_debug(NULL); iv2 requested_size = init_term(&term, &memory, cells); init_window(&term, memory, requested_size); diff --git a/terminal.c b/terminal.c @@ -474,16 +474,6 @@ set_mode(Term *t, CSI *csi, b32 set) #undef PRIV } -enum { - DCR_FAILURE, - DCR_SUCCESS -}; - -struct direct_colour_result { - i32 status; - Colour colour; -}; - /* NOTE: adapted from the perl script 256colres.pl in xterm src */ static Colour indexed_colour(i32 index) @@ -508,10 +498,10 @@ indexed_colour(i32 index) return result; } -static struct direct_colour_result +static struct conversion_result direct_colour(i32 *argv, i32 argc, i32 *idx) { - struct direct_colour_result result = {.status = DCR_FAILURE}; + struct conversion_result result = {.status = CR_FAILURE}; switch (argv[*idx + 1]) { case 2: /* NOTE: defined RGB colour */ if (*idx + 4 >= argc) { @@ -527,7 +517,7 @@ direct_colour(i32 *argv, i32 argc, i32 *idx) break; } result.colour = (Colour){.r = r, .g = g, .b = b, .a = 0xFF}; - result.status = DCR_SUCCESS; + result.status = CR_SUCCESS; break; case 5: /* NOTE: indexed colour */ if (*idx + 2 >= argc) { @@ -544,7 +534,7 @@ direct_colour(i32 *argv, i32 argc, i32 *idx) result.colour = g_colours.data[argv[*idx]]; else result.colour = indexed_colour(argv[*idx]); - result.status = DCR_SUCCESS; + result.status = CR_SUCCESS; break; default: fprintf(stderr, "define_colour: unknown argument: %d\n", argv[*idx + 1]); @@ -557,7 +547,7 @@ static void set_colours(Term *t, CSI *csi) { CellStyle *cs = &t->cursor.style; - struct direct_colour_result dcr; + struct conversion_result dcr; for (i32 i = 0; i < csi->argc; i++) { switch (csi->argv[i]) { case 0: cursor_reset(t); break; @@ -578,7 +568,7 @@ set_colours(Term *t, CSI *csi) case 29: cs->attr &= ~ATTR_STRUCK; break; case 38: dcr = direct_colour(csi->argv, csi->argc, &i); - if (dcr.status == DCR_SUCCESS) { + if (dcr.status == CR_SUCCESS) { cs->fg = dcr.colour; } else { fputs("set_colours: ", stderr); @@ -590,7 +580,7 @@ set_colours(Term *t, CSI *csi) case 48: dcr = direct_colour(csi->argv, csi->argc, &i); - if (dcr.status == DCR_SUCCESS) { + if (dcr.status == CR_SUCCESS) { cs->bg = dcr.colour; } else { fputs("set_colours: ", stderr); diff --git a/util.c b/util.c @@ -135,6 +135,34 @@ s8_to_cstr(Arena *a, s8 s) return cstr; } +static struct conversion_result +i32_from_cstr(char *s, char delim) +{ + struct conversion_result ret = {.status = CR_FAILURE}; + i32 scale = 1; + + if (!s || !s[0]) + return ret; + + if (s[0] == '-') { + s++; + scale = -1; + } + + for (; *s && *s != delim; s++) { + if (!BETWEEN(s[0], '0', '9')) + return ret; + ret.i *= 10; + ret.i += s[0] - '0'; + } + + ret.i *= scale; + ret.status = CR_SUCCESS; + ret.unparsed = (*s == delim) ? s + 1 : s; + + return ret; +} + static s8 utf8_encode(u32 cp) { diff --git a/util.h b/util.h @@ -264,6 +264,13 @@ typedef struct { #define MAX_FONT_SIZE 128 +enum conversion_status { CR_FAILURE, CR_SUCCESS }; +struct conversion_result { + i32 status; + char *unparsed; + union { i32 i; f32 f; Colour colour;}; +}; + #include "util.c" #define STB_TRUETYPE_IMPLEMENTATION diff --git a/vtgl.c b/vtgl.c @@ -768,7 +768,6 @@ scroll_callback(GLFWwindow *win, f64 xoff, f64 yoff) DEBUG_EXPORT iv2 init_term(Term *t, Arena *a, iv2 cells) { - iv2 requested_size = {.x = -1, .y = -1}; init_fonts(t, a); for (u32 i = 0; i < ARRAY_COUNT(t->saved_cursors); i++) { cursor_reset(t); @@ -776,11 +775,11 @@ init_term(Term *t, Arena *a, iv2 cells) cursor_alt(t, 1); } selection_clear(&t->selection); - if (cells.x != -1 && cells.y != -1) { - v2 cs = get_cell_size(t); - requested_size.x = cs.x * cells.x + 2 * g_term_pad.x; - requested_size.y = cs.y * cells.y + 2 * g_term_pad.y; - } + v2 cs = get_cell_size(t); + iv2 requested_size = { + .x = cs.x * cells.x + 2 * g_term_pad.x, + .y = cs.y * cells.y + 2 * g_term_pad.y, + }; return requested_size; }