wayclip

Wayland clipboard utility
git clone git://git.nihaljere.xyz/wayclip
Log | Files | Refs | README | LICENSE

commit 53e0dedb1add9a603e65958999cecce20314a2ff
parent 216c87a77c1af2c1526d2084fde321fd331b7d83
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Mon, 21 Feb 2022 19:39:52 -0600

copy arbitrary data

Diffstat:
Mutil.c | 6++++++
Mutil.h | 1+
Mwaycopy.c | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
3 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/util.c b/util.c @@ -12,3 +12,9 @@ die(const char *const error) exit(1); } +void +warn(const char *const error) +{ + fprintf(stderr, "%s: warning: %s\n", argv0, error); +} + diff --git a/util.h b/util.h @@ -1 +1,2 @@ void die(const char *const error); +void warn(const char *const error); diff --git a/waycopy.c b/waycopy.c @@ -1,7 +1,9 @@ #include <assert.h> +#include <limits.h> #include <string.h> #include <stdbool.h> #include <stdio.h> +#include <stdlib.h> #include <wayland-client.h> #include <unistd.h> @@ -15,11 +17,35 @@ char mimetype[MIMETYPE_MAX_SIZE]; struct zwlr_data_control_manager_v1 *data_control_manager; struct wl_seat *seat; +FILE *temp; -int destfd; bool running = 1; void +copyfile(FILE *out, FILE *in) +{ + char buf[BUFSIZ]; + + size_t rcount, wcount; + do { + rcount = fread(buf, 1, BUFSIZ, in); + wcount = fwrite(buf, 1, rcount, out); + if (rcount < BUFSIZ) { + if (ferror(in)) { + // TODO: print actual error + warn("fread failed"); + } else if (feof(in)) { + break; + } + } + + if (wcount < rcount) { + warn("fwrite failed"); + } + } while (1); +} + +void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { if (strcmp(interface, "wl_seat") == 0) { @@ -42,20 +68,14 @@ static const struct wl_registry_listener registry_listener = { void data_source_send(void *data, struct zwlr_data_control_source_v1 *source, const char *mime_type, int32_t fd) { - char *buf = "this is some text", *ptr = buf; - int len = strlen(buf); - while (len) { - int ret = write(fd, ptr, len); - if (ret == -1) { - fprintf(stderr, "write failed\n"); - return; - } - - len -= ret; - ptr += ret; + fseek(temp, SEEK_SET, 0); + FILE *out = fdopen(fd, "w"); + if (out == NULL) { + warn("failed to open fd as FILE"); } - close(fd); + copyfile(out, temp); + fclose(out); } void @@ -69,11 +89,37 @@ static const struct zwlr_data_control_source_v1_listener data_source_listener = .cancelled = data_source_cancelled, }; +const char *const tempname = "/waycopy-buffer-XXXXXX"; + int main(int argc, const char *argv[]) { argv0 = argv[0]; + char path[PATH_MAX] = {0}; + char *ptr = getenv("TMPDIR"); + if (ptr == NULL) + strcpy(path, "/tmp"); + else { + if (strlen(ptr) > PATH_MAX - strlen(tempname)) + die("TMPDIR has too long of a path"); + + strcpy(path, ptr); + } + + strncat(path, tempname, PATH_MAX - 1); + int tempfd = mkstemp(path); + if (tempfd == -1) + die("failed to create temporary file for copy buffer"); + + temp = fdopen(tempfd, "r+"); + if (temp == NULL) { + die("failed to open temporary file as FILE"); + } + + copyfile(temp, stdin); + fclose(stdin); + struct wl_display *const display = wl_display_connect(NULL); if (display == NULL) die("failed to connect to display"); @@ -106,5 +152,6 @@ main(int argc, const char *argv[]) while (wl_display_dispatch(display) != -1 && running); - return 1; + unlink(path); + return running; }