wayclip

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

commit 7f5c6936f3f46b7914a6e1c2c15066037efcb58b
parent 293557b6d4bd771c7d3ae19555db0479af049c2e
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Tue, 22 Feb 2022 18:45:25 -0600

add seat and mimetype parameters

Diffstat:
Mutil.c | 37+++++++++++++++++++++++++++++++++++++
Mutil.h | 1+
Mwaycopy.c | 48++++++++++++++++++++++++++++++++++++++++++------
Mwaypaste.c | 48++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 124 insertions(+), 10 deletions(-)

diff --git a/util.c b/util.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> #include <unistd.h> #include "util.h" @@ -47,3 +48,39 @@ copyfd(int out, int in) break; } while (1); } + +struct { + const char *type; + const char *seat; +} options; + +void +parseopts(int argc, char *const argv[]) +{ + while (1) { + int next = getopt(argc, argv, "s:t:"); + if (next == -1) { + if (argv[optind] && *argv[optind] != '-') { + fprintf(stderr, "usage: %s [-s seat] [-t mimetype]\n", argv0); + exit(1); + } + break; + } + + if (next == ':' || next == '?') { + exit(1); + } + + switch (next) { + case 's': + options.seat = optarg; + break; + case 't': + if (strlen(optarg) > 255) { + die("mimetype can be at most 255 characters"); + } + options.type = optarg; + break; + } + } +} diff --git a/util.h b/util.h @@ -1,3 +1,4 @@ void die(const char *const error); void warn(const char *const error); void copyfd(int out, int in); +void parseopts(int argc, char *const argv[]); diff --git a/waycopy.c b/waycopy.c @@ -13,20 +13,51 @@ extern const char *argv0; +extern struct { + const char *type; + const char *seat; +} options; + #define MIMETYPE_MAX_SIZE 256 char mimetype[MIMETYPE_MAX_SIZE]; struct zwlr_data_control_manager_v1 *data_control_manager; struct wl_seat *seat; +struct wl_registry *registry; int temp; -bool running = 1; +bool running = true, seat_found = false; + +void +seat_capabilities(void *data, struct wl_seat *seat, uint32_t cap) +{ +} + +void +seat_name(void *data, struct wl_seat *_seat, const char *name) +{ + if (!seat_found && strcmp(name, options.seat) == 0) { + seat_found = true; + seat = _seat; + } + else + wl_seat_destroy(_seat); +} + +struct wl_seat_listener seat_listener = { + .capabilities = seat_capabilities, + .name = seat_name, +}; void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, "wl_seat") == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); + if (!seat_found && strcmp(interface, "wl_seat") == 0) { + seat = wl_registry_bind(registry, name, &wl_seat_interface, 2); + if (options.seat) { + wl_seat_add_listener(seat, &seat_listener, NULL); + seat = NULL; + } else seat_found = true; } else if (strcmp(interface, "zwlr_data_control_manager_v1") == 0) { data_control_manager = wl_registry_bind(registry, name, &zwlr_data_control_manager_v1_interface, 1); } @@ -65,10 +96,14 @@ static const struct zwlr_data_control_source_v1_listener data_source_listener = const char *const tempname = "/waycopy-buffer-XXXXXX"; int -main(int argc, const char *argv[]) +main(int argc, char *argv[]) { argv0 = argv[0]; + options.type = "text/plain"; + options.seat = NULL; + parseopts(argc, argv); + char path[PATH_MAX] = {0}; char *ptr = getenv("TMPDIR"); if (ptr == NULL) @@ -92,13 +127,14 @@ main(int argc, const char *argv[]) if (display == NULL) die("failed to connect to display"); - struct wl_registry *const registry = wl_display_get_registry(display); + registry = wl_display_get_registry(display); if (registry == NULL) die("failed to get registry"); wl_registry_add_listener(registry, &registry_listener, NULL); wl_display_roundtrip(display); + wl_display_roundtrip(display); if (seat == NULL) die("failed to bind to seat interface"); @@ -114,7 +150,7 @@ main(int argc, const char *argv[]) if (source == NULL) die("source is null"); - zwlr_data_control_source_v1_offer(source, "text/plain"); + zwlr_data_control_source_v1_offer(source, options.type); zwlr_data_control_source_v1_add_listener(source, &data_source_listener, NULL); zwlr_data_control_device_v1_set_selection(device, source); diff --git a/waypaste.c b/waypaste.c @@ -1,5 +1,6 @@ #include <assert.h> #include <limits.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -9,15 +10,47 @@ #include "protocol/wlr-data-control-unstable-v1-client-protocol.h" #include "util.h" +extern const char *argv0; + +extern struct { + const char *type; + const char *seat; +} options; + +bool seat_found = false; + struct zwlr_data_control_manager_v1 *data_control_manager; struct wl_seat *seat; struct wl_display *display; void +seat_capabilities(void *data, struct wl_seat *seat, uint32_t cap) +{ +} + +void +seat_name(void *data, struct wl_seat *_seat, const char *name) +{ + if (!seat_found && strcmp(name, options.seat) == 0) { + seat_found = true; + seat = _seat; + } else wl_seat_destroy(_seat); +} + +struct wl_seat_listener seat_listener = { + .capabilities = seat_capabilities, + .name = seat_name, +}; + +void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { - if (strcmp(interface, "wl_seat") == 0) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); + if (!seat_found && strcmp(interface, "wl_seat") == 0) { + seat = wl_registry_bind(registry, name, &wl_seat_interface, 2); + if (options.seat) { + wl_seat_add_listener(seat, &seat_listener, NULL); + seat = NULL; + } else seat_found = true; } else if (strcmp(interface, "zwlr_data_control_manager_v1") == 0) { data_control_manager = wl_registry_bind(registry, name, &zwlr_data_control_manager_v1_interface, 1); } @@ -37,7 +70,7 @@ void offer_offer(void *data, struct zwlr_data_control_offer_v1 *offer, const char *mime_type) { int pipes[2]; - if (strcmp(mime_type, "text/plain") == 0) { + if (strcmp(mime_type, options.type) == 0) { if (pipe(pipes) == -1) die("failed to create pipe"); @@ -74,8 +107,14 @@ static const struct zwlr_data_control_device_v1_listener device_listener = { }; int -main() +main(int argc, char *argv[]) { + argv0 = argv[0]; + + options.type = "text/plain"; + options.seat = NULL; + parseopts(argc, argv); + display = wl_display_connect(NULL); if (display == NULL) die("failed to connect to display"); @@ -87,6 +126,7 @@ main() wl_registry_add_listener(registry, &registry_listener, NULL); wl_display_roundtrip(display); + wl_display_roundtrip(display); if (seat == NULL) die("failed to bind to seat interface");