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.
This commit is contained in:
Daniel Eklöf 2019-11-05 08:49:32 +01:00
parent 9cd22dc398
commit b15032d223
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 59 additions and 34 deletions

35
osc.c
View file

@ -102,6 +102,22 @@ from_clipboard_cb(const char *text, size_t size, void *user)
free(chunk); 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 static void
osc_from_clipboard(struct terminal *term, const char *source) 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, &src, 1);
term_to_slave(term, ";", 1); term_to_slave(term, ";", 1);
struct clip_context ctx = { struct clip_context *ctx = malloc(sizeof(*ctx));
.term = term, *ctx = (struct clip_context) {.term = term};
};
switch (src) { switch (src) {
case 'c': 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; break;
case 'p': case 'p':
text_from_primary(term, &from_clipboard_cb, &ctx); text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, ctx);
break; 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 static void

View file

@ -566,17 +566,17 @@ selection_to_clipboard(struct terminal *term, uint32_t serial)
void void
text_from_clipboard(struct terminal *term, uint32_t serial, text_from_clipboard(struct terminal *term, uint32_t serial,
void (*cb)(const char *data, size_t size, void *user), 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; struct wl_clipboard *clipboard = &term->wl->clipboard;
if (clipboard->data_offer == NULL) if (clipboard->data_offer == NULL)
return; goto done;
/* Prepare a pipe the other client can write its selection to us */ /* Prepare a pipe the other client can write its selection to us */
int fds[2]; int fds[2];
if (pipe2(fds, O_CLOEXEC) == -1) { if (pipe2(fds, O_CLOEXEC) == -1) {
LOG_ERRNO("failed to create pipe"); LOG_ERRNO("failed to create pipe");
return; goto done;
} }
int read_fd = fds[0]; 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); close(read_fd);
done:
if (done != NULL)
done(user);
} }
static void static void
@ -622,6 +627,15 @@ from_clipboard_cb(const char *data, size_t size, void *user)
term_to_slave(term, data, size); 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 void
selection_from_clipboard(struct terminal *term, uint32_t serial) 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) if (term->bracketed_paste)
term_to_slave(term, "\033[200~", 6); term_to_slave(term, "\033[200~", 6);
text_from_clipboard(term, serial, &from_clipboard_cb, term); text_from_clipboard(
term, serial, &from_clipboard_cb, &from_clipboard_done, term);
if (term->bracketed_paste)
term_to_slave(term, "\033[201~", 6);
} }
bool bool
@ -696,21 +708,22 @@ selection_to_primary(struct terminal *term, uint32_t serial)
void void
text_from_primary( text_from_primary(
struct terminal *term, void (*cb)(const char *data, size_t size, void *user), struct terminal *term,
void *user) void (*cb)(const char *data, size_t size, void *user),
void (*done)(void *user), void *user)
{ {
if (term->wl->primary_selection_device_manager == NULL) if (term->wl->primary_selection_device_manager == NULL)
return; goto done;
struct wl_primary *primary = &term->wl->primary; struct wl_primary *primary = &term->wl->primary;
if (primary->data_offer == NULL) if (primary->data_offer == NULL)
return; goto done;
/* Prepare a pipe the other client can write its selection to us */ /* Prepare a pipe the other client can write its selection to us */
int fds[2]; int fds[2];
if (pipe2(fds, O_CLOEXEC) == -1) { if (pipe2(fds, O_CLOEXEC) == -1) {
LOG_ERRNO("failed to create pipe"); LOG_ERRNO("failed to create pipe");
return; goto done;
} }
int read_fd = fds[0]; 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); close(read_fd);
done:
if (done != NULL)
done(user);
} }
void void
@ -762,10 +780,7 @@ selection_from_primary(struct terminal *term)
if (term->bracketed_paste) if (term->bracketed_paste)
term_to_slave(term, "\033[200~", 6); term_to_slave(term, "\033[200~", 6);
text_from_primary(term, &from_clipboard_cb, term); text_from_primary(term, &from_clipboard_cb, &from_clipboard_done, term);
if (term->bracketed_paste)
term_to_slave(term, "\033[201~", 6);
} }
#if 0 #if 0

View file

@ -29,9 +29,10 @@ bool text_to_clipboard(struct terminal *term, char *text, uint32_t serial);
void text_from_clipboard( void text_from_clipboard(
struct terminal *term, uint32_t serial, struct terminal *term, uint32_t serial,
void (*cb)(const char *data, size_t size, void *user), 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); bool text_to_primary(struct terminal *term, char *text, uint32_t serial);
void text_from_primary( void text_from_primary(
struct terminal *term, void (*cb)(const char *data, size_t size, void *user), struct terminal *term,
void *user); void (*cb)(const char *data, size_t size, void *user),
void (*dont)(void *user), void *user);