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:
M | util.c | | | 37 | +++++++++++++++++++++++++++++++++++++ |
M | util.h | | | 1 | + |
M | waycopy.c | | | 48 | ++++++++++++++++++++++++++++++++++++++++++------ |
M | waypaste.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, ®istry_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, ®istry_listener, NULL);
wl_display_roundtrip(display);
+ wl_display_roundtrip(display);
if (seat == NULL)
die("failed to bind to seat interface");