aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/render/interface.h6
-rw-r--r--include/wlr/render/wlr_renderer.h10
-rw-r--r--include/wlr/types/wlr_surface.h2
-rw-r--r--render/wlr_renderer.c5
-rw-r--r--types/wlr_region.c7
-rw-r--r--types/wlr_surface.c15
6 files changed, 33 insertions, 12 deletions
diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h
index 9dbe7247..e7cdce0a 100644
--- a/include/wlr/render/interface.h
+++ b/include/wlr/render/interface.h
@@ -11,12 +11,6 @@
#include <wlr/types/wlr_linux_dmabuf.h>
#include <wlr/types/wlr_output.h>
-struct wlr_renderer_impl;
-
-struct wlr_renderer {
- const struct wlr_renderer_impl *impl;
-};
-
struct wlr_renderer_impl {
void (*begin)(struct wlr_renderer *renderer, uint32_t width,
uint32_t height);
diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h
index eb365762..21f9c16c 100644
--- a/include/wlr/render/wlr_renderer.h
+++ b/include/wlr/render/wlr_renderer.h
@@ -6,9 +6,15 @@
#include <wlr/render/wlr_texture.h>
#include <wlr/types/wlr_box.h>
-struct wlr_output;
+struct wlr_renderer_impl;
-struct wlr_renderer;
+struct wlr_renderer {
+ const struct wlr_renderer_impl *impl;
+
+ struct {
+ struct wl_signal destroy;
+ } events;
+};
void wlr_renderer_begin(struct wlr_renderer *r, int width, int height);
void wlr_renderer_end(struct wlr_renderer *r);
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index f799b28a..5ff9996d 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -93,6 +93,8 @@ struct wlr_surface {
// wlr_subsurface::parent_pending_link
struct wl_list subsurface_pending_list;
+ struct wl_listener renderer_destroy;
+
void *data;
};
diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c
index 700da05b..8d1bd9ce 100644
--- a/render/wlr_renderer.c
+++ b/render/wlr_renderer.c
@@ -5,6 +5,7 @@
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/util/log.h>
+#include "util/signal.h"
void wlr_renderer_init(struct wlr_renderer *renderer,
const struct wlr_renderer_impl *impl) {
@@ -18,9 +19,13 @@ void wlr_renderer_init(struct wlr_renderer *renderer,
assert(impl->format_supported);
assert(impl->texture_from_pixels);
renderer->impl = impl;
+
+ wl_signal_init(&renderer->events.destroy);
}
void wlr_renderer_destroy(struct wlr_renderer *r) {
+ wlr_signal_emit_safe(&r->events.destroy, r);
+
if (r && r->impl && r->impl->destroy) {
r->impl->destroy(r);
} else {
diff --git a/types/wlr_region.c b/types/wlr_region.c
index f452bbdf..860864c1 100644
--- a/types/wlr_region.c
+++ b/types/wlr_region.c
@@ -32,10 +32,13 @@ static const struct wl_region_interface region_impl = {
.subtract = region_subtract,
};
-static void destroy_region(struct wl_resource *resource) {
+static void region_handle_resource_destroy(struct wl_resource *resource) {
pixman_region32_t *reg = wlr_region_from_resource(resource);
pixman_region32_fini(reg);
free(reg);
+
+ // Set by wlr_compositor
+ wl_list_remove(wl_resource_get_link(resource));
}
struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id) {
@@ -53,7 +56,7 @@ struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id) {
return NULL;
}
wl_resource_set_implementation(region_resource, &region_impl, region,
- destroy_region);
+ region_handle_resource_destroy);
return region_resource;
}
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 578c43d3..9a2421db 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -622,7 +622,7 @@ void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) {
free(subsurface);
}
-static void destroy_surface(struct wl_resource *resource) {
+static void surface_handle_resource_destroy(struct wl_resource *resource) {
struct wlr_surface *surface = wlr_surface_from_resource(resource);
wlr_signal_emit_safe(&surface->events.destroy, surface);
@@ -634,6 +634,13 @@ static void destroy_surface(struct wl_resource *resource) {
free(surface);
}
+static void surface_handle_renderer_destroy(struct wl_listener *listener,
+ void *data) {
+ struct wlr_surface *surface =
+ wl_container_of(listener, surface, renderer_destroy);
+ wl_resource_destroy(surface->resource);
+}
+
struct wlr_surface *wlr_surface_create(struct wl_resource *res,
struct wlr_renderer *renderer) {
struct wlr_surface *surface = calloc(1, sizeof(struct wlr_surface));
@@ -654,7 +661,11 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res,
wl_list_init(&surface->subsurfaces);
wl_list_init(&surface->subsurface_pending_list);
wl_resource_set_implementation(res, &surface_interface,
- surface, destroy_surface);
+ surface, surface_handle_resource_destroy);
+
+ wl_signal_add(&renderer->events.destroy, &surface->renderer_destroy);
+ surface->renderer_destroy.notify = surface_handle_renderer_destroy;
+
return surface;
}