selection: re-factor: break out code shared between clipboard/primary send

The send functions are called by the compositor when another
application wants to paste data *from* foot.
This commit is contained in:
Daniel Eklöf 2020-10-13 18:38:49 +02:00
parent 8b06a55cb0
commit 033ff180af
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

View file

@ -937,18 +937,9 @@ done:
} }
static void static void
send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, send_clipboard_or_primary(struct seat *seat, int fd, const char *selection,
int32_t fd) const char *source_name)
{ {
struct seat *seat = data;
const struct wl_clipboard *clipboard = &seat->clipboard;
assert(clipboard != NULL);
assert(clipboard->text != NULL);
const char *selection = clipboard->text;
const size_t len = strlen(selection);
/* Make it NONBLOCK:ing right away - we don't want to block if the /* Make it NONBLOCK:ing right away - we don't want to block if the
* initial attempt to send the data synchronously fails */ * initial attempt to send the data synchronously fails */
int flags; int flags;
@ -959,14 +950,16 @@ send(void *data, struct wl_data_source *wl_data_source, const char *mime_type,
return; return;
} }
size_t len = strlen(selection);
size_t async_idx = 0; size_t async_idx = 0;
switch (async_write(fd, selection, len, &async_idx)) { switch (async_write(fd, selection, len, &async_idx)) {
case ASYNC_WRITE_REMAIN: { case ASYNC_WRITE_REMAIN: {
struct clipboard_send *ctx = xmalloc(sizeof(*ctx)); struct clipboard_send *ctx = xmalloc(sizeof(*ctx));
*ctx = (struct clipboard_send) { *ctx = (struct clipboard_send) {
.data = xstrdup(selection), .data = xstrdup(&selection[async_idx]),
.len = len, .len = len - async_idx,
.idx = async_idx, .idx = 0,
}; };
if (fdm_add(seat->wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx)) if (fdm_add(seat->wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx))
@ -981,15 +974,25 @@ send(void *data, struct wl_data_source *wl_data_source, const char *mime_type,
break; break;
case ASYNC_WRITE_ERR: case ASYNC_WRITE_ERR:
LOG_ERRNO( LOG_ERRNO("failed write %zu bytes of %s selection data to FD=%d",
"failed to write %zu bytes of clipboard selection data to FD=%d", len, source_name, fd);
len, fd);
break; break;
} }
close(fd); close(fd);
} }
static void
send(void *data, struct wl_data_source *wl_data_source, const char *mime_type,
int32_t fd)
{
struct seat *seat = data;
const struct wl_clipboard *clipboard = &seat->clipboard;
assert(clipboard->text != NULL);
send_clipboard_or_primary(seat, fd, clipboard->text, "clipboard");
}
static void static void
cancelled(void *data, struct wl_data_source *wl_data_source) cancelled(void *data, struct wl_data_source *wl_data_source)
{ {
@ -1037,49 +1040,8 @@ primary_send(void *data,
struct seat *seat = data; struct seat *seat = data;
const struct wl_primary *primary = &seat->primary; const struct wl_primary *primary = &seat->primary;
assert(primary != NULL);
assert(primary->text != NULL); assert(primary->text != NULL);
send_clipboard_or_primary(seat, fd, primary->text, "primary");
const char *selection = primary->text;
const size_t len = strlen(selection);
int flags;
if ((flags = fcntl(fd, F_GETFL)) < 0 ||
fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
{
LOG_ERRNO("failed to set O_NONBLOCK");
return;
}
size_t async_idx = 0;
switch (async_write(fd, selection, len, &async_idx)) {
case ASYNC_WRITE_REMAIN: {
struct clipboard_send *ctx = xmalloc(sizeof(*ctx));
*ctx = (struct clipboard_send) {
.data = xstrdup(selection),
.len = len,
.idx = async_idx,
};
if (fdm_add(seat->wayl->fdm, fd, EPOLLOUT, &fdm_send, ctx))
return;
free(ctx->data);
free(ctx);
break;
}
case ASYNC_WRITE_DONE:
break;
case ASYNC_WRITE_ERR:
LOG_ERRNO(
"failed to write %zu bytes of primary selection data to FD=%d",
len, fd);
break;
}
close(fd);
} }
static void static void