aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.builds/archlinux.yml10
-rw-r--r--README.md2
-rw-r--r--include/types/wlr_data_device.h3
-rw-r--r--include/types/wlr_tablet_v2.h4
-rw-r--r--include/wlr/render/wlr_renderer.h5
-rw-r--r--include/wlr/types/wlr_compositor.h4
-rw-r--r--include/wlr/types/wlr_data_device.h13
-rw-r--r--include/wlr/types/wlr_output.h6
-rw-r--r--render/wlr_renderer.c9
-rw-r--r--types/data_device/wlr_data_device.c33
-rw-r--r--types/data_device/wlr_data_offer.c120
-rw-r--r--types/data_device/wlr_data_source.c35
-rw-r--r--types/data_device/wlr_drag.c46
-rw-r--r--types/tablet_v2/wlr_tablet_v2.c45
-rw-r--r--types/wlr_output.c15
-rw-r--r--types/wlr_screencopy_v1.c2
-rw-r--r--types/wlr_surface.c12
-rw-r--r--types/wlr_text_input_v3.c2
18 files changed, 176 insertions, 190 deletions
diff --git a/.builds/archlinux.yml b/.builds/archlinux.yml
index 4b3e197d..2a4b5fc0 100644
--- a/.builds/archlinux.yml
+++ b/.builds/archlinux.yml
@@ -15,14 +15,12 @@ sources:
- https://github.com/swaywm/wlroots
tasks:
- setup: |
- mkdir wlroots/build-{gcc,clang}
- cd wlroots/build-gcc
- CC=gcc meson ..
- cd ../build-clang
- CC=clang meson ..
+ cd wlroots
+ CC=gcc meson build-gcc
+ CC=clang meson build-clang
- gcc: |
cd wlroots/build-gcc
ninja
- clang: |
cd wlroots/build-clang
- ninja scan-build
+ ninja
diff --git a/README.md b/README.md
index a2fca488..2ebef443 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# wlroots
Pluggable, composable, unopinionated modules for building a
-[Wayland](http://wayland.freedesktop.org/) compositor; or about 40,000 lines of
+[Wayland](http://wayland.freedesktop.org/) compositor; or about 50,000 lines of
code you were going to write anyway.
- wlroots provides backends that abstract the underlying display and input
diff --git a/include/types/wlr_data_device.h b/include/types/wlr_data_device.h
index 388e91a5..376c5f09 100644
--- a/include/types/wlr_data_device.h
+++ b/include/types/wlr_data_device.h
@@ -19,6 +19,7 @@ extern const struct wlr_surface_role drag_icon_surface_role;
struct wlr_data_offer *data_offer_create(struct wl_client *client,
struct wlr_data_source *source, uint32_t version);
void data_offer_update_action(struct wlr_data_offer *offer);
+void data_offer_destroy(struct wlr_data_offer *offer);
struct wlr_client_data_source *client_data_source_create(
struct wl_client *client, uint32_t version, uint32_t id,
@@ -26,7 +27,7 @@ struct wlr_client_data_source *client_data_source_create(
struct wlr_client_data_source *client_data_source_from_resource(
struct wl_resource *resource);
struct wlr_data_offer *data_source_send_offer(struct wlr_data_source *source,
- struct wlr_seat_client *target);
+ struct wl_resource *device_resource);
void data_source_notify_finish(struct wlr_data_source *source);
bool seat_client_start_drag(struct wlr_seat_client *client,
diff --git a/include/types/wlr_tablet_v2.h b/include/types/wlr_tablet_v2.h
index 4b9e727d..becde596 100644
--- a/include/types/wlr_tablet_v2.h
+++ b/include/types/wlr_tablet_v2.h
@@ -6,7 +6,7 @@
#include <wlr/types/wlr_tablet_v2.h>
struct wlr_tablet_seat_v2 {
- struct wl_list link;
+ struct wl_list link; // wlr_tablet_manager_v2::seats
struct wlr_seat *wlr_seat;
struct wlr_tablet_manager_v2 *manager;
@@ -14,7 +14,7 @@ struct wlr_tablet_seat_v2 {
struct wl_list tools;
struct wl_list pads;
- struct wl_list clients; //wlr_tablet_seat_v2_client::link;
+ struct wl_list clients; // wlr_tablet_seat_v2_client::link
struct wl_listener seat_destroy;
};
diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h
index 02b4a11e..9c031b7f 100644
--- a/include/wlr/render/wlr_renderer.h
+++ b/include/wlr/render/wlr_renderer.h
@@ -97,11 +97,6 @@ int wlr_renderer_get_dmabuf_formats(struct wlr_renderer *renderer,
int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *renderer, int format,
uint64_t **modifiers);
/**
- * Get the preferred format for reading pixels.
- */
-bool wlr_renderer_preferred_read_format(struct wlr_renderer *renderer,
- enum wl_shm_format *fmt);
-/**
* Reads out of pixels of the currently bound surface into data. `stride` is in
* bytes.
*
diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h
index 1772e54b..36b9e83f 100644
--- a/include/wlr/types/wlr_compositor.h
+++ b/include/wlr/types/wlr_compositor.h
@@ -43,6 +43,10 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
bool wlr_surface_is_subsurface(struct wlr_surface *surface);
+/**
+ * Get a subsurface from a surface. Can return NULL if the subsurface has been
+ * destroyed.
+ */
struct wlr_subsurface *wlr_subsurface_from_wlr_surface(
struct wlr_surface *surface);
diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h
index 9ce8f400..9c4ce995 100644
--- a/include/wlr/types/wlr_data_device.h
+++ b/include/wlr/types/wlr_data_device.h
@@ -12,14 +12,14 @@
#include <wayland-server.h>
#include <wlr/types/wlr_seat.h>
-extern const struct
-wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface;
+extern const struct wlr_pointer_grab_interface
+ wlr_data_device_pointer_drag_interface;
-extern const struct
-wlr_keyboard_grab_interface wlr_data_device_keyboard_drag_interface;
+extern const struct wlr_keyboard_grab_interface
+ wlr_data_device_keyboard_drag_interface;
-extern const struct
-wlr_touch_grab_interface wlr_data_device_touch_drag_interface;
+extern const struct wlr_touch_grab_interface
+ wlr_data_device_touch_drag_interface;
struct wlr_data_device_manager {
struct wl_global *global;
@@ -72,7 +72,6 @@ struct wlr_data_source {
// source status
bool accepted;
- struct wlr_data_offer *offer;
// drag'n'drop status
enum wl_data_device_manager_dnd_action current_dnd_action;
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 557a3895..6d38152a 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -193,6 +193,12 @@ void wlr_output_effective_resolution(struct wlr_output *output,
*/
bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
/**
+ * Get the preferred format for reading pixels.
+ * This function might change the current rendering context.
+ */
+bool wlr_output_preferred_read_format(struct wlr_output *output,
+ enum wl_shm_format *fmt);
+/**
* Swaps the output buffers. If the time of the frame isn't known, set `when` to
* NULL. If the compositor doesn't support damage tracking, set `damage` to
* NULL.
diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c
index ca1a337d..58731d7f 100644
--- a/render/wlr_renderer.c
+++ b/render/wlr_renderer.c
@@ -139,15 +139,6 @@ int wlr_renderer_get_dmabuf_modifiers(struct wlr_renderer *r, int format,
return r->impl->get_dmabuf_modifiers(r, format, modifiers);
}
-bool wlr_renderer_preferred_read_format(struct wlr_renderer *r,
- enum wl_shm_format *fmt) {
- if (!r->impl->preferred_read_format || !r->impl->read_pixels) {
- return false;
- }
- *fmt = r->impl->preferred_read_format(r);
- return true;
-}
-
bool wlr_renderer_read_pixels(struct wlr_renderer *r, enum wl_shm_format fmt,
uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
diff --git a/types/data_device/wlr_data_device.c b/types/data_device/wlr_data_device.c
index a50f0b4a..f868ea37 100644
--- a/types/data_device/wlr_data_device.c
+++ b/types/data_device/wlr_data_device.c
@@ -94,25 +94,24 @@ static void data_device_handle_resource_destroy(struct wl_resource *resource) {
void wlr_seat_client_send_selection(struct wlr_seat_client *seat_client) {
- if (wl_list_empty(&seat_client->data_devices)) {
- return;
+ struct wlr_data_source *source = seat_client->seat->selection_source;
+ if (source != NULL) {
+ source->accepted = false;
}
- if (seat_client->seat->selection_source) {
- struct wlr_data_offer *offer = data_source_send_offer(
- seat_client->seat->selection_source, seat_client);
- if (offer == NULL) {
- return;
- }
-
- struct wl_resource *resource;
- wl_resource_for_each(resource, &seat_client->data_devices) {
- wl_data_device_send_selection(resource, offer->resource);
- }
- } else {
- struct wl_resource *resource;
- wl_resource_for_each(resource, &seat_client->data_devices) {
- wl_data_device_send_selection(resource, NULL);
+ struct wl_resource *device_resource;
+ wl_resource_for_each(device_resource, &seat_client->data_devices) {
+ if (source != NULL) {
+ struct wlr_data_offer *offer =
+ data_source_send_offer(source, device_resource);
+ if (offer == NULL) {
+ wl_client_post_no_memory(seat_client->client);
+ return;
+ }
+
+ wl_data_device_send_selection(device_resource, offer->resource);
+ } else {
+ wl_data_device_send_selection(device_resource, NULL);
}
}
}
diff --git a/types/data_device/wlr_data_offer.c b/types/data_device/wlr_data_offer.c
index 9847e07c..b8cec091 100644
--- a/types/data_device/wlr_data_offer.c
+++ b/types/data_device/wlr_data_offer.c
@@ -55,15 +55,10 @@ static uint32_t data_offer_choose_action(struct wlr_data_offer *offer) {
}
void data_offer_update_action(struct wlr_data_offer *offer) {
- if (!offer->source) {
- return;
- }
-
uint32_t action = data_offer_choose_action(offer);
if (offer->source->current_dnd_action == action) {
return;
}
-
offer->source->current_dnd_action = action;
if (offer->in_ask) {
@@ -78,50 +73,77 @@ void data_offer_update_action(struct wlr_data_offer *offer) {
}
}
-static void data_offer_accept(struct wl_client *client,
+static void data_offer_handle_accept(struct wl_client *client,
struct wl_resource *resource, uint32_t serial, const char *mime_type) {
struct wlr_data_offer *offer = data_offer_from_resource(resource);
-
- if (!offer->source || offer != offer->source->offer) {
+ if (offer == NULL) {
return;
}
- // TODO check that client is currently focused by the input device
-
wlr_data_source_accept(offer->source, serial, mime_type);
}
-static void data_offer_receive(struct wl_client *client,
+static void data_offer_handle_receive(struct wl_client *client,
struct wl_resource *resource, const char *mime_type, int32_t fd) {
struct wlr_data_offer *offer = data_offer_from_resource(resource);
-
- if (offer->source && offer == offer->source->offer) {
- wlr_data_source_send(offer->source, mime_type, fd);
- } else {
+ if (offer == NULL) {
close(fd);
+ return;
}
+
+ wlr_data_source_send(offer->source, mime_type, fd);
}
-static void data_offer_destroy(struct wl_client *client,
+static void data_offer_dnd_finish(struct wlr_data_offer *offer) {
+ struct wlr_data_source *source = offer->source;
+ if (source->actions < 0) {
+ return;
+ }
+
+ if (offer->in_ask) {
+ wlr_data_source_dnd_action(source, source->current_dnd_action);
+ }
+
+ wlr_data_source_dnd_finish(source);
+}
+
+static void data_offer_handle_destroy(struct wl_client *client,
struct wl_resource *resource) {
+ struct wlr_data_offer *offer = data_offer_from_resource(resource);
+ if (offer == NULL) {
+ goto out;
+ }
+
+ // If the drag destination has version < 3, wl_data_offer.finish
+ // won't be called, so do this here as a safety net, because
+ // we still want the version >= 3 drag source to be happy.
+ if (wl_resource_get_version(offer->resource) <
+ WL_DATA_OFFER_ACTION_SINCE_VERSION) {
+ data_offer_dnd_finish(offer);
+ }
+
+out:
wl_resource_destroy(resource);
}
-static void data_offer_finish(struct wl_client *client,
+static void data_offer_handle_finish(struct wl_client *client,
struct wl_resource *resource) {
struct wlr_data_offer *offer = data_offer_from_resource(resource);
-
- if (!offer->source || offer->source->offer != offer) {
+ if (offer == NULL) {
return;
}
- data_source_notify_finish(offer->source);
+ data_offer_dnd_finish(offer);
+ data_offer_destroy(offer);
}
-static void data_offer_set_actions(struct wl_client *client,
+static void data_offer_handle_set_actions(struct wl_client *client,
struct wl_resource *resource, uint32_t actions,
uint32_t preferred_action) {
struct wlr_data_offer *offer = data_offer_from_resource(resource);
+ if (offer == NULL) {
+ return;
+ }
if (actions & ~DATA_DEVICE_ALL_ACTIONS) {
wl_resource_post_error(offer->resource,
@@ -144,52 +166,36 @@ static void data_offer_set_actions(struct wl_client *client,
data_offer_update_action(offer);
}
-static void data_offer_handle_resource_destroy(struct wl_resource *resource) {
- struct wlr_data_offer *offer = data_offer_from_resource(resource);
-
- if (!offer->source) {
- goto out;
+void data_offer_destroy(struct wlr_data_offer *offer) {
+ if (offer == NULL) {
+ return;
}
wl_list_remove(&offer->source_destroy.link);
- if (offer->source->offer != offer) {
- goto out;
- }
-
- // If the drag destination has version < 3, wl_data_offer.finish
- // won't be called, so do this here as a safety net, because
- // we still want the version >= 3 drag source to be happy.
- if (wl_resource_get_version(offer->resource) <
- WL_DATA_OFFER_ACTION_SINCE_VERSION) {
- data_source_notify_finish(offer->source);
- offer->source->offer = NULL;
- } else if (offer->source->impl->dnd_finish) {
- // source->cancel can free the source
- offer->source->offer = NULL;
- wlr_data_source_cancel(offer->source);
- } else {
- offer->source->offer = NULL;
- }
-
-out:
+ // Make the resource inert
+ wl_resource_set_user_data(offer->resource, NULL);
free(offer);
}
static const struct wl_data_offer_interface data_offer_impl = {
- .accept = data_offer_accept,
- .receive = data_offer_receive,
- .destroy = data_offer_destroy,
- .finish = data_offer_finish,
- .set_actions = data_offer_set_actions,
+ .accept = data_offer_handle_accept,
+ .receive = data_offer_handle_receive,
+ .destroy = data_offer_handle_destroy,
+ .finish = data_offer_handle_finish,
+ .set_actions = data_offer_handle_set_actions,
};
-static void handle_offer_source_destroyed(struct wl_listener *listener,
+static void data_offer_handle_resource_destroy(struct wl_resource *resource) {
+ struct wlr_data_offer *offer = data_offer_from_resource(resource);
+ data_offer_destroy(offer);
+}
+
+static void data_offer_handle_source_destroy(struct wl_listener *listener,
void *data) {
struct wlr_data_offer *offer =
wl_container_of(listener, offer, source_destroy);
-
- offer->source = NULL;
+ data_offer_destroy(offer);
}
struct wlr_data_offer *data_offer_create(struct wl_client *client,
@@ -200,8 +206,8 @@ struct wlr_data_offer *data_offer_create(struct wl_client *client,
}
offer->source = source;
- offer->resource = wl_resource_create(client,
- &wl_data_offer_interface, version, 0);
+ offer->resource =
+ wl_resource_create(client, &wl_data_offer_interface, version, 0);
if (offer->resource == NULL) {
free(offer);
return NULL;
@@ -209,7 +215,7 @@ struct wlr_data_offer *data_offer_create(struct wl_client *client,
wl_resource_set_implementation(offer->resource, &data_offer_impl, offer,
data_offer_handle_resource_destroy);
- offer->source_destroy.notify = handle_offer_source_destroyed;
+ offer->source_destroy.notify = data_offer_handle_source_destroy;
wl_signal_add(&source->events.destroy, &offer->source_destroy);
return offer;
diff --git a/types/data_device/wlr_data_source.c b/types/data_device/wlr_data_source.c
index 64db3a70..413f461a 100644
--- a/types/data_device/wlr_data_source.c
+++ b/types/data_device/wlr_data_source.c
@@ -11,47 +11,22 @@
#include "types/wlr_data_device.h"
#include "util/signal.h"
-void data_source_notify_finish(struct wlr_data_source *source) {
- assert(source->offer);
- if (source->actions < 0) {
- return;
- }
-
- if (source->offer->in_ask) {
- wlr_data_source_dnd_action(source, source->current_dnd_action);
- }
-
- source->offer = NULL;
- wlr_data_source_dnd_finish(source);
-}
-
struct wlr_data_offer *data_source_send_offer(struct wlr_data_source *source,
- struct wlr_seat_client *target) {
- if (wl_list_empty(&target->data_devices)) {
- return NULL;
- }
-
- uint32_t version = wl_resource_get_version(
- wl_resource_from_link(target->data_devices.next));
-
- struct wlr_data_offer *offer =
- data_offer_create(target->client, source, version);
+ struct wl_resource *device_resource) {
+ struct wl_client *client = wl_resource_get_client(device_resource);
+ uint32_t version = wl_resource_get_version(device_resource);
+ struct wlr_data_offer *offer = data_offer_create(client, source, version);
if (offer == NULL) {
return NULL;
}
- struct wl_resource *target_resource;
- wl_resource_for_each(target_resource, &target->data_devices) {
- wl_data_device_send_data_offer(target_resource, offer->resource);
- }
+ wl_data_device_send_data_offer(device_resource, offer->resource);
char **p;
wl_array_for_each(p, &source->mime_types) {
wl_data_offer_send_offer(offer->resource, *p);
}
- source->offer = offer;
- source->accepted = false;
return offer;
}
diff --git a/types/data_device/wlr_drag.c b/types/data_device/wlr_drag.c
index 8ed6e034..8e737597 100644
--- a/types/data_device/wlr_drag.c
+++ b/types/data_device/wlr_drag.c
@@ -47,25 +47,27 @@ static void drag_set_focus(struct wlr_drag *drag,
return;
}
- if (drag->source && drag->source->offer) {
- // unlink the offer from the source
- wl_list_remove(&drag->source->offer->source_destroy.link);
- drag->source->offer->source = NULL;
- drag->source->offer = NULL;
- }
-
struct wlr_seat_client *focus_client = wlr_seat_client_for_wl_client(
drag->seat_client->seat, wl_resource_get_client(surface->resource));
if (!focus_client) {
return;
}
- struct wl_resource *offer_resource = NULL;
- if (drag->source) {
+ if (drag->source != NULL) {
drag->source->accepted = false;
- struct wlr_data_offer *offer = data_source_send_offer(drag->source,
- focus_client);
- if (offer != NULL) {
+
+ uint32_t serial =
+ wl_display_next_serial(drag->seat_client->seat->display);
+
+ struct wl_resource *device_resource;
+ wl_resource_for_each(device_resource, &focus_client->data_devices) {
+ struct wlr_data_offer *offer =
+ data_source_send_offer(drag->source, device_resource);
+ if (offer == NULL) {
+ wl_resource_post_no_memory(device_resource);
+ return;
+ }
+
data_offer_update_action(offer);
if (wl_resource_get_version(offer->resource) >=
@@ -74,18 +76,10 @@ static void drag_set_focus(struct wlr_drag *drag,
drag->source->actions);
}
- offer_resource = offer->resource;
- }
- }
-
- if (!wl_list_empty(&focus_client->data_devices)) {
- uint32_t serial =
- wl_display_next_serial(drag->seat_client->seat->display);
- struct wl_resource *resource;
- wl_resource_for_each(resource, &focus_client->data_devices) {
- wl_data_device_send_enter(resource, serial, surface->resource,
+ wl_data_device_send_enter(device_resource, serial,
+ surface->resource,
wl_fixed_from_double(sx), wl_fixed_from_double(sy),
- offer_resource);
+ offer->resource);
}
}
@@ -174,12 +168,6 @@ static uint32_t drag_handle_pointer_button(struct wlr_seat_pointer_grab *grab,
}
wlr_data_source_dnd_drop(drag->source);
- if (drag->source->offer != NULL) {
- drag->source->offer->in_ask =
- drag->source->current_dnd_action ==
- WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
- }
-
struct wlr_drag_drop_event event = {
.drag = drag,
.time = time,
diff --git a/types/tablet_v2/wlr_tablet_v2.c b/types/tablet_v2/wlr_tablet_v2.c
index 7f3d5f30..a1cace93 100644
--- a/types/tablet_v2/wlr_tablet_v2.c
+++ b/types/tablet_v2/wlr_tablet_v2.c
@@ -27,20 +27,22 @@ struct wlr_tablet_manager_client_v2 {
struct wl_list tablet_seats; // wlr_tablet_seat_client_v2::link
};
-static void handle_wlr_seat_destroy(struct wl_listener *listener, void *data) {
- struct wlr_tablet_seat_v2 *seat =
- wl_container_of(listener, seat, seat_destroy);
-
+static void tablet_seat_destroy(struct wlr_tablet_seat_v2 *seat) {
wl_list_remove(&seat->link);
wl_list_remove(&seat->seat_destroy.link);
- struct wlr_tablet_seat_client_v2 *client;
- struct wlr_tablet_seat_client_v2 *tmp;
- wl_list_for_each_safe(client, tmp, &seat->clients, seat_link) {
+ struct wlr_tablet_seat_client_v2 *client, *client_tmp;
+ wl_list_for_each_safe(client, client_tmp, &seat->clients, seat_link) {
tablet_seat_client_v2_destroy(client->resource);
}
}
+static void handle_wlr_seat_destroy(struct wl_listener *listener, void *data) {
+ struct wlr_tablet_seat_v2 *seat =
+ wl_container_of(listener, seat, seat_destroy);
+ tablet_seat_destroy(seat);
+}
+
static struct wlr_tablet_seat_v2 *create_tablet_seat(
struct wlr_tablet_manager_v2 *manager,
struct wlr_seat *wlr_seat) {
@@ -79,13 +81,13 @@ struct wlr_tablet_seat_v2 *get_or_create_tablet_seat(
return create_tablet_seat(manager, wlr_seat);
}
-static void tablet_seat_destroy(struct wl_client *client,
+static void tablet_seat_handle_destroy(struct wl_client *client,
struct wl_resource *resource) {
wl_resource_destroy(resource);
}
static struct zwp_tablet_seat_v2_interface seat_impl = {
- .destroy = tablet_seat_destroy,
+ .destroy = tablet_seat_handle_destroy,
};
struct wlr_tablet_seat_client_v2 *tablet_seat_client_from_resource(
@@ -138,12 +140,13 @@ static void tablet_manager_destroy(struct wl_client *client,
wl_resource_destroy(resource);
}
-static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource(struct wl_resource *resource);
+static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource(
+ struct wl_resource *resource);
static void get_tablet_seat(struct wl_client *wl_client, struct wl_resource *resource,
- uint32_t id, struct wl_resource *seat_resource)
-{
- struct wlr_tablet_manager_client_v2 *manager = tablet_manager_client_from_resource(resource);
+ uint32_t id, struct wl_resource *seat_resource) {
+ struct wlr_tablet_manager_client_v2 *manager =
+ tablet_manager_client_from_resource(resource);
if (!manager) {
/* Inert manager, just set up the resource for later
* destruction, without allocations or advertising things
@@ -214,7 +217,7 @@ static struct zwp_tablet_manager_v2_interface manager_impl = {
.destroy = tablet_manager_destroy,
};
-static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource (
+static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource(
struct wl_resource *resource) {
assert(wl_resource_instance_of(resource, &zwp_tablet_manager_v2_interface,
&manager_impl));
@@ -222,7 +225,8 @@ static struct wlr_tablet_manager_client_v2 *tablet_manager_client_from_resource
}
static void wlr_tablet_manager_v2_destroy(struct wl_resource *resource) {
- struct wlr_tablet_manager_client_v2 *client = tablet_manager_client_from_resource(resource);
+ struct wlr_tablet_manager_client_v2 *client =
+ tablet_manager_client_from_resource(resource);
if (!client) {
return;
}
@@ -275,11 +279,14 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
}
void wlr_tablet_v2_destroy(struct wlr_tablet_manager_v2 *manager) {
- struct wlr_tablet_manager_client_v2 *tmp;
- struct wlr_tablet_manager_client_v2 *pos;
+ struct wlr_tablet_manager_client_v2 *client, *client_tmp;
+ wl_list_for_each_safe(client, client_tmp, &manager->clients, link) {
+ wlr_tablet_manager_v2_destroy(client->resource);
+ }
- wl_list_for_each_safe(pos, tmp, &manager->clients, link) {
- wlr_tablet_manager_v2_destroy(pos->resource);
+ struct wlr_tablet_seat_v2 *seat, *seat_tmp;
+ wl_list_for_each_safe(seat, seat_tmp, &manager->seats, link) {
+ tablet_seat_destroy(seat);
}
wlr_signal_emit_safe(&manager->events.destroy, manager);
diff --git a/types/wlr_output.c b/types/wlr_output.c
index 71cb3eba..dc8e34b8 100644
--- a/types/wlr_output.c
+++ b/types/wlr_output.c
@@ -6,6 +6,7 @@
#include <time.h>
#include <wayland-server.h>
#include <wlr/interfaces/wlr_output.h>
+#include <wlr/render/interface.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_matrix.h>
@@ -339,6 +340,20 @@ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age) {
return output->impl->make_current(output, buffer_age);
}
+bool wlr_output_preferred_read_format(struct wlr_output *output,
+ enum wl_shm_format *fmt) {
+ if (!wlr_output_make_current(output, NULL)) {
+ return false;
+ }
+
+ struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
+ if (!renderer->impl->preferred_read_format || !renderer->impl->read_pixels) {
+ return false;
+ }
+ *fmt = renderer->impl->preferred_read_format(renderer);
+ return true;
+}
+
bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
pixman_region32_t *damage) {
if (output->frame_pending) {
diff --git a/types/wlr_screencopy_v1.c b/types/wlr_screencopy_v1.c
index b186b89b..1d8550fe 100644
--- a/types/wlr_screencopy_v1.c
+++ b/types/wlr_screencopy_v1.c
@@ -219,7 +219,7 @@ static void capture_output(struct wl_client *client,
struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
assert(renderer);
- if (!wlr_renderer_preferred_read_format(renderer, &frame->format)) {
+ if (!wlr_output_preferred_read_format(frame->output, &frame->format)) {
wlr_log(WLR_ERROR,
"Failed to capture output: no read format supported by renderer");
goto error;
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index b19387c8..27176ef0 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -376,7 +376,7 @@ static void surface_commit_pending(struct wlr_surface *surface) {
}
static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) {
- while (1) {
+ while (subsurface != NULL) {
if (subsurface->synchronized) {
return true;
}
@@ -436,15 +436,14 @@ static void surface_commit(struct wl_client *client,
struct wl_resource *resource) {
struct wlr_surface *surface = wlr_surface_from_resource(resource);
- if (wlr_surface_is_subsurface(surface)) {
- struct wlr_subsurface *subsurface =
- wlr_subsurface_from_wlr_surface(surface);
+ struct wlr_subsurface *subsurface = wlr_surface_is_subsurface(surface) ?
+ wlr_subsurface_from_wlr_surface(surface) : NULL;
+ if (subsurface != NULL) {
subsurface_commit(subsurface);
} else {
surface_commit_pending(surface);
}
- struct wlr_subsurface *subsurface;
wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) {
subsurface_parent_commit(subsurface, false);
}
@@ -904,6 +903,9 @@ struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) {
while (wlr_surface_is_subsurface(surface)) {
struct wlr_subsurface *subsurface =
wlr_subsurface_from_wlr_surface(surface);
+ if (subsurface == NULL) {
+ break;
+ }
surface = subsurface->parent;
}
return surface;
diff --git a/types/wlr_text_input_v3.c b/types/wlr_text_input_v3.c
index 6ec0762a..e8f7a613 100644
--- a/types/wlr_text_input_v3.c
+++ b/types/wlr_text_input_v3.c
@@ -176,7 +176,7 @@ static void text_input_commit(struct wl_client *client,
text_input->current_serial++;
if (text_input->focused_surface == NULL) {
- wlr_log(WLR_DEBUG, "Text input commit received without focus\n");
+ wlr_log(WLR_DEBUG, "Text input commit received without focus");
}
if (!old_enabled && text_input->current_enabled) {