aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2020-03-28 20:56:27 +0100
committerDrew DeVault <sir@cmpwn.com>2020-03-29 20:57:28 +0200
commit7516a98167326350fb6e1906224bbff04fbf4c62 (patch)
treeede663f71490d3424f12c1b76edb386dd012badf
parent13db99b0f829791ed3d794b73f9cdccd99c46939 (diff)
Gracefully handle inert wl_output resources
Closes: https://github.com/swaywm/wlroots/issues/2088
-rw-r--r--include/wlr/types/wlr_output.h5
-rw-r--r--types/wlr_gamma_control_v1.c7
-rw-r--r--types/wlr_screencopy_v1.c12
-rw-r--r--types/wlr_xdg_output_v1.c22
4 files changed, 35 insertions, 11 deletions
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 9d6e85b3..3b7f7ee3 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -369,6 +369,11 @@ bool wlr_output_set_gamma(struct wlr_output *output, size_t size,
const uint16_t *r, const uint16_t *g, const uint16_t *b);
bool wlr_output_export_dmabuf(struct wlr_output *output,
struct wlr_dmabuf_attributes *attribs);
+/**
+ * Returns the wlr_output matching the provided wl_output resource. If the
+ * resource isn't a wl_output, it aborts. If the resource is inert (because the
+ * wlr_output has been destroyed), NULL is returned.
+ */
struct wlr_output *wlr_output_from_resource(struct wl_resource *resource);
/**
* Locks the output to only use rendering instead of direct scan-out. This is
diff --git a/types/wlr_gamma_control_v1.c b/types/wlr_gamma_control_v1.c
index 7eb5df5b..a75e45db 100644
--- a/types/wlr_gamma_control_v1.c
+++ b/types/wlr_gamma_control_v1.c
@@ -161,6 +161,13 @@ static void gamma_control_manager_get_gamma_control(struct wl_client *client,
wl_resource_set_implementation(gamma_control->resource, &gamma_control_impl,
gamma_control, gamma_control_handle_resource_destroy);
+ if (output == NULL) {
+ wl_resource_set_user_data(gamma_control->resource, NULL);
+ zwlr_gamma_control_v1_send_failed(gamma_control->resource);
+ free(gamma_control);
+ return;
+ }
+
wl_signal_add(&output->events.destroy,
&gamma_control->output_destroy_listener);
gamma_control->output_destroy_listener.notify =
diff --git a/types/wlr_screencopy_v1.c b/types/wlr_screencopy_v1.c
index f0f8f8c9..85012d55 100644
--- a/types/wlr_screencopy_v1.c
+++ b/types/wlr_screencopy_v1.c
@@ -379,13 +379,19 @@ static void capture_output(struct wl_client *wl_client,
wl_client_post_no_memory(wl_client);
return;
}
+ wl_resource_set_implementation(frame->resource, &frame_impl, frame,
+ frame_handle_resource_destroy);
+
+ if (output == NULL) {
+ wl_resource_set_user_data(frame->resource, NULL);
+ zwlr_screencopy_frame_v1_send_failed(frame->resource);
+ free(frame);
+ return;
+ }
frame->client = client;
client->ref++;
- wl_resource_set_implementation(frame->resource, &frame_impl, frame,
- frame_handle_resource_destroy);
-
wl_list_insert(&client->manager->frames, &frame->link);
wl_list_init(&frame->output_precommit.link);
diff --git a/types/wlr_xdg_output_v1.c b/types/wlr_xdg_output_v1.c
index 79778e6a..e81080ba 100644
--- a/types/wlr_xdg_output_v1.c
+++ b/types/wlr_xdg_output_v1.c
@@ -96,6 +96,20 @@ static void output_manager_handle_get_xdg_output(struct wl_client *client,
struct wlr_output_layout *layout = manager->layout;
struct wlr_output *output = wlr_output_from_resource(output_resource);
+ struct wl_resource *xdg_output_resource = wl_resource_create(client,
+ &zxdg_output_v1_interface, wl_resource_get_version(resource), id);
+ if (!xdg_output_resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+ wl_resource_set_implementation(xdg_output_resource, &output_implementation,
+ NULL, output_handle_resource_destroy);
+
+ if (output == NULL) {
+ wl_list_init(wl_resource_get_link(xdg_output_resource));
+ return;
+ }
+
struct wlr_output_layout_output *layout_output =
wlr_output_layout_get(layout, output);
assert(layout_output);
@@ -109,14 +123,6 @@ static void output_manager_handle_get_xdg_output(struct wl_client *client,
}
assert(xdg_output);
- struct wl_resource *xdg_output_resource = wl_resource_create(client,
- &zxdg_output_v1_interface, wl_resource_get_version(resource), id);
- if (!xdg_output_resource) {
- wl_client_post_no_memory(client);
- return;
- }
- wl_resource_set_implementation(xdg_output_resource, &output_implementation,
- NULL, output_handle_resource_destroy);
wl_list_insert(&xdg_output->resources,
wl_resource_get_link(xdg_output_resource));