diff --git a/include/seat.h b/include/seat.h new file mode 100644 index 0000000..4faf0fc --- /dev/null +++ b/include/seat.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 - 2020 Andri Yngvason + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +#include +#include + +struct seat { + struct wl_seat* wl_seat; + struct wl_list link; + + uint32_t id; + uint32_t capabilities; + char name[256]; +}; + +struct seat* seat_new(struct wl_seat* wl_seat, uint32_t id); +void seat_destroy(struct seat* self); +void seat_list_destroy(struct wl_list* list); + +struct seat* seat_find_by_name(struct wl_list* list, const char* name); +struct seat* seat_find_by_id(struct wl_list* list, uint32_t id); +struct seat* seat_first(struct wl_list* list); diff --git a/include/strlcpy.h b/include/strlcpy.h new file mode 100644 index 0000000..b9a2249 --- /dev/null +++ b/include/strlcpy.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019 - 2020 Andri Yngvason + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +#include + +size_t strlcpy(char *dst, const char *src, size_t siz); + diff --git a/meson.build b/meson.build index 56a54fc..cf1e131 100644 --- a/meson.build +++ b/meson.build @@ -45,6 +45,8 @@ subdir('protocols') sources = [ 'src/main.c', 'src/shm.c', + 'src/seat.c', + 'src/strlcpy.c', ] dependencies = [ diff --git a/src/main.c b/src/main.c index 4810b58..b912b65 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,7 @@ #include "xdg-shell.h" #include "shm.h" +#include "seat.h" struct buffer { int width, height, stride; @@ -37,6 +38,7 @@ static struct wl_registry* wl_registry; static struct wl_compositor* wl_compositor; static struct wl_shm* wl_shm; static struct xdg_wm_base* xdg_wm_base; +static struct wl_list seats; static enum wl_shm_format wl_shm_format; static bool have_format = false; @@ -55,12 +57,27 @@ static void registry_add(void* data, struct wl_registry* registry, uint32_t id, xdg_wm_base = wl_registry_bind(registry, id, &xdg_wm_base_interface, 1); } else if (strcmp(interface, "wl_shm") == 0) { wl_shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); + } else if (strcmp(interface, "wl_seat") == 0) { + struct wl_seat* wl_seat; + wl_seat = wl_registry_bind(registry, id, &wl_seat_interface, 1); + + struct seat* seat = seat_new(wl_seat, id); + if (!seat) { + wl_seat_destroy(wl_seat); + return; + } + + wl_list_insert(&seats, &seat->link); } } void registry_remove(void* data, struct wl_registry* registry, uint32_t id) { - // Nothing to do here + struct seat* seat = seat_find_by_id(&seats, id); + if (seat) { + wl_list_remove(&seat->link); + seat_destroy(seat); + } } static const struct wl_registry_listener registry_listener = { @@ -439,6 +456,8 @@ int main(int argc, char* argv[]) if (!wl_registry) goto registry_failure; + wl_list_init(&seats); + wl_registry_add_listener(wl_registry, ®istry_listener, wl_display); wl_display_roundtrip(wl_display); @@ -454,7 +473,6 @@ int main(int argc, char* argv[]) if (!vnc) goto vnc_failure; - wl_display_dispatch(wl_display); while (do_run) { @@ -468,6 +486,7 @@ int main(int argc, char* argv[]) window_destroy(window); rfb_client_destroy(vnc); vnc_failure: + seat_list_destroy(&seats); wl_compositor_destroy(wl_compositor); wl_shm_destroy(wl_shm); xdg_wm_base_destroy(xdg_wm_base); diff --git a/src/seat.c b/src/seat.c new file mode 100644 index 0000000..d6bf333 --- /dev/null +++ b/src/seat.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019 - 2020 Andri Yngvason + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "seat.h" +#include "strlcpy.h" + +static void seat_capabilities(void* data, struct wl_seat* wl_seat, + uint32_t capabilities) +{ + struct seat* self = data; + + self->capabilities = capabilities; +} + +static void seat_name(void* data, struct wl_seat* wl_seat, const char* name) +{ + struct seat* self = data; + + strlcpy(self->name, name, sizeof(self->name)); +} + +static const struct wl_seat_listener seat_listener = { + .capabilities = seat_capabilities, + .name = seat_name, +}; + +struct seat* seat_new(struct wl_seat* wl_seat, uint32_t id) +{ + struct seat* self = calloc(1, sizeof(*self)); + if (!self) + return NULL; + + self->wl_seat = wl_seat; + self->id = id; + + wl_seat_add_listener(wl_seat, &seat_listener, self); + + return self; +} + +void seat_destroy(struct seat* self) +{ + wl_seat_destroy(self->wl_seat); + free(self); +} + +void seat_list_destroy(struct wl_list* list) +{ + struct seat* seat; + struct seat* tmp; + + wl_list_for_each_safe(seat, tmp, list, link) { + wl_list_remove(&seat->link); + seat_destroy(seat); + } +} + +struct seat* seat_find_by_name(struct wl_list* list, const char* name) +{ + struct seat* seat; + + wl_list_for_each(seat, list, link) + if (strcmp(seat->name, name) == 0) + return seat; + + return NULL; +} + +struct seat* seat_find_by_id(struct wl_list* list, uint32_t id) +{ + struct seat* seat; + + wl_list_for_each(seat, list, link) + if (seat->id == id) + return seat; + + return NULL; +} + +struct seat* seat_first(struct wl_list* list) +{ + struct seat* seat; + + wl_list_for_each(seat, list, link) + return seat; + + return NULL; +} diff --git a/src/strlcpy.c b/src/strlcpy.c new file mode 100644 index 0000000..6301674 --- /dev/null +++ b/src/strlcpy.c @@ -0,0 +1,50 @@ +/* $OpenBSD: strlcpy.c,v 1.13 2015/08/31 02:53:57 guenther Exp $ */ + +/* + * Copyright (c) 1998, 2015 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Copy string src to buffer dst of size dsize. At most dsize-1 + * chars will be copied. Always NUL terminates (unless dsize == 0). + * Returns strlen(src); if retval >= dsize, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t dsize) +{ + const char *osrc = src; + size_t nleft = dsize; + + /* Copy as many bytes as will fit. */ + if (nleft != 0) { + while (--nleft != 0) { + if ((*dst++ = *src++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src. */ + if (nleft == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + + return(src - osrc - 1); /* count does not include NUL */ +}