From b15032d223115ad0f65a182804ba914bf0fcc51b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 5 Nov 2019 08:49:32 +0100 Subject: [PATCH] selection: text_from_{clipboard,primary}: add 'done' callback This callback is *always* called, including when there has been an error. This is in preparation for making text_from_{clipboard,primary} asynchronous. --- osc.c | 35 ++++++++++++++++++++++------------- selection.c | 51 +++++++++++++++++++++++++++++++++------------------ selection.h | 7 ++++--- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/osc.c b/osc.c index 6b86be03..20bc06b4 100644 --- a/osc.c +++ b/osc.c @@ -102,6 +102,22 @@ from_clipboard_cb(const char *text, size_t size, void *user) free(chunk); } +static void +from_clipboard_done(void *user) +{ + struct clip_context *ctx = user; + struct terminal *term = ctx->term; + + if (ctx->idx > 0) { + char res[4]; + base64_encode_final(ctx->buf, ctx->idx, res); + term_to_slave(term, res, 4); + } + + term_to_slave(term, "\033\\", 2); + free(ctx); +} + static void osc_from_clipboard(struct terminal *term, const char *source) { @@ -124,27 +140,20 @@ osc_from_clipboard(struct terminal *term, const char *source) term_to_slave(term, &src, 1); term_to_slave(term, ";", 1); - struct clip_context ctx = { - .term = term, - }; + struct clip_context *ctx = malloc(sizeof(*ctx)); + *ctx = (struct clip_context) {.term = term}; switch (src) { case 'c': - text_from_clipboard(term, term->wl->input_serial, &from_clipboard_cb, &ctx); + text_from_clipboard( + term, term->wl->input_serial, + &from_clipboard_cb, &from_clipboard_done, ctx); break; case 'p': - text_from_primary(term, &from_clipboard_cb, &ctx); + text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, ctx); break; } - - if (ctx.idx > 0) { - char res[4]; - base64_encode_final(ctx.buf, ctx.idx, res); - term_to_slave(term, res, 4); - } - - term_to_slave(term, "\033\\", 2); } static void diff --git a/selection.c b/selection.c index 72ade90b..bd9d76fb 100644 --- a/selection.c +++ b/selection.c @@ -566,17 +566,17 @@ selection_to_clipboard(struct terminal *term, uint32_t serial) void text_from_clipboard(struct terminal *term, uint32_t serial, void (*cb)(const char *data, size_t size, void *user), - void *user) + void (*done)(void *user), void *user) { struct wl_clipboard *clipboard = &term->wl->clipboard; if (clipboard->data_offer == NULL) - return; + goto done; /* Prepare a pipe the other client can write its selection to us */ int fds[2]; if (pipe2(fds, O_CLOEXEC) == -1) { LOG_ERRNO("failed to create pipe"); - return; + goto done; } int read_fd = fds[0]; @@ -609,10 +609,15 @@ text_from_clipboard(struct terminal *term, uint32_t serial, } } - cb(text, amount, user); + if (cb != NULL) + cb(text, amount, user); } close(read_fd); + +done: + if (done != NULL) + done(user); } static void @@ -622,6 +627,15 @@ from_clipboard_cb(const char *data, size_t size, void *user) term_to_slave(term, data, size); } +static void +from_clipboard_done(void *user) +{ + struct terminal *term = user; + + if (term->bracketed_paste) + term_to_slave(term, "\033[201~", 6); +} + void selection_from_clipboard(struct terminal *term, uint32_t serial) { @@ -632,10 +646,8 @@ selection_from_clipboard(struct terminal *term, uint32_t serial) if (term->bracketed_paste) term_to_slave(term, "\033[200~", 6); - text_from_clipboard(term, serial, &from_clipboard_cb, term); - - if (term->bracketed_paste) - term_to_slave(term, "\033[201~", 6); + text_from_clipboard( + term, serial, &from_clipboard_cb, &from_clipboard_done, term); } bool @@ -696,21 +708,22 @@ selection_to_primary(struct terminal *term, uint32_t serial) void text_from_primary( - struct terminal *term, void (*cb)(const char *data, size_t size, void *user), - void *user) + struct terminal *term, + void (*cb)(const char *data, size_t size, void *user), + void (*done)(void *user), void *user) { if (term->wl->primary_selection_device_manager == NULL) - return; + goto done; struct wl_primary *primary = &term->wl->primary; if (primary->data_offer == NULL) - return; + goto done; /* Prepare a pipe the other client can write its selection to us */ int fds[2]; if (pipe2(fds, O_CLOEXEC) == -1) { LOG_ERRNO("failed to create pipe"); - return; + goto done; } int read_fd = fds[0]; @@ -743,10 +756,15 @@ text_from_primary( } } - cb(text, amount, user); + if (cb != NULL) + cb(text, amount, user); } close(read_fd); + +done: + if (done != NULL) + done(user); } void @@ -762,10 +780,7 @@ selection_from_primary(struct terminal *term) if (term->bracketed_paste) term_to_slave(term, "\033[200~", 6); - text_from_primary(term, &from_clipboard_cb, term); - - if (term->bracketed_paste) - term_to_slave(term, "\033[201~", 6); + text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, term); } #if 0 diff --git a/selection.h b/selection.h index 7345766c..9ff40919 100644 --- a/selection.h +++ b/selection.h @@ -29,9 +29,10 @@ bool text_to_clipboard(struct terminal *term, char *text, uint32_t serial); void text_from_clipboard( struct terminal *term, uint32_t serial, void (*cb)(const char *data, size_t size, void *user), - void *user); + void (*done)(void *user), void *user); bool text_to_primary(struct terminal *term, char *text, uint32_t serial); void text_from_primary( - struct terminal *term, void (*cb)(const char *data, size_t size, void *user), - void *user); + struct terminal *term, + void (*cb)(const char *data, size_t size, void *user), + void (*dont)(void *user), void *user);