vtgl

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

Commit: f329ac43b51dc3df831fc59b4bef055a6b585a9d
Parent: 47d920130d77b3f255cdde28c159d212cf056c93
Author: Randy Palamar
Date:   Fri, 15 Nov 2024 08:07:47 -0700

move key callback out of the terminal

There should still be a better way of handling this but this is
good enough for now to get rid of the rest of the GLFW calls in
the terminal.

Diffstat:
Mplatform_linux_x11.c | 97+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mutil.h | 1-
Mvtgl.c | 95+++++++++++++++++++++++++++++++++++--------------------------------------------
Mvtgl.h | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
4 files changed, 245 insertions(+), 104 deletions(-)

diff --git a/platform_linux_x11.c b/platform_linux_x11.c @@ -1,5 +1,5 @@ /* See LICENSE for copyright details */ -#define GL_GLEXT_PROTOTYPES 1 +#define GL_GLEXT_PROTOTYPES #include <GLFW/glfw3.h> /* TODO: fix glfw */ @@ -34,6 +34,8 @@ typedef struct { TerminalMemory memory; TerminalInput input; + Stream char_stream; + posix_platform_process child; i32 inotify_fd; @@ -45,9 +47,6 @@ typedef struct { #ifdef _DEBUG void *library_handle; #endif - - /* TODO: remove */ - b32 terminal_initialized; } PlatformCtx; static PlatformCtx linux_ctx; @@ -61,15 +60,12 @@ static PlatformCtx linux_ctx; #define DEBUG_LIB_NAME "./vtgl.so" -/* TODO: cleanup */ -typedef void reset_terminal_fn(TerminalMemory *); - #define LIB_FNS \ X(debug_begin_frame) \ X(debug_end_frame) \ - X(reset_terminal) \ X(vtgl_active_selection) \ X(vtgl_initialize) \ + X(vtgl_handle_keys) \ X(vtgl_frame_step) #define X(name) static name ## _fn *name; @@ -99,7 +95,6 @@ static PLATFORM_FILE_WATCH_CALLBACK_FN(debug_reload_library) LIB_FNS #undef X - if (ctx->terminal_initialized) reset_terminal(&ctx->memory); stream_push_s8(&ctx->error_stream, s8("Reloaded Main Program\n")); os_write_err_msg(stream_to_s8(&ctx->error_stream)); @@ -135,34 +130,70 @@ glfw_error_callback(int code, const char *desc) static void char_callback(GLFWwindow *win, u32 codepoint) { - tmp_user_ctx *ctx = glfwGetWindowUserPointer(win); - TerminalInput *input = ctx->input; - stream_push_s8(&input->char_stream, utf8_encode(codepoint)); + PlatformCtx *ctx = glfwGetWindowUserPointer(win); + stream_push_s8(&ctx->char_stream, utf8_encode(codepoint)); } /* NOTE: called when the window was resized */ static void fb_callback(GLFWwindow *win, i32 w, i32 h) { - //TerminalInput *input = glfwGetWindowUserPointer(win); - tmp_user_ctx *ctx = glfwGetWindowUserPointer(win); - ctx->input->window_size = (iv2){.w = w, .h = h}; + PlatformCtx *ctx = glfwGetWindowUserPointer(win); + ctx->input.window_size = (iv2){.w = w, .h = h}; } static void scroll_callback(GLFWwindow *win, f64 xoff, f64 yoff) { - tmp_user_ctx *ctx = glfwGetWindowUserPointer(win); - TerminalInput *input = ctx->input; - input->mouse_scroll.x = xoff; - input->mouse_scroll.y = yoff; + PlatformCtx *ctx = glfwGetWindowUserPointer(win); + ctx->input.mouse_scroll.x = xoff; + ctx->input.mouse_scroll.y = yoff; +} + +static void +key_callback(GLFWwindow *win, i32 key, i32 scancode, i32 action, i32 modifiers) +{ + PlatformCtx *ctx = glfwGetWindowUserPointer(win); + TerminalInput *input = &ctx->input; + + /* TODO: base this on X11 keys directly */ + switch (key) { + case GLFW_KEY_LEFT_SHIFT: + button_action(input->keys + KEY_LEFT_SHIFT, action == GLFW_PRESS); + break; + case GLFW_KEY_LEFT_CONTROL: + button_action(input->keys + KEY_LEFT_CONTROL, action == GLFW_PRESS); + break; + case GLFW_KEY_LEFT_ALT: + button_action(input->keys + KEY_LEFT_ALT, action == GLFW_PRESS); + break; + case GLFW_KEY_LEFT_SUPER: + button_action(input->keys + KEY_LEFT_SUPER, action == GLFW_PRESS); + break; + case GLFW_KEY_RIGHT_SHIFT: + button_action(input->keys + KEY_RIGHT_SHIFT, action == GLFW_PRESS); + break; + case GLFW_KEY_RIGHT_CONTROL: + button_action(input->keys + KEY_RIGHT_CONTROL, action == GLFW_PRESS); + break; + case GLFW_KEY_RIGHT_ALT: + button_action(input->keys + KEY_RIGHT_ALT, action == GLFW_PRESS); + break; + case GLFW_KEY_RIGHT_SUPER: + button_action(input->keys + KEY_RIGHT_SUPER, action == GLFW_PRESS); + break; + case GLFW_KEY_MENU: + button_action(input->keys + KEY_MENU, action == GLFW_PRESS); + break; + } + vtgl_handle_keys(&ctx->memory, &ctx->input, key, action, modifiers); } static void mouse_button_callback(GLFWwindow *win, i32 button, i32 action, i32 modifiers) { - tmp_user_ctx *ctx = glfwGetWindowUserPointer(win); - TerminalInput *input = ctx->input; + PlatformCtx *ctx = glfwGetWindowUserPointer(win); + TerminalInput *input = &ctx->input; switch (button) { case GLFW_MOUSE_BUTTON_LEFT: @@ -184,7 +215,7 @@ mouse_button_callback(GLFWwindow *win, i32 button, i32 action, i32 modifiers) } static GLFWwindow * -init_window(tmp_user_ctx *ctx, iv2 window_size) +init_window(PlatformCtx *ctx, iv2 window_size) { glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); @@ -213,6 +244,7 @@ init_window(tmp_user_ctx *ctx, iv2 window_size) glfwSetCharCallback(window, char_callback); glfwSetFramebufferSizeCallback(window, fb_callback); + glfwSetKeyCallback(window, key_callback); glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetScrollCallback(window, scroll_callback); @@ -275,7 +307,7 @@ update_input(PlatformCtx *ctx) for (u32 i = 0; i < ARRAY_COUNT(input->keys); i++) input->keys[i].transitions = 0; - input->char_stream.widx = 0; + ctx->char_stream.widx = 0; glfwPollEvents(); @@ -297,7 +329,7 @@ update_input(PlatformCtx *ctx) } /* NOTE: char_stream was filled in char callback */ - input->character_input = stream_to_s8(&input->char_stream); + input->character_input = stream_to_s8(&ctx->char_stream); } static PLATFORM_CLIPBOARD_FN(x11_get_clipboard) @@ -464,15 +496,10 @@ main(i32 argc, char *argv[], char *envp[]) iv2 monitor_size; glfwGetMonitorWorkarea(mon, NULL, NULL, &monitor_size.w, &monitor_size.h); - linux_ctx.input.char_stream = arena_stream(linux_ctx.platform_memory); - - /* TODO: delete !!!! */ - tmp_user_ctx ctx; - ctx.memory = &linux_ctx.memory; - ctx.input = &linux_ctx.input; + linux_ctx.char_stream = arena_stream(linux_ctx.platform_memory); iv2 window_size = {.w = 1280, .h = 720}; - linux_ctx.window = init_window(&ctx, window_size); + linux_ctx.window = init_window(&linux_ctx, window_size); linux_ctx.child = os_fork_child("/bin/sh"); iv2 requested_size = vtgl_initialize(&linux_ctx.memory, linux_ctx.child.handle, cells, monitor_size); @@ -500,14 +527,6 @@ main(i32 argc, char *argv[], char *envp[]) linux_ctx.input.window_size = window_size; - /* TODO: remove */ - { - Term *t = linux_ctx.memory.memory; - t->gl.window = linux_ctx.window; - reset_terminal(&linux_ctx.memory); - linux_ctx.terminal_initialized = 1; - } - Range last_sel = {0}; f64 last_time = os_get_time(); while (!glfwWindowShouldClose(linux_ctx.window)) { diff --git a/util.h b/util.h @@ -267,7 +267,6 @@ typedef struct { } ShaderParameters; typedef struct { - GLFWwindow *window; iv2 window_size; u32 vao, vbos[5]; diff --git a/vtgl.c b/vtgl.c @@ -1,6 +1,7 @@ /* See LICENSE for copyright details */ -#define GL_GLEXT_PROTOTYPES 1 -#include <GLFW/glfw3.h> +/* TODO: define this ourselves since we should be loading it at runtime */ +#define GL_GLEXT_PROTOTYPES +#include <GL/glcorearb.h> #include "util.h" @@ -755,43 +756,41 @@ KEYBIND_FN(zoom) return 1; } -static void -key_callback(GLFWwindow *win, i32 key, i32 sc, i32 act, i32 mods) +DEBUG_EXPORT VTGL_HANDLE_KEYS_FN(vtgl_handle_keys) { - tmp_user_ctx *ctx = glfwGetWindowUserPointer(win); - Term *t = ctx->memory->memory; + Term *t = memory->memory; #ifdef _DEBUG - if (key == GLFW_KEY_F1 && act == GLFW_PRESS) { + if (key == KEY_F1 && action == ACT_PRESS) { dump_lines_to_file(t); return; } - if (key == GLFW_KEY_F11 && act == GLFW_PRESS) { + if (key == KEY_F11 && action == ACT_PRESS) { /* TODO: probably move this into the debug frame start */ - DebugState *ds = ctx->memory->debug_memory; + DebugState *ds = memory->debug_memory; ds->paused = !ds->paused; return; } - if (key == GLFW_KEY_F12 && act == GLFW_PRESS) { + if (key == KEY_F12 && action == ACT_PRESS) { t->gl.flags ^= DRAW_DEBUG_OVERLAY; return; } #endif /* NOTE: handle mapped keybindings */ - u32 enc = ENCODE_KEY(act, mods, key); + u32 enc = ENCODE_KEY(action, modifiers, key); for (u32 i = 0; i < ARRAY_COUNT(g_hotkeys); i++) { struct hotkey *hk = g_hotkeys + i; if (hk->key == enc) { - b32 handled = hk->fn(t, &ctx->memory->platform_api, hk->arg); + b32 handled = hk->fn(t, &memory->platform_api, hk->arg); if (handled) return; } } /* NOTE: send control sequences */ - if (mods & GLFW_MOD_CONTROL && act != GLFW_RELEASE) { - /* TODO: this is wrong. look up where 8-bit mods should be sent */ + if (modifiers & MOD_CONTROL && action != ACT_RELEASE) { + /* TODO: this is wrong. look up where 8-bit modifiers should be sent */ if (0 && t->gl.mode & WIN_MODE_8BIT) { if (key < 0x7F) { s8 enc = utf8_encode(key | 0x80); @@ -805,61 +804,61 @@ key_callback(GLFWwindow *win, i32 key, i32 sc, i32 act, i32 mods) } /* TODO: construct a hash table of bound keys */ - switch (ENCODE_KEY(act, 0, key)) { - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_ESCAPE): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_ESCAPE): + switch (ENCODE_KEY(action, 0, key)) { + case ENCODE_KEY(ACT_PRESS, 0, KEY_ESCAPE): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_ESCAPE): os_child_put_char(t->child, 0x1B); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_TAB): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_TAB): + case ENCODE_KEY(ACT_PRESS, 0, KEY_TAB): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_TAB): os_child_put_char(t->child, '\t'); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_ENTER): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_ENTER): + case ENCODE_KEY(ACT_PRESS, 0, KEY_ENTER): + case ENCODE_KEY(ACT_REPEAT, 0, 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): + case ENCODE_KEY(ACT_PRESS, 0, KEY_BACKSPACE): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_BACKSPACE): os_child_put_char(t->child, 0x7F); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_UP): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_UP): + case ENCODE_KEY(ACT_PRESS, 0, KEY_UP): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_UP): if (t->gl.mode & WIN_MODE_APPCURSOR) os_child_put_s8(t->child, s8("\x1BOA")); else os_child_put_s8(t->child, s8("\x1B[A")); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_DOWN): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_DOWN): + case ENCODE_KEY(ACT_PRESS, 0, KEY_DOWN): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_DOWN): if (t->gl.mode & WIN_MODE_APPCURSOR) os_child_put_s8(t->child, s8("\x1BOB")); else os_child_put_s8(t->child, s8("\x1B[B")); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_RIGHT): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_RIGHT): + case ENCODE_KEY(ACT_PRESS, 0, KEY_RIGHT): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_RIGHT): if (t->gl.mode & WIN_MODE_APPCURSOR) os_child_put_s8(t->child, s8("\x1BOC")); else os_child_put_s8(t->child, s8("\x1B[C")); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_LEFT): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_LEFT): + case ENCODE_KEY(ACT_PRESS, 0, KEY_LEFT): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_LEFT): if (t->gl.mode & WIN_MODE_APPCURSOR) os_child_put_s8(t->child, s8("\x1BOD")); else os_child_put_s8(t->child, s8("\x1B[D")); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_PAGE_UP): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_PAGE_UP): - if (mods & GLFW_MOD_CONTROL) os_child_put_s8(t->child, s8("\x1B[5;5~")); - else if (mods & GLFW_MOD_SHIFT) os_child_put_s8(t->child, s8("\x1B[5;2~")); + case ENCODE_KEY(ACT_PRESS, 0, KEY_PAGE_UP): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_PAGE_UP): + if (modifiers & MOD_CONTROL) os_child_put_s8(t->child, s8("\x1B[5;5~")); + else if (modifiers & MOD_SHIFT) os_child_put_s8(t->child, s8("\x1B[5;2~")); else os_child_put_s8(t->child, s8("\x1B[5~")); break; - case ENCODE_KEY(GLFW_PRESS, 0, GLFW_KEY_PAGE_DOWN): - case ENCODE_KEY(GLFW_REPEAT, 0, GLFW_KEY_PAGE_DOWN): - if (mods & GLFW_MOD_CONTROL) os_child_put_s8(t->child, s8("\x1B[6;5~")); - else if (mods & GLFW_MOD_SHIFT) os_child_put_s8(t->child, s8("\x1B[6;2~")); + case ENCODE_KEY(ACT_PRESS, 0, KEY_PAGE_DOWN): + case ENCODE_KEY(ACT_REPEAT, 0, KEY_PAGE_DOWN): + if (modifiers & MOD_CONTROL) os_child_put_s8(t->child, s8("\x1B[6;5~")); + else if (modifiers & MOD_SHIFT) os_child_put_s8(t->child, s8("\x1B[6;2~")); else os_child_put_s8(t->child, s8("\x1B[6~")); break; } @@ -868,12 +867,11 @@ key_callback(GLFWwindow *win, i32 key, i32 sc, i32 act, i32 mods) static void handle_keybindings(Term *t, TerminalInput *input, PlatformAPI *platform) { - GLFWwindow *win = t->gl.window; if (input->mouse_scroll.y) { + b32 left_shift_state = input->keys[KEY_LEFT_SHIFT].ended_down; + b32 right_shift_state = input->keys[KEY_RIGHT_SHIFT].ended_down; + b32 shift_down = left_shift_state || right_shift_state; 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 (input->mouse_scroll.y > 0) { if (shift_down) platform->write(t->child, s8("\x1B[5;2~"), 0); else platform->write(t->child, s8("\x19"), 0); @@ -883,8 +881,7 @@ handle_keybindings(Term *t, TerminalInput *input, PlatformAPI *platform) } } else { Arg a = {.i = (i32)input->mouse_scroll.y}; - if (glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) || - glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT)) + if (shift_down) a.i *= 5; scroll(t, platform, a); } @@ -994,14 +991,6 @@ gen_2D_texture(iv2 size, u32 format, u32 filter, u32 *rgba) return result; } -DEBUG_EXPORT void -reset_terminal(TerminalMemory *memory) -{ - Term *t = memory->memory; - glfwSetKeyCallback(t->gl.window, key_callback); - //glfwSetWindowRefreshCallback(t->gl.window, refresh_callback); -} - DEBUG_EXPORT VTGL_INITIALIZE_FN(vtgl_initialize) { Term *t = (Term *)memory->memory; diff --git a/vtgl.h b/vtgl.h @@ -56,6 +56,126 @@ enum { CLIPBOARD_1, }; +/* TODO: for now these are just based on the GLFW keycodes directly. It might + * be better for the platform to define these values themselves */ +#define ACT_RELEASE 0 +#define ACT_PRESS 1 +#define ACT_REPEAT 2 + +#define KEY_SPACE 32 +#define KEY_APOSTROPHE 39 /* ' */ +#define KEY_COMMA 44 /* , */ +#define KEY_MINUS 45 /* - */ +#define KEY_PERIOD 46 /* . */ +#define KEY_SLASH 47 /* / */ +#define KEY_0 48 +#define KEY_1 49 +#define KEY_2 50 +#define KEY_3 51 +#define KEY_4 52 +#define KEY_5 53 +#define KEY_6 54 +#define KEY_7 55 +#define KEY_8 56 +#define KEY_9 57 +#define KEY_SEMICOLON 59 /* ; */ +#define KEY_EQUAL 61 /* = */ +#define KEY_A 65 +#define KEY_B 66 +#define KEY_C 67 +#define KEY_D 68 +#define KEY_E 69 +#define KEY_F 70 +#define KEY_G 71 +#define KEY_H 72 +#define KEY_I 73 +#define KEY_J 74 +#define KEY_K 75 +#define KEY_L 76 +#define KEY_M 77 +#define KEY_N 78 +#define KEY_O 79 +#define KEY_P 80 +#define KEY_Q 81 +#define KEY_R 82 +#define KEY_S 83 +#define KEY_T 84 +#define KEY_U 85 +#define KEY_V 86 +#define KEY_W 87 +#define KEY_X 88 +#define KEY_Y 89 +#define KEY_Z 90 +#define KEY_LEFT_BRACKET 91 /* [ */ +#define KEY_BACKSLASH 92 /* \ */ +#define KEY_RIGHT_BRACKET 93 /* ] */ +#define KEY_GRAVE_ACCENT 96 /* ` */ +#define KEY_WORLD_1 161 /* non-US #1 */ +#define KEY_WORLD_2 162 /* non-US #2 */ + +/* Function keys */ +#define KEY_ESCAPE 256 +#define KEY_ENTER 257 +#define KEY_TAB 258 +#define KEY_BACKSPACE 259 +#define KEY_INSERT 260 +#define KEY_DELETE 261 +#define KEY_RIGHT 262 +#define KEY_LEFT 263 +#define KEY_DOWN 264 +#define KEY_UP 265 +#define KEY_PAGE_UP 266 +#define KEY_PAGE_DOWN 267 +#define KEY_HOME 268 +#define KEY_END 269 +#define KEY_CAPS_LOCK 280 +#define KEY_SCROLL_LOCK 281 +#define KEY_NUM_LOCK 282 +#define KEY_PRINT_SCREEN 283 +#define KEY_PAUSE 284 +#define KEY_F1 290 +#define KEY_F2 291 +#define KEY_F3 292 +#define KEY_F4 293 +#define KEY_F5 294 +#define KEY_F6 295 +#define KEY_F7 296 +#define KEY_F8 297 +#define KEY_F9 298 +#define KEY_F10 299 +#define KEY_F11 300 +#define KEY_F12 301 +#define KEY_F13 302 +#define KEY_F14 303 +#define KEY_F15 304 +#define KEY_F16 305 +#define KEY_F17 306 +#define KEY_F18 307 +#define KEY_F19 308 +#define KEY_F20 309 +#define KEY_F21 310 +#define KEY_F22 311 +#define KEY_F23 312 +#define KEY_F24 313 +#define KEY_F25 314 +#define KEY_KP_0 320 +#define KEY_KP_1 321 +#define KEY_KP_2 322 +#define KEY_KP_3 323 +#define KEY_KP_4 324 +#define KEY_KP_5 325 +#define KEY_KP_6 326 +#define KEY_KP_7 327 +#define KEY_KP_8 328 +#define KEY_KP_9 329 +#define KEY_KP_DECIMAL 330 +#define KEY_KP_DIVIDE 331 +#define KEY_KP_MULTIPLY 332 +#define KEY_KP_SUBTRACT 333 +#define KEY_KP_ADD 334 +#define KEY_KP_ENTER 335 +#define KEY_KP_EQUAL 336 + enum input_keys { MOUSE_LEFT, MOUSE_RIGHT, @@ -63,13 +183,32 @@ enum input_keys { MOUSE_EXTENDED_0, MOUSE_EXTENDED_1, + KEY_LEFT_SHIFT, + KEY_LEFT_CONTROL, + KEY_LEFT_ALT, + KEY_LEFT_SUPER, + KEY_RIGHT_SHIFT, + KEY_RIGHT_CONTROL, + KEY_RIGHT_ALT, + KEY_RIGHT_SUPER, + KEY_MENU, + INPUT_KEY_COUNT, }; +enum modifiers { + MOD_SHIFT = (1 << 0), + MOD_CONTROL = (1 << 1), + MOD_ALT = (1 << 2), + MOD_SUPER = (1 << 3), + + MOD_MASK = (MOD_SHIFT|MOD_CONTROL|MOD_ALT|MOD_SUPER), +}; + typedef struct { /* TODO: is this even supported or does GLFW only call you once per poll? */ - i32 transitions; - b32 ended_down; + i16 transitions; + i16 ended_down; } ButtonState; typedef struct TerminalInput { @@ -82,9 +221,6 @@ typedef struct TerminalInput { v2 mouse_scroll; ButtonState keys[INPUT_KEY_COUNT]; - /* TODO: move this out of here once callbacks are removed from terminal */ - Stream char_stream; - /* TODO: do we want the 32bit codepoints instead? */ s8 character_input; @@ -103,12 +239,6 @@ typedef struct TerminalMemory { PlatformAPI platform_api; } TerminalMemory; -/* TODO: delete this !!!! */ -typedef struct { - TerminalMemory *memory; - TerminalInput *input; -} tmp_user_ctx; - /************************************************************/ /* NOTE: functions provided by the terminal to the platform */ /************************************************************/ @@ -121,4 +251,8 @@ typedef VTGL_FRAME_STEP_FN(vtgl_frame_step_fn); #define VTGL_ACTIVE_SELECTION_FN(name) Range name(TerminalMemory *memory, Stream *out) typedef VTGL_ACTIVE_SELECTION_FN(vtgl_active_selection_fn); +#define VTGL_HANDLE_KEYS_FN(name) void name(TerminalMemory *memory, TerminalInput *input, \ + i32 key, i32 action, u32 modifiers) +typedef VTGL_HANDLE_KEYS_FN(vtgl_handle_keys_fn); + #endif /*_VTGL_H_ */