aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_surface.h15
-rw-r--r--types/wlr_compositor.c24
-rw-r--r--types/wlr_surface.c76
3 files changed, 112 insertions, 3 deletions
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index 87d421e3..eb88a663 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -19,6 +19,12 @@ struct wlr_frame_callback {
#define WLR_SURFACE_INVALID_TRANSFORM 32
#define WLR_SURFACE_INVALID_SCALE 64
+struct wlr_subsurface {
+ struct wl_resource *resource;
+ struct wlr_surface *surface;
+ struct wlr_surface *parent;
+};
+
struct wlr_surface_state {
uint32_t invalid;
struct wl_resource *buffer;
@@ -52,6 +58,9 @@ struct wlr_surface {
struct wl_listener compositor_listener; // destroy listener used by compositor
void *compositor_data;
+ // subsurface properties
+ struct wlr_subsurface *subsurface;
+
void *data;
};
@@ -80,4 +89,10 @@ void wlr_surface_get_matrix(struct wlr_surface *surface,
int wlr_surface_set_role(struct wlr_surface *surface, const char *role,
struct wl_resource *error_resource, uint32_t error_code);
+/**
+ * Create the subsurface implementation for this surface.
+ */
+void wlr_surface_make_subsurface(struct wlr_surface *surface,
+ struct wlr_surface *parent, uint32_t id);
+
#endif
diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c
index 75bf6146..a142ddd4 100644
--- a/types/wlr_compositor.c
+++ b/types/wlr_compositor.c
@@ -78,9 +78,27 @@ static void subcompositor_destroy(struct wl_client *client,
}
static void subcompositor_get_subsurface(struct wl_client *client,
- struct wl_resource *resource, uint32_t id, struct wl_resource *surface,
- struct wl_resource *parent) {
- wlr_log(L_DEBUG, "TODO: subcompositor get subsurface");
+ struct wl_resource *resource, uint32_t id,
+ struct wl_resource *surface_resource,
+ struct wl_resource *parent_resource) {
+ struct wlr_surface *surface = wl_resource_get_user_data(surface_resource);
+ struct wlr_surface *parent = wl_resource_get_user_data(parent_resource);
+
+ // TODO: errors
+ // * cannot be its own parent
+ // * cannot already a subsurface
+ // * cannot be an ancestor of parent
+
+ if (wlr_surface_set_role(surface, "wl_subsurface", resource,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0) {
+ return;
+ }
+
+ wlr_surface_make_subsurface(surface, parent, id);
+ if (!surface->subsurface) {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
}
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index a9a54abe..de28f4df 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -443,3 +443,79 @@ int wlr_surface_set_role(struct wlr_surface *surface, const char *role,
return -1;
}
+
+void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) {
+ wlr_log(L_DEBUG, "TODO: wlr subsurface destroy");
+}
+
+static void subsurface_resource_destroy(struct wl_resource *resource) {
+ struct wlr_subsurface *subsurface = wl_resource_get_user_data(resource);
+
+ if (subsurface) {
+ wlr_subsurface_destroy(subsurface);
+ }
+}
+
+static void subsurface_destroy(struct wl_client *client,
+ struct wl_resource *resource) {
+ wl_resource_destroy(resource);
+}
+
+static void subsurface_set_position(struct wl_client *client,
+ struct wl_resource *resource, int32_t x, int32_t y) {
+ wlr_log(L_DEBUG, "TODO: subsurface set position");
+}
+
+static void subsurface_place_above(struct wl_client *client,
+ struct wl_resource *resource, struct wl_resource *sibling) {
+ wlr_log(L_DEBUG, "TODO: subsurface place above");
+}
+
+static void subsurface_place_below(struct wl_client *client,
+ struct wl_resource *resource, struct wl_resource *sibling) {
+ wlr_log(L_DEBUG, "TODO: subsurface place below");
+}
+
+static void subsurface_set_sync(struct wl_client *client,
+ struct wl_resource *resource) {
+ wlr_log(L_DEBUG, "TODO: subsurface set sync");
+}
+
+static void subsurface_set_desync(struct wl_client *client,
+ struct wl_resource *resource) {
+ wlr_log(L_DEBUG, "TODO: subsurface set desync");
+}
+
+static const struct wl_subsurface_interface subsurface_implementation = {
+ .destroy = subsurface_destroy,
+ .set_position = subsurface_set_position,
+ .place_above = subsurface_place_above,
+ .place_below = subsurface_place_below,
+ .set_sync = subsurface_set_sync,
+ .set_desync = subsurface_set_desync,
+};
+
+void wlr_surface_make_subsurface(struct wlr_surface *surface,
+ struct wlr_surface *parent, uint32_t id) {
+ assert(surface->subsurface == NULL);
+
+ struct wlr_subsurface *subsurface =
+ calloc(1, sizeof(struct wlr_subsurface));
+ if (!subsurface) {
+ return;
+ }
+
+ subsurface->surface = surface;
+ subsurface->parent = parent;
+
+ struct wl_client *client = wl_resource_get_client(surface->resource);
+
+ subsurface->resource =
+ wl_resource_create(client, &wl_subsurface_interface, 1, id);
+
+ wl_resource_set_implementation(subsurface->resource,
+ &subsurface_implementation, subsurface,
+ subsurface_resource_destroy);
+
+ surface->subsurface = subsurface;
+}