vtgl

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

Commit: 85b37299588331849b353f3194673995e2db5220
Parent: aed2bfe73d3afe9a37f9a39fdfbcfd08e20e09a5
Author: Randy Palamar
Date:   Mon, 24 Jun 2024 20:10:28 -0600

handle some control chars in push_line

Diffstat:
Mbuild.sh | 2++
Aconfig.def.h | 1+
Mutil.h | 4++++
Mvtgl.c | 39+++++++++++++++++++++++++++++----------
4 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/build.sh b/build.sh @@ -11,5 +11,7 @@ cflags="$cflags -D_DEBUG -Wno-unused-function" libcflags="$cflags -fPIC -Wno-unused-function" libldflags="$ldflags -shared" +if ! [ -s "./config.h" ]; then cp ./config.def.h ./config.h; fi + cc $libcflags vtgl.c -o vtgl.so $libldflags cc $cflags -o vtgl main.c $ldflags diff --git a/config.def.h b/config.def.h @@ -0,0 +1 @@ +static u8 g_tabstop = 8; diff --git a/util.h b/util.h @@ -27,6 +27,9 @@ #define ISPRINT(c) BETWEEN((c), ' ', '~') +/* NOTE: GLFW does not sequentially number keys so switch statement will never be optimized */ +#define ENCODE_KEY(action, mod, key) (((action) << 24) | ((mod) << 16) | ((key) & 0xFFFF)) + typedef float f32; typedef double f64; typedef uint8_t u8; @@ -198,6 +201,7 @@ typedef struct { FT_Library ftlib; } Term; +#include "config.h" #include "font.c" #include "terminal.c" diff --git a/vtgl.c b/vtgl.c @@ -154,7 +154,6 @@ push_cell(Term *t, u32 cp, Rect r, u32 bg, u32 fg) .y = g.size.h / MAX_FONT_SIZE, }; - i32 charmap[2]; charmap[0] = depth_idx; charmap[1] = depth_idx; @@ -195,6 +194,15 @@ line_to_s8(Line *l) } static void +push_tab(Term *t) +{ + u32 col = t->cursor.col; + u32 advance = g_tabstop - col % g_tabstop; + t->cursor.col += advance; + /* TODO: wrap cursor if it goes of edge of terminal */ +} + +static void push_line(Term *t, Line *line, v2 start_pos) { s8 l = line_to_s8(line); @@ -208,17 +216,19 @@ push_line(Term *t, Line *line, v2 start_pos) u32 cp = get_ascii(&l); switch (cp) { case 0x1B: handle_escape(t, &l); break; + case '\b': t->cursor.col--; break; /* TODO: make sure cursor is clamped */ + case '\r': t->cursor.col = 0; break; + case '\n': t->cursor.row++; break; + case '\t': push_tab(t); break; default: /* TODO properly make characters are printable */ CLAMP(cp, ' ', '~'); + cr.pos.w = cs.w * t->cursor.col; push_cell(t, cp, cr, t->cursor.state.bg.rgba, t->cursor.state.fg.rgba); - cr.pos.w += cs.w; /* TODO: properly advance cursor */ t->cursor.col++; } } - /* TODO: properly advance cursor */ - t->cursor.row++; } static void @@ -231,12 +241,10 @@ blit_lines(Term *t) ASSERT(t->log_lines.widx >= line_count); size line_off = t->log_lines.widx - line_count; - /* TODO: properly set cursor */ + /* NOTE: for now we assume that we blit the whole screen everytime */ t->cursor.row = 0; - + t->cursor.col = 0; for (size i = 0; i <= line_count; i++) { - /* TODO: properly set cursor */ - t->cursor.col = 0; v2 pos = { .x = t->cursor.col * cs.w, .y = t->gl.window_size.h - (t->cursor.row + 1) * cs.h @@ -259,10 +267,21 @@ static void key_callback(GLFWwindow *win, i32 key, i32 sc, i32 act, i32 mods) { Term *t = glfwGetWindowUserPointer(win); - if (key == GLFW_KEY_ESCAPE && act == GLFW_PRESS) + + switch (ENCODE_KEY(act, 0, key)) { + case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_ESCAPE): + case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_ESCAPE): glfwSetWindowShouldClose(win, GL_TRUE); - if (key == GLFW_KEY_ENTER && act == GLFW_PRESS) + break; + case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_ENTER): + case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_ENTER): os_child_put_char(t->child, '\r'); + break; + case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_BACKSPACE): + case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_BACKSPACE): + os_child_put_char(t->child, 0x7F); + break; + } } static void