vtgl

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

Commit: 0aadfd7588980817e18cd43d564ad6e2b43074d4
Parent: 3800192c466fd6a4dc515a09c904d8ac001b210b
Author: Randy Palamar
Date:   Thu,  7 Nov 2024 17:55:51 -0700

push rest of clipboard handling into the platform code

Diffstat:
Mconfig.def.h | 10+++++-----
Mplatform_linux_x11.c | 36++++++++++++++++++++++++++++--------
Mvtgl.c | 35++++++++++++++---------------------
Mvtgl.h | 16++++++++++++----
4 files changed, 59 insertions(+), 38 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -57,12 +57,12 @@ struct { u8 bgidx; } g_colours = {base16_colours, 7, 0}; -#define KEYBIND_FN(name) b32 name(Term *t, Arg a) +#define KEYBIND_FN(name) b32 name(Term *t, PlatformAPI *platform, Arg a) typedef KEYBIND_FN(KeyBind_Fn); /* NOTE: Bindable Functions */ -KEYBIND_FN(copy); /* arg: none */ -KEYBIND_FN(paste); /* arg: none */ +KEYBIND_FN(copy); /* arg: .i = CLIPBOARD_0 or CLIPBOARD_1 (on supported platforms) */ +KEYBIND_FN(paste); /* arg: .i = CLIPBOARD_0 or CLIPBOARD_1 (on supported platforms) */ KEYBIND_FN(scroll); /* arg: .i = line count increment */ KEYBIND_FN(zoom); /* arg: .i = font size increment */ @@ -76,8 +76,8 @@ struct hotkey { KeyBind_Fn *fn; Arg arg; } g_hotkeys[] = { - {ENCODE_KEY(GLFW_PRESS, MODKEY, GLFW_KEY_C), copy, {0}}, - {ENCODE_KEY(GLFW_PRESS, MODKEY, GLFW_KEY_V), paste, {0}}, + {ENCODE_KEY(GLFW_PRESS, MODKEY, GLFW_KEY_C), copy, {.i = CLIPBOARD_0}}, + {ENCODE_KEY(GLFW_PRESS, MODKEY, GLFW_KEY_V), paste, {.i = CLIPBOARD_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}}, diff --git a/platform_linux_x11.c b/platform_linux_x11.c @@ -310,22 +310,41 @@ update_input(GLFWwindow *win, TerminalInput *input) input->mouse_buttons[i].transitions = 0; } -static PLATFORM_GET_SELECTION_FN(x11_get_selection) +static PLATFORM_GET_CLIPBOARD_FN(x11_get_clipboard) { /* NOTE: this does a bunch of extra copying and other garbage. both GLFW and X11 are * at fault. The API is designed to do what the terminal wants and not be constrained * by GLFW and X11 garbage */ b32 result = 0; - if (buffer) { - char *selection = (char *)glfwGetX11SelectionString(); - if (selection) { - stream_push_s8(buffer, c_str_to_s8(selection)); - result = !buffer->errors; - } + ASSERT(buffer); + + char *text = 0; + switch (clipboard) { + case CLIPBOARD_0: text = (c8 *)glfwGetClipboardString(0); break; + case CLIPBOARD_1: text = (c8 *)glfwGetX11SelectionString(); break; + } + if (text) { + /* TODO: we may need to replace '\n' with '\r\n' */ + stream_push_s8(buffer, c_str_to_s8(text)); + result = !buffer->errors; } + return result; } +static PLATFORM_SET_CLIPBOARD_FN(x11_set_clipboard) +{ + ASSERT(buffer); + stream_push_byte(buffer, 0); + + if (!buffer->errors) { + switch (clipboard) { + case CLIPBOARD_0: glfwSetClipboardString(0, (c8 *)buffer->buf); break; + case CLIPBOARD_1: glfwSetX11SelectionString((c8 *)buffer->buf); break; + } + } +} + static void usage(char *argv0, Stream *err) { @@ -356,7 +375,8 @@ main(i32 argc, char *argv[], char *envp[]) term_memory.platform_api.read = posix_read; term_memory.platform_api.write = posix_write; term_memory.platform_api.allocate_ring_buffer = posix_allocate_ring_buffer; - term_memory.platform_api.get_selection = x11_get_selection; + term_memory.platform_api.get_clipboard = x11_get_clipboard; + term_memory.platform_api.set_clipboard = x11_set_clipboard; Arena platform_arena = os_new_arena(2 * MEGABYTE); Stream error_stream = stream_alloc(&platform_arena, MEGABYTE / 4); diff --git a/vtgl.c b/vtgl.c @@ -576,26 +576,22 @@ KEYBIND_FN(copy) { Stream buf = arena_stream(t->arena_for_frame); stream_push_selection(&buf, t->views + t->view_idx, t->selection.range, t->size.w); - stream_push_byte(&buf, 0); - - if (!buf.errors) - glfwSetClipboardString(0, (c8 *)buf.buf); - + platform->set_clipboard(&buf, a.i); return 1; } KEYBIND_FN(paste) { - s8 text = {.data = (u8 *)glfwGetClipboardString(0)}; + Stream buf = arena_stream(t->arena_for_frame); b32 bracketed = t->gl.mode & WIN_MODE_BRACKPASTE; - /* TODO: we may need to replace '\n' with '\r' */ - if (text.data) { - for (u8 *t = text.data; *t; t++) - text.len++; - if (bracketed) os_child_put_s8(t->child, s8("\033[200~")); - os_child_put_s8(t->child, text); - if (bracketed) os_child_put_s8(t->child, s8("\033[201~")); - } + + if (bracketed) stream_push_s8(&buf, s8("\033[200~")); + b32 success = platform->get_clipboard(&buf, a.i); + if (bracketed) stream_push_s8(&buf, s8("\033[201~")); + + if (success) + platform->write(t->child, stream_to_s8(&buf), 0); + return 1; } @@ -654,7 +650,7 @@ 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) { - b32 handled = hk->fn(t, hk->arg); + b32 handled = hk->fn(t, &ctx->memory->platform_api, hk->arg); if (handled) return; } @@ -759,15 +755,12 @@ handle_keybindings(Term *t, TerminalInput *input, PlatformAPI *platform) if (glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT)) a.i *= 5; - scroll(t, a); + scroll(t, platform, a); } } - if (pressed_this_frame(input->mouse_buttons + MOUSE_MIDDLE)) { - Stream buffer = arena_stream(t->arena_for_frame); - if (platform->get_selection(&buffer)) - platform->write(t->child, stream_to_s8(&buffer), 0); - } + if (pressed_this_frame(input->mouse_buttons + MOUSE_MIDDLE)) + paste(t, platform, (Arg){.i = CLIPBOARD_1}); } static void diff --git a/vtgl.h b/vtgl.h @@ -11,18 +11,26 @@ typedef PLATFORM_WRITE_FN(platform_write_fn); #define PLATFORM_READ_FN(name) size name(iptr file, s8 buffer, size offset) typedef PLATFORM_READ_FN(platform_read_fn); -#define PLATFORM_GET_SELECTION_FN(name) b32 name(Stream *buffer) -typedef PLATFORM_GET_SELECTION_FN(platform_get_selection_fn); -PLATFORM_GET_SELECTION_FN(get_selection_stub) {return 0;}; +#define PLATFORM_GET_CLIPBOARD_FN(name) b32 name(Stream *buffer, u32 clipboard) +typedef PLATFORM_GET_CLIPBOARD_FN(platform_get_clipboard_fn); +#define PLATFORM_SET_CLIPBOARD_FN(name) void name(Stream *buffer, u32 clipboard) +typedef PLATFORM_SET_CLIPBOARD_FN(platform_set_clipboard_fn); typedef struct { platform_allocate_ring_buffer_fn *allocate_ring_buffer; platform_read_fn *read; platform_write_fn *write; - platform_get_selection_fn *get_selection; + platform_get_clipboard_fn *get_clipboard; + platform_set_clipboard_fn *set_clipboard; } PlatformAPI; +/* NOTE: CLIPBOARD_1 need not be supported on all platforms */ +enum { + CLIPBOARD_0, + CLIPBOARD_1, +}; + enum mouse_buttons { MOUSE_LEFT, MOUSE_RIGHT,