diff --git a/include/sway/scene_descriptor.h b/include/sway/scene_descriptor.h new file mode 100644 index 00000000..13ae81a3 --- /dev/null +++ b/include/sway/scene_descriptor.h @@ -0,0 +1,25 @@ +/** + * Across a wayland compositor, there are multiple shells: It can be + * a toplevel, or a layer_shell, or even something more meta like a drag + * icon or highlight indicators when dragging windows around. + * + * This object lets us store values that represent these modes of operation + * and keep track of what object is being represented. + */ +#ifndef _SWAY_SCENE_DESCRIPTOR_H +#define _SWAY_SCENE_DESCRIPTOR_H +#include + +enum sway_scene_descriptor_type { +}; + +bool scene_descriptor_assign(struct wlr_scene_node *node, + enum sway_scene_descriptor_type type, void *data); + +void *scene_descriptor_try_get(struct wlr_scene_node *node, + enum sway_scene_descriptor_type type); + +void scene_descriptor_destroy(struct wlr_scene_node *node, + enum sway_scene_descriptor_type type); + +#endif diff --git a/sway/meson.build b/sway/meson.build index 3abd778d..26251e58 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -8,6 +8,7 @@ sway_sources = files( 'lock.c', 'main.c', 'realtime.c', + 'scene_descriptor.c', 'server.c', 'swaynag.c', 'xdg_activation_v1.c', diff --git a/sway/scene_descriptor.c b/sway/scene_descriptor.c new file mode 100644 index 00000000..a30d4664 --- /dev/null +++ b/sway/scene_descriptor.c @@ -0,0 +1,66 @@ +#include +#include +#include "log.h" +#include "sway/scene_descriptor.h" + +struct scene_descriptor { + void *data; + struct wlr_addon addon; +}; + +static const struct wlr_addon_interface addon_interface; + +static struct scene_descriptor *scene_node_get_descriptor( + struct wlr_scene_node *node, enum sway_scene_descriptor_type type) { + struct wlr_addon *addon = wlr_addon_find(&node->addons, (void *)type, &addon_interface); + if (!addon) { + return NULL; + } + + struct scene_descriptor *desc = wl_container_of(addon, desc, addon); + return desc; +} + +static void descriptor_destroy(struct scene_descriptor *desc) { + wlr_addon_finish(&desc->addon); + free(desc); +} + +void *scene_descriptor_try_get(struct wlr_scene_node *node, + enum sway_scene_descriptor_type type) { + struct scene_descriptor *desc = scene_node_get_descriptor(node, type); + if (!desc) { + return NULL; + } + + return desc->data; +} + +void scene_descriptor_destroy(struct wlr_scene_node *node, + enum sway_scene_descriptor_type type) { + struct scene_descriptor *desc = scene_node_get_descriptor(node, type); + descriptor_destroy(desc); +} + +static void addon_handle_destroy(struct wlr_addon *addon) { + struct scene_descriptor *desc = wl_container_of(addon, desc, addon); + descriptor_destroy(desc); +} + +static const struct wlr_addon_interface addon_interface = { + .name = "sway_scene_descriptor", + .destroy = addon_handle_destroy, +}; + +bool scene_descriptor_assign(struct wlr_scene_node *node, + enum sway_scene_descriptor_type type, void *data) { + struct scene_descriptor *desc = calloc(1, sizeof(*desc)); + if (!desc) { + sway_log(SWAY_ERROR, "Could not allocate a scene descriptor"); + return false; + } + + wlr_addon_init(&desc->addon, &node->addons, (void *)type, &addon_interface); + desc->data = data; + return true; +}