diff options
author | Robby Zambito <contact@robbyzambito.me> | 2021-08-23 21:45:03 -0400 |
---|---|---|
committer | Robby Zambito <contact@robbyzambito.me> | 2021-08-23 21:45:03 -0400 |
commit | 19c8717ec4b4d29734bd6a0201d6d1d7c2b153b3 (patch) | |
tree | f5f92ec064fec5c563e0fe2f04793cb10a7a161c |
Initial commit.
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | main.c | 61 |
3 files changed, 81 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6e82373 --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ + +build: + gcc -lwayland-client main.c -o wayland-run-on-new-display diff --git a/README.md b/README.md new file mode 100644 index 0000000..4fb26f1 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# wayland-run-on-new-display + +Run a command every time a new display is attached. + +## Building + +You must have wayland client libraries installed on your system. + +Build by running `make` + +Place the produced binary somewhere on your `$PATH`. + +## Running + +`wayland-run-on-new-display some-command args-for-command` + +The program will block until a new display is attached, and then run the specified command. @@ -0,0 +1,61 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wayland-client.h> + +#define STREQ(a, b) (strcmp(a, b) == 0) + +static char **command_argv; + +static void global_registry_handler(void *data, struct wl_registry *registry, + uint32_t id, const char *interface, + uint32_t version) { + /* A new display has been attached */ + if (STREQ(interface, "wl_output")) { + errno = 0; + switch (fork()) { + case -1: /* Handle error */ + perror("Unable to fork"); + break; + case 0: /* In child */ + execvp(command_argv[0], command_argv); + /* No need to break, the exec leaves the current program. */ + default:; + } + } +} + +static void global_registry_remover(void *data, struct wl_registry *registry, + uint32_t id) { + /* Do nothing. */ +} + +int main(int argc, char **argv) { + command_argv = argv + 1; + + struct wl_display *display = wl_display_connect(NULL); + + if (display == NULL) { + fputs("Failed to connect to the Wayland socket", stderr); + exit(EXIT_FAILURE); + } + + const struct wl_registry_listener registry_listener = { + global_registry_handler, + global_registry_remover, + }; + + struct wl_registry *registry = wl_display_get_registry(display); + + wl_registry_add_listener(registry, ®istry_listener, NULL); + + for (;;) { + wl_display_dispatch(display); + wl_display_roundtrip(display); + } + + wl_display_disconnect(display); + return EXIT_SUCCESS; +} |