Commit: c6d3f5262b88548410a0a49408b605f3021636f7
Parent: 6bfd5ccf1c1e40677b1b5a8d39eff986b75c4d62
Author: Randy Palamar
Date: Tue, 20 Aug 2024 06:37:22 -0600
basic scrollback support
There are still some things to work out but this is a starting point.
Diffstat:
4 files changed, 65 insertions(+), 11 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -32,7 +32,7 @@ struct {
u8 bgidx;
} g_colours = {base16_colours, 7, 0};
-#define KEYBIND_FN(name) void name(Term *t, Arg *a)
+#define KEYBIND_FN(name) b32 name(Term *t, Arg *a)
typedef KEYBIND_FN(KeyBind_Fn);
/* NOTE: Bindable Functions */
@@ -49,9 +49,13 @@ struct hotkey {
KeyBind_Fn *fn;
Arg arg;
} g_hotkeys[] = {
- {ENCODE_KEY(GLFW_PRESS, MODKEY, GLFW_KEY_V), paste, {0}},
- {ENCODE_KEY(GLFW_PRESS, TERMMOD, GLFW_KEY_MINUS), zoom, {.i = -1}},
- {ENCODE_KEY(GLFW_REPEAT, TERMMOD, GLFW_KEY_MINUS), zoom, {.i = -1}},
- {ENCODE_KEY(GLFW_PRESS, TERMMOD, GLFW_KEY_EQUAL), zoom, {.i = +1}},
- {ENCODE_KEY(GLFW_REPEAT, TERMMOD, GLFW_KEY_EQUAL), zoom, {.i = +1}},
+ {ENCODE_KEY(GLFW_PRESS, MODKEY, GLFW_KEY_V), paste, {0}},
+ {ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_PAGE_UP), scroll, {.i = +3}},
+ {ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_PAGE_UP), scroll, {.i = +3}},
+ {ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_PAGE_DOWN), scroll, {.i = -3}},
+ {ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_PAGE_DOWN), scroll, {.i = -3}},
+ {ENCODE_KEY(GLFW_PRESS, TERMMOD, GLFW_KEY_MINUS), zoom, {.i = -1}},
+ {ENCODE_KEY(GLFW_REPEAT, TERMMOD, GLFW_KEY_MINUS), zoom, {.i = -1}},
+ {ENCODE_KEY(GLFW_PRESS, TERMMOD, GLFW_KEY_EQUAL), zoom, {.i = +1}},
+ {ENCODE_KEY(GLFW_REPEAT, TERMMOD, GLFW_KEY_EQUAL), zoom, {.i = +1}},
};
diff --git a/terminal.c b/terminal.c
@@ -942,9 +942,10 @@ blit_lines(Term *t, Arena a, size line_count)
line_count = t->size.h - 1;
}
+ size off = t->scroll_offset;
CLAMP(line_count, 0, tv->lines.filled);
- for (size i = 0; i <= line_count; i++) {
- size line_idx = get_line_idx(&tv->lines, -line_count + i);
+ for (size idx = -line_count; idx <= 0; idx++) {
+ size line_idx = get_line_idx(&tv->lines, idx - off);
if (line_idx == tv->last_line_idx)
t->cursor.pos = tv->last_cursor_pos;
tv->last_cursor_pos = t->cursor.pos;
diff --git a/util.h b/util.h
@@ -291,6 +291,7 @@ typedef struct {
Cursor saved_cursors[2];
TermView views[2];
i32 view_idx;
+ i32 scroll_offset;
size unprocessed_bytes;
diff --git a/vtgl.c b/vtgl.c
@@ -305,6 +305,22 @@ KEYBIND_FN(paste)
text.len++;
os_child_put_s8(t->child, text);
}
+ return 1;
+}
+
+KEYBIND_FN(scroll)
+{
+ if (t->mode & TM_ALTSCREEN)
+ return 0;
+
+ TermView *tv = t->views + t->view_idx;
+
+ t->scroll_offset += a.i;
+ CLAMP(t->scroll_offset, 0, tv->lines.filled - (t->size.h - 1));
+
+ t->gl.flags |= NEEDS_FULL_BLIT;
+
+ return 1;
}
KEYBIND_FN(zoom)
@@ -312,6 +328,7 @@ KEYBIND_FN(zoom)
shift_font_sizes(&t->fa, a.i);
update_font_textures(t);
t->gl.flags |= NEEDS_RESIZE;
+ return 1;
}
/* NOTE: called when the window was resized */
@@ -360,8 +377,9 @@ key_callback(GLFWwindow *win, i32 key, i32 sc, i32 act, i32 mods)
for (u32 i = 0; i < ARRAY_COUNT(g_hotkeys); i++) {
struct hotkey *hk = g_hotkeys + i;
if (hk->key == enc) {
- hk->fn(t, hk->arg);
- return;
+ b32 handled = hk->fn(t, hk->arg);
+ if (handled)
+ return;
}
}
@@ -413,9 +431,39 @@ static void
char_callback(GLFWwindow *win, u32 codepoint)
{
Term *t = glfwGetWindowUserPointer(win);
+ if (t->scroll_offset) {
+ t->scroll_offset = 0;
+ t->gl.flags |= NEEDS_FULL_BLIT;
+ }
os_child_put_char(t->child, codepoint);
}
+static void
+scroll_callback(GLFWwindow *win, f64 xoff, f64 yoff)
+{
+ (void)xoff;
+
+ Term *t = glfwGetWindowUserPointer(win);
+ if (t->mode & TM_ALTSCREEN) {
+ b32 left_shift_state = glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS;
+ b32 right_shift_state = glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS;
+ b32 shift_down = left_shift_state || right_shift_state;
+ if (yoff > 0) {
+ if (shift_down) os_child_put_s8(t->child, s8("\x1B[5;2~"));
+ else os_child_put_s8(t->child, s8("\x19"));
+ } else {
+ if (shift_down) os_child_put_s8(t->child, s8("\x1B[6;2~"));
+ else os_child_put_s8(t->child, s8("\x05"));
+ }
+ } else {
+ Arg a = {.i = (i32)yoff};
+ if (glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) ||
+ glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT))
+ a.i *= 5;
+ scroll(t, a);
+ }
+}
+
DEBUG_EXPORT void
init_term(Term *t, Arena *a)
{
@@ -434,7 +482,7 @@ init_callbacks(GLCtx *gl)
glfwSetFramebufferSizeCallback(gl->window, fb_callback);
glfwSetKeyCallback(gl->window, key_callback);
//glfwSetWindowRefreshCallback(gl->window, refresh_callback);
- //glfwSetScrollCallback(gl->window, scroll_callback);
+ glfwSetScrollCallback(gl->window, scroll_callback);
}
DEBUG_EXPORT void