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:
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,