From 5e58d46cc1a90810e3ee76203cee8ca2f14fb462 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 12 Feb 2018 09:12:31 +0100 Subject: [PATCH] Add wlr_signal_emit_safe --- backend/drm/backend.c | 3 ++- backend/drm/drm.c | 5 ++-- backend/headless/backend.c | 7 +++--- backend/headless/input_device.c | 5 ++-- backend/headless/output.c | 3 ++- backend/libinput/backend.c | 5 ++-- backend/libinput/events.c | 13 +++++----- backend/libinput/pointer.c | 9 +++---- backend/libinput/tablet_pad.c | 7 +++--- backend/libinput/tablet_tool.c | 9 +++---- backend/libinput/touch.c | 9 +++---- backend/multi/backend.c | 15 ++++++------ backend/session/direct-freebsd.c | 5 ++-- backend/session/direct.c | 5 ++-- backend/session/logind.c | 7 +++--- backend/session/session.c | 3 ++- backend/wayland/backend.c | 3 ++- backend/wayland/output.c | 3 ++- backend/wayland/wl_seat.c | 13 +++++----- backend/x11/backend.c | 21 ++++++++-------- include/wlr/util/signal.h | 8 +++++++ render/gles2/texture.c | 3 ++- rootston/desktop.c | 3 ++- types/wlr_compositor.c | 3 ++- types/wlr_cursor.c | 25 +++++++++---------- types/wlr_data_device.c | 13 +++++----- types/wlr_gamma_control.c | 3 ++- types/wlr_idle.c | 3 ++- types/wlr_input_device.c | 3 ++- types/wlr_keyboard.c | 11 +++++---- types/wlr_output.c | 21 ++++++++-------- types/wlr_output_damage.c | 5 ++-- types/wlr_output_layout.c | 19 ++++++++------- types/wlr_primary_selection.c | 7 +++--- types/wlr_seat.c | 21 ++++++++-------- types/wlr_server_decoration.c | 7 +++--- types/wlr_surface.c | 9 +++---- types/wlr_wl_shell.c | 25 +++++++++---------- types/wlr_xdg_shell_v6.c | 25 +++++++++---------- util/meson.build | 1 + util/signal.c | 34 ++++++++++++++++++++++++++ xwayland/xwayland.c | 7 +++--- xwayland/xwm.c | 41 ++++++++++++++++---------------- 43 files changed, 265 insertions(+), 182 deletions(-) create mode 100644 include/wlr/util/signal.h create mode 100644 util/signal.c diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 3782817ce..4d09e0780 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "backend/drm/drm.h" @@ -34,7 +35,7 @@ static void wlr_drm_backend_destroy(struct wlr_backend *backend) { wlr_output_destroy(&conn->output); } - wl_signal_emit(&backend->events.destroy, backend); + wlr_signal_emit_safe(&backend->events.destroy, backend); wl_list_remove(&drm->display_destroy.link); wl_list_remove(&drm->session_signal.link); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 56a788512..516eb405f 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -870,7 +871,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET; wlr_log(L_INFO, "Sending modesetting signal for '%s'", wlr_conn->output.name); - wl_signal_emit(&drm->backend.events.output_add, &wlr_conn->output); + wlr_signal_emit_safe(&drm->backend.events.output_add, &wlr_conn->output); } else if (wlr_conn->state == WLR_DRM_CONN_CONNECTED && drm_conn->connection != DRM_MODE_CONNECTED) { wlr_log(L_INFO, "'%s' disconnected", wlr_conn->output.name); @@ -1014,7 +1015,7 @@ void wlr_drm_connector_cleanup(struct wlr_drm_connector *conn) { case WLR_DRM_CONN_NEEDS_MODESET: wlr_log(L_INFO, "Emitting destruction signal for '%s'", conn->output.name); - wl_signal_emit(&drm->backend.events.output_remove, &conn->output); + wlr_signal_emit_safe(&drm->backend.events.output_remove, &conn->output); break; case WLR_DRM_CONN_DISCONNECTED: break; diff --git a/backend/headless/backend.c b/backend/headless/backend.c index 0bf5ec286..7832b00c0 100644 --- a/backend/headless/backend.c +++ b/backend/headless/backend.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include "backend/headless.h" @@ -16,14 +17,14 @@ static bool backend_start(struct wlr_backend *wlr_backend) { wl_list_for_each(output, &backend->outputs, link) { wl_event_source_timer_update(output->frame_timer, output->frame_delay); wlr_output_update_enabled(&output->wlr_output, true); - wl_signal_emit(&backend->backend.events.output_add, + wlr_signal_emit_safe(&backend->backend.events.output_add, &output->wlr_output); } struct wlr_headless_input_device *input_device; wl_list_for_each(input_device, &backend->input_devices, wlr_input_device.link) { - wl_signal_emit(&backend->backend.events.input_add, + wlr_signal_emit_safe(&backend->backend.events.input_add, &input_device->wlr_input_device); } @@ -51,7 +52,7 @@ static void backend_destroy(struct wlr_backend *wlr_backend) { wlr_input_device_destroy(&input_device->wlr_input_device); } - wl_signal_emit(&wlr_backend->events.destroy, backend); + wlr_signal_emit_safe(&wlr_backend->events.destroy, backend); wlr_egl_finish(&backend->egl); free(backend); diff --git a/backend/headless/input_device.c b/backend/headless/input_device.c index 5c62e87f1..68e7ce242 100644 --- a/backend/headless/input_device.c +++ b/backend/headless/input_device.c @@ -6,12 +6,13 @@ #include #include #include +#include #include "backend/headless.h" static void input_device_destroy(struct wlr_input_device *wlr_dev) { struct wlr_headless_input_device *device = (struct wlr_headless_input_device *)wlr_dev; - wl_signal_emit(&device->backend->backend.events.input_remove, wlr_dev); + wlr_signal_emit_safe(&device->backend->backend.events.input_remove, wlr_dev); free(device); } @@ -88,7 +89,7 @@ struct wlr_input_device *wlr_headless_add_input_device( wl_list_insert(&backend->input_devices, &wlr_device->link); if (backend->started) { - wl_signal_emit(&backend->backend.events.input_add, wlr_device); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_device); } return wlr_device; diff --git a/backend/headless/output.c b/backend/headless/output.c index 507595a5d..eab983ccb 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "backend/headless.h" static EGLSurface egl_create_surface(struct wlr_egl *egl, unsigned int width, @@ -136,7 +137,7 @@ struct wlr_output *wlr_headless_add_output(struct wlr_backend *wlr_backend, if (backend->started) { wl_event_source_timer_update(output->frame_timer, output->frame_delay); wlr_output_update_enabled(wlr_output, true); - wl_signal_emit(&backend->backend.events.output_add, wlr_output); + wlr_signal_emit_safe(&backend->backend.events.output_add, wlr_output); } return wlr_output; diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c index 864779472..dfbe1d200 100644 --- a/backend/libinput/backend.c +++ b/backend/libinput/backend.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "backend/libinput.h" static int wlr_libinput_open_restricted(const char *path, @@ -106,13 +107,13 @@ static void wlr_libinput_backend_destroy(struct wlr_backend *wlr_backend) { struct wl_list *wlr_devices = backend->wlr_device_lists.items[i]; struct wlr_input_device *wlr_dev, *next; wl_list_for_each_safe(wlr_dev, next, wlr_devices, link) { - wl_signal_emit(&backend->backend.events.input_remove, wlr_dev); + wlr_signal_emit_safe(&backend->backend.events.input_remove, wlr_dev); wlr_input_device_destroy(wlr_dev); } free(wlr_devices); } - wl_signal_emit(&wlr_backend->events.destroy, wlr_backend); + wlr_signal_emit_safe(&wlr_backend->events.destroy, wlr_backend); wl_list_remove(&backend->display_destroy.link); wl_list_remove(&backend->session_signal.link); diff --git a/backend/libinput/events.c b/backend/libinput/events.c index 758a9f252..60088a400 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "backend/libinput.h" struct wlr_input_device *get_appropriate_device( @@ -88,7 +89,7 @@ static void handle_device_added(struct wlr_libinput_backend *backend, free(wlr_dev); goto fail; } - wl_signal_emit(&backend->backend.events.input_add, wlr_dev); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) { struct wlr_input_device *wlr_dev = allocate_device(backend, @@ -101,7 +102,7 @@ static void handle_device_added(struct wlr_libinput_backend *backend, free(wlr_dev); goto fail; } - wl_signal_emit(&backend->backend.events.input_add, wlr_dev); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) { struct wlr_input_device *wlr_dev = allocate_device(backend, @@ -114,7 +115,7 @@ static void handle_device_added(struct wlr_libinput_backend *backend, free(wlr_dev); goto fail; } - wl_signal_emit(&backend->backend.events.input_add, wlr_dev); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) { struct wlr_input_device *wlr_dev = allocate_device(backend, @@ -127,7 +128,7 @@ static void handle_device_added(struct wlr_libinput_backend *backend, free(wlr_dev); goto fail; } - wl_signal_emit(&backend->backend.events.input_add, wlr_dev); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_TABLET_PAD)) { struct wlr_input_device *wlr_dev = allocate_device(backend, @@ -140,7 +141,7 @@ static void handle_device_added(struct wlr_libinput_backend *backend, free(wlr_dev); goto fail; } - wl_signal_emit(&backend->backend.events.input_add, wlr_dev); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_dev); } if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_GESTURE)) { // TODO @@ -178,7 +179,7 @@ static void handle_device_removed(struct wlr_libinput_backend *backend, } struct wlr_input_device *dev, *tmp_dev; wl_list_for_each_safe(dev, tmp_dev, wlr_devices, link) { - wl_signal_emit(&backend->backend.events.input_remove, dev); + wlr_signal_emit_safe(&backend->backend.events.input_remove, dev); wlr_input_device_destroy(dev); } for (size_t i = 0; i < backend->wlr_device_lists.length; i++) { diff --git a/backend/libinput/pointer.c b/backend/libinput/pointer.c index 13402ac20..f80f4f84e 100644 --- a/backend/libinput/pointer.c +++ b/backend/libinput/pointer.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "backend/libinput.h" struct wlr_pointer *wlr_libinput_pointer_create( @@ -35,7 +36,7 @@ void handle_pointer_motion(struct libinput_event *event, usec_to_msec(libinput_event_pointer_get_time_usec(pevent)); wlr_event.delta_x = libinput_event_pointer_get_dx(pevent); wlr_event.delta_y = libinput_event_pointer_get_dy(pevent); - wl_signal_emit(&wlr_dev->pointer->events.motion, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->pointer->events.motion, &wlr_event); } void handle_pointer_motion_abs(struct libinput_event *event, @@ -55,7 +56,7 @@ void handle_pointer_motion_abs(struct libinput_event *event, wlr_event.x_mm = libinput_event_pointer_get_absolute_x(pevent); wlr_event.y_mm = libinput_event_pointer_get_absolute_y(pevent); libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); - wl_signal_emit(&wlr_dev->pointer->events.motion_absolute, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->pointer->events.motion_absolute, &wlr_event); } void handle_pointer_button(struct libinput_event *event, @@ -81,7 +82,7 @@ void handle_pointer_button(struct libinput_event *event, wlr_event.state = WLR_BUTTON_RELEASED; break; } - wl_signal_emit(&wlr_dev->pointer->events.button, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->pointer->events.button, &wlr_event); } void handle_pointer_axis(struct libinput_event *event, @@ -128,7 +129,7 @@ void handle_pointer_axis(struct libinput_event *event, } wlr_event.delta = libinput_event_pointer_get_axis_value( pevent, axies[i]); - wl_signal_emit(&wlr_dev->pointer->events.axis, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->pointer->events.axis, &wlr_event); } } } diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index 7dac3b7c9..54315581c 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "backend/libinput.h" struct wlr_tablet_pad *wlr_libinput_tablet_pad_create( @@ -41,7 +42,7 @@ void handle_tablet_pad_button(struct libinput_event *event, wlr_event.state = WLR_BUTTON_RELEASED; break; } - wl_signal_emit(&wlr_dev->tablet_pad->events.button, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.button, &wlr_event); } void handle_tablet_pad_ring(struct libinput_event *event, @@ -67,7 +68,7 @@ void handle_tablet_pad_ring(struct libinput_event *event, wlr_event.source = WLR_TABLET_PAD_RING_SOURCE_FINGER; break; } - wl_signal_emit(&wlr_dev->tablet_pad->events.ring, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.ring, &wlr_event); } void handle_tablet_pad_strip(struct libinput_event *event, @@ -93,5 +94,5 @@ void handle_tablet_pad_strip(struct libinput_event *event, wlr_event.source = WLR_TABLET_PAD_STRIP_SOURCE_FINGER; break; } - wl_signal_emit(&wlr_dev->tablet_pad->events.strip, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.strip, &wlr_event); } diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 3d5fafc3f..2f28540b5 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "backend/libinput.h" struct wlr_tablet_tool *wlr_libinput_tablet_tool_create( @@ -72,7 +73,7 @@ void handle_tablet_tool_axis(struct libinput_event *event, } wlr_log(L_DEBUG, "Tablet tool axis event %d @ %f,%f", wlr_event.updated_axes, wlr_event.x_mm, wlr_event.y_mm); - wl_signal_emit(&wlr_dev->tablet_tool->events.axis, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.axis, &wlr_event); } void handle_tablet_tool_proximity(struct libinput_event *event, @@ -98,7 +99,7 @@ void handle_tablet_tool_proximity(struct libinput_event *event, handle_tablet_tool_axis(event, libinput_dev); break; } - wl_signal_emit(&wlr_dev->tablet_tool->events.proximity, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.proximity, &wlr_event); } void handle_tablet_tool_tip(struct libinput_event *event, @@ -124,7 +125,7 @@ void handle_tablet_tool_tip(struct libinput_event *event, wlr_event.state = WLR_TABLET_TOOL_TIP_DOWN; break; } - wl_signal_emit(&wlr_dev->tablet_tool->events.tip, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.tip, &wlr_event); } void handle_tablet_tool_button(struct libinput_event *event, @@ -151,5 +152,5 @@ void handle_tablet_tool_button(struct libinput_event *event, wlr_event.state = WLR_BUTTON_PRESSED; break; } - wl_signal_emit(&wlr_dev->tablet_tool->events.button, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.button, &wlr_event); } diff --git a/backend/libinput/touch.c b/backend/libinput/touch.c index 0ba6ec86a..d496d7927 100644 --- a/backend/libinput/touch.c +++ b/backend/libinput/touch.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "backend/libinput.h" struct wlr_touch *wlr_libinput_touch_create( @@ -37,7 +38,7 @@ void handle_touch_down(struct libinput_event *event, wlr_event.x_mm = libinput_event_touch_get_x(tevent); wlr_event.y_mm = libinput_event_touch_get_y(tevent); libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); - wl_signal_emit(&wlr_dev->touch->events.down, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->touch->events.down, &wlr_event); } void handle_touch_up(struct libinput_event *event, @@ -55,7 +56,7 @@ void handle_touch_up(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_touch_get_time_usec(tevent)); wlr_event.touch_id = libinput_event_touch_get_slot(tevent); - wl_signal_emit(&wlr_dev->touch->events.up, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->touch->events.up, &wlr_event); } void handle_touch_motion(struct libinput_event *event, @@ -76,7 +77,7 @@ void handle_touch_motion(struct libinput_event *event, wlr_event.x_mm = libinput_event_touch_get_x(tevent); wlr_event.y_mm = libinput_event_touch_get_y(tevent); libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); - wl_signal_emit(&wlr_dev->touch->events.motion, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->touch->events.motion, &wlr_event); } void handle_touch_cancel(struct libinput_event *event, @@ -94,5 +95,5 @@ void handle_touch_cancel(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_touch_get_time_usec(tevent)); wlr_event.touch_id = libinput_event_touch_get_slot(tevent); - wl_signal_emit(&wlr_dev->touch->events.cancel, &wlr_event); + wlr_signal_emit_safe(&wlr_dev->touch->events.cancel, &wlr_event); } diff --git a/backend/multi/backend.c b/backend/multi/backend.c index 78f5c63be..14f774d05 100644 --- a/backend/multi/backend.c +++ b/backend/multi/backend.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "backend/multi.h" #include "backend/drm/drm.h" @@ -51,7 +52,7 @@ static void multi_backend_destroy(struct wlr_backend *wlr_backend) { } // Destroy this backend only after removing all sub-backends - wl_signal_emit(&wlr_backend->events.destroy, backend); + wlr_signal_emit_safe(&wlr_backend->events.destroy, backend); free(backend); } @@ -120,25 +121,25 @@ bool wlr_backend_is_multi(struct wlr_backend *b) { static void input_add_reemit(struct wl_listener *listener, void *data) { struct subbackend_state *state = wl_container_of(listener, state, input_add); - wl_signal_emit(&state->container->events.input_add, data); + wlr_signal_emit_safe(&state->container->events.input_add, data); } static void input_remove_reemit(struct wl_listener *listener, void *data) { struct subbackend_state *state = wl_container_of(listener, state, input_remove); - wl_signal_emit(&state->container->events.input_remove, data); + wlr_signal_emit_safe(&state->container->events.input_remove, data); } static void output_add_reemit(struct wl_listener *listener, void *data) { struct subbackend_state *state = wl_container_of(listener, state, output_add); - wl_signal_emit(&state->container->events.output_add, data); + wlr_signal_emit_safe(&state->container->events.output_add, data); } static void output_remove_reemit(struct wl_listener *listener, void *data) { struct subbackend_state *state = wl_container_of(listener, state, output_remove); - wl_signal_emit(&state->container->events.output_remove, data); + wlr_signal_emit_safe(&state->container->events.output_remove, data); } static void handle_subbackend_destroy(struct wl_listener *listener, @@ -194,7 +195,7 @@ void wlr_multi_backend_add(struct wlr_backend *_multi, wl_signal_add(&backend->events.output_remove, &sub->output_remove); sub->output_remove.notify = output_remove_reemit; - wl_signal_emit(&multi->events.backend_add, backend); + wlr_signal_emit_safe(&multi->events.backend_add, backend); } void wlr_multi_backend_remove(struct wlr_backend *_multi, @@ -206,7 +207,7 @@ void wlr_multi_backend_remove(struct wlr_backend *_multi, multi_backend_get_subbackend(multi, backend); if (sub) { - wl_signal_emit(&multi->events.backend_remove, backend); + wlr_signal_emit_safe(&multi->events.backend_remove, backend); subbackend_state_destroy(sub); } } diff --git a/backend/session/direct-freebsd.c b/backend/session/direct-freebsd.c index c0621416c..fe4ff653b 100644 --- a/backend/session/direct-freebsd.c +++ b/backend/session/direct-freebsd.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "backend/session/direct-ipc.h" const struct session_impl session_direct; @@ -95,12 +96,12 @@ static int vt_handler(int signo, void *data) { if (session->base.active) { session->base.active = false; - wl_signal_emit(&session->base.session_signal, session); + wlr_signal_emit_safe(&session->base.session_signal, session); ioctl(session->tty_fd, VT_RELDISP, 1); } else { ioctl(session->tty_fd, VT_RELDISP, VT_ACKACQ); session->base.active = true; - wl_signal_emit(&session->base.session_signal, session); + wlr_signal_emit_safe(&session->base.session_signal, session); } return 1; diff --git a/backend/session/direct.c b/backend/session/direct.c index 9d6cd36d5..245683eab 100644 --- a/backend/session/direct.c +++ b/backend/session/direct.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "backend/session/direct-ipc.h" enum { DRM_MAJOR = 226 }; @@ -107,7 +108,7 @@ static int vt_handler(int signo, void *data) { if (session->base.active) { session->base.active = false; - wl_signal_emit(&session->base.session_signal, session); + wlr_signal_emit_safe(&session->base.session_signal, session); struct wlr_device *dev; wl_list_for_each(dev, &session->base.devices, link) { @@ -130,7 +131,7 @@ static int vt_handler(int signo, void *data) { } session->base.active = true; - wl_signal_emit(&session->base.session_signal, session); + wlr_signal_emit_safe(&session->base.session_signal, session); } return 1; diff --git a/backend/session/logind.c b/backend/session/logind.c index 1ece051f1..f6150817e 100644 --- a/backend/session/logind.c +++ b/backend/session/logind.c @@ -13,13 +13,14 @@ #include #include #include +#include #ifdef WLR_HAS_SYSTEMD #include #include #elif defined(WLR_HAS_ELOGIND) #include - #include + #include #endif enum { DRM_MAJOR = 226 }; @@ -250,7 +251,7 @@ static int pause_device(sd_bus_message *msg, void *userdata, sd_bus_error *ret_e if (major == DRM_MAJOR) { session->base.active = false; - wl_signal_emit(&session->base.session_signal, session); + wlr_signal_emit_safe(&session->base.session_signal, session); } if (strcmp(type, "pause") == 0) { @@ -286,7 +287,7 @@ static int resume_device(sd_bus_message *msg, void *userdata, sd_bus_error *ret_ if (!session->base.active) { session->base.active = true; - wl_signal_emit(&session->base.session_signal, session); + wlr_signal_emit_safe(&session->base.session_signal, session); } } diff --git a/backend/session/session.c b/backend/session/session.c index 2bbbd4efe..4b81e2307 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -13,6 +13,7 @@ #include #include #include +#include extern const struct session_impl session_logind; extern const struct session_impl session_direct; @@ -49,7 +50,7 @@ static int udev_event(int fd, uint32_t mask, void *data) { wl_list_for_each(dev, &session->devices, link) { if (dev->dev == devnum) { - wl_signal_emit(&dev->signal, session); + wlr_signal_emit_safe(&dev->signal, session); break; } } diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 458c9dd06..2907057c0 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "backend/wayland.h" #include "xdg-shell-unstable-v6-client-protocol.h" @@ -80,7 +81,7 @@ static void wlr_wl_backend_destroy(struct wlr_backend *wlr_backend) { wlr_input_device_destroy(input_device); } - wl_signal_emit(&wlr_backend->events.destroy, wlr_backend); + wlr_signal_emit_safe(&wlr_backend->events.destroy, wlr_backend); wl_list_remove(&backend->local_display_destroy.link); diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 0bbf6d42e..f2336549b 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "backend/wayland.h" #include "xdg-shell-unstable-v6-client-protocol.h" @@ -338,7 +339,7 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) { wl_list_insert(&backend->outputs, &output->link); wlr_output_update_enabled(wlr_output, true); - wl_signal_emit(&backend->backend.events.output_add, wlr_output); + wlr_signal_emit_safe(&backend->backend.events.output_add, wlr_output); return wlr_output; error: diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 374896785..2018f4495 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "backend/wayland.h" static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, @@ -78,7 +79,7 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, wlr_event.height_mm = layout_box.height; wlr_event.x_mm = transformed.x + wlr_output->lx - layout_box.x; wlr_event.y_mm = transformed.y + wlr_output->ly - layout_box.y; - wl_signal_emit(&dev->pointer->events.motion_absolute, &wlr_event); + wlr_signal_emit_safe(&dev->pointer->events.motion_absolute, &wlr_event); } static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, @@ -91,7 +92,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, wlr_event.button = button; wlr_event.state = state; wlr_event.time_msec = time; - wl_signal_emit(&dev->pointer->events.button, &wlr_event); + wlr_signal_emit_safe(&dev->pointer->events.button, &wlr_event); } static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, @@ -106,7 +107,7 @@ static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, wlr_event.orientation = axis; wlr_event.time_msec = time; wlr_event.source = wlr_wl_pointer->axis_source; - wl_signal_emit(&dev->pointer->events.axis, &wlr_event); + wlr_signal_emit_safe(&dev->pointer->events.axis, &wlr_event); } static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) { @@ -194,7 +195,7 @@ static struct wl_keyboard_listener keyboard_listener = { static void input_device_destroy(struct wlr_input_device *_dev) { struct wlr_wl_input_device *dev = (struct wlr_wl_input_device *)_dev; - wl_signal_emit(&dev->backend->backend.events.input_remove, &dev->wlr_input_device); + wlr_signal_emit_safe(&dev->backend->backend.events.input_remove, &dev->wlr_input_device); if (dev->resource) { wl_proxy_destroy(dev->resource); } @@ -256,7 +257,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, wlr_device->pointer = &wlr_wl_pointer->wlr_pointer; wlr_pointer_init(wlr_device->pointer, NULL); wlr_wl_device->resource = wl_pointer; - wl_signal_emit(&backend->backend.events.input_add, wlr_device); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_device); backend->pointer = wl_pointer; } if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { @@ -280,7 +281,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, struct wl_keyboard *wl_keyboard = wl_seat_get_keyboard(wl_seat); wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, wlr_device); wlr_wl_device->resource = wl_keyboard; - wl_signal_emit(&backend->backend.events.input_add, wlr_device); + wlr_signal_emit_safe(&backend->backend.events.input_add, wlr_device); } } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 411d0ef66..2417810af 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "backend/x11.h" static struct wlr_backend_impl backend_impl; @@ -77,7 +78,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e .orientation = WLR_AXIS_ORIENTATION_VERTICAL, .delta = delta, }; - wl_signal_emit(&x11->pointer.events.axis, &axis); + wlr_signal_emit_safe(&x11->pointer.events.axis, &axis); x11->time = ev->time; break; } @@ -96,7 +97,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED, }; - wl_signal_emit(&x11->pointer.events.button, &button); + wlr_signal_emit_safe(&x11->pointer.events.button, &button); } x11->time = ev->time; break; @@ -112,7 +113,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e .height_mm = output->wlr_output.height, }; - wl_signal_emit(&x11->pointer.events.motion_absolute, &abs); + wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); x11->time = ev->time; break; } @@ -140,7 +141,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e .height_mm = output->wlr_output.height, }; - wl_signal_emit(&x11->pointer.events.motion_absolute, &abs); + wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); break; } case XCB_GLX_DELETE_QUERIES_ARB: { @@ -229,9 +230,9 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) { xcb_flush(x11->xcb_conn); wlr_output_update_enabled(&output->wlr_output, true); - wl_signal_emit(&x11->backend.events.output_add, output); - wl_signal_emit(&x11->backend.events.input_add, &x11->keyboard_dev); - wl_signal_emit(&x11->backend.events.input_add, &x11->pointer_dev); + wlr_signal_emit_safe(&x11->backend.events.output_add, output); + wlr_signal_emit_safe(&x11->backend.events.input_add, &x11->keyboard_dev); + wlr_signal_emit_safe(&x11->backend.events.input_add, &x11->pointer_dev); wl_event_source_timer_update(x11->frame_timer, 16); @@ -248,8 +249,8 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { struct wlr_x11_output *output = &x11->output; wlr_output_destroy(&output->wlr_output); - wl_signal_emit(&backend->events.input_remove, &x11->pointer_dev); - wl_signal_emit(&backend->events.input_remove, &x11->keyboard_dev); + wlr_signal_emit_safe(&backend->events.input_remove, &x11->pointer_dev); + wlr_signal_emit_safe(&backend->events.input_remove, &x11->keyboard_dev); // TODO probably need to use wlr_keyboard_destroy, but the devices need to // be malloced for that to work if (x11->keyboard_dev.keyboard->keymap) { @@ -259,7 +260,7 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) { xkb_state_unref(x11->keyboard_dev.keyboard->xkb_state); } - wl_signal_emit(&backend->events.destroy, backend); + wlr_signal_emit_safe(&backend->events.destroy, backend); wl_list_remove(&x11->display_destroy.link); diff --git a/include/wlr/util/signal.h b/include/wlr/util/signal.h new file mode 100644 index 000000000..e13141d8a --- /dev/null +++ b/include/wlr/util/signal.h @@ -0,0 +1,8 @@ +#ifndef WLR_UTIL_SIGNAL_H +#define WLR_UTIL_SIGNAL_H + +#include + +void wlr_signal_emit_safe(struct wl_signal *signal, void *data); + +#endif diff --git a/render/gles2/texture.c b/render/gles2/texture.c index ff71cb089..54cee6277 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "render/gles2.h" static struct pixel_format external_pixel_format = { @@ -271,7 +272,7 @@ static void gles2_texture_bind(struct wlr_texture *_texture) { static void gles2_texture_destroy(struct wlr_texture *_texture) { struct wlr_gles2_texture *texture = (struct wlr_gles2_texture *)_texture; - wl_signal_emit(&texture->wlr_texture.destroy_signal, &texture->wlr_texture); + wlr_signal_emit_safe(&texture->wlr_texture.destroy_signal, &texture->wlr_texture); if (texture->tex_id) { GL_CALL(glDeleteTextures(1, &texture->tex_id)); } diff --git a/rootston/desktop.c b/rootston/desktop.c index 91661c058..e9d66d5c8 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "rootston/server.h" #include "rootston/seat.h" #include "rootston/xcursor.h" @@ -383,7 +384,7 @@ struct roots_subsurface *subsurface_create(struct roots_view *view, void view_finish(struct roots_view *view) { view_damage_whole(view); - wl_signal_emit(&view->events.destroy, view); + wlr_signal_emit_safe(&view->events.destroy, view); wl_list_remove(&view->new_subsurface.link); diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c index a4bd7a164..bab41b856 100644 --- a/types/wlr_compositor.c +++ b/types/wlr_compositor.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -35,7 +36,7 @@ static void wl_compositor_create_surface(struct wl_client *client, wl_list_insert(&compositor->surfaces, wl_resource_get_link(surface_resource)); - wl_signal_emit(&compositor->events.new_surface, surface); + wlr_signal_emit_safe(&compositor->events.new_surface, surface); } static void wl_compositor_create_region(struct wl_client *client, diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index fd48c1b61..564ead46c 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -325,7 +326,7 @@ static void handle_pointer_motion(struct wl_listener *listener, void *data) { struct wlr_event_pointer_motion *event = data; struct wlr_cursor_device *device = wl_container_of(listener, device, motion); - wl_signal_emit(&device->cursor->events.motion, event); + wlr_signal_emit_safe(&device->cursor->events.motion, event); } static void handle_pointer_motion_absolute(struct wl_listener *listener, @@ -333,62 +334,62 @@ static void handle_pointer_motion_absolute(struct wl_listener *listener, struct wlr_event_pointer_motion_absolute *event = data; struct wlr_cursor_device *device = wl_container_of(listener, device, motion_absolute); - wl_signal_emit(&device->cursor->events.motion_absolute, event); + wlr_signal_emit_safe(&device->cursor->events.motion_absolute, event); } static void handle_pointer_button(struct wl_listener *listener, void *data) { struct wlr_event_pointer_button *event = data; struct wlr_cursor_device *device = wl_container_of(listener, device, button); - wl_signal_emit(&device->cursor->events.button, event); + wlr_signal_emit_safe(&device->cursor->events.button, event); } static void handle_pointer_axis(struct wl_listener *listener, void *data) { struct wlr_event_pointer_axis *event = data; struct wlr_cursor_device *device = wl_container_of(listener, device, axis); - wl_signal_emit(&device->cursor->events.axis, event); + wlr_signal_emit_safe(&device->cursor->events.axis, event); } static void handle_touch_up(struct wl_listener *listener, void *data) { struct wlr_event_touch_up *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, touch_up); - wl_signal_emit(&device->cursor->events.touch_up, event); + wlr_signal_emit_safe(&device->cursor->events.touch_up, event); } static void handle_touch_down(struct wl_listener *listener, void *data) { struct wlr_event_touch_down *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, touch_down); - wl_signal_emit(&device->cursor->events.touch_down, event); + wlr_signal_emit_safe(&device->cursor->events.touch_down, event); } static void handle_touch_motion(struct wl_listener *listener, void *data) { struct wlr_event_touch_motion *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, touch_motion); - wl_signal_emit(&device->cursor->events.touch_motion, event); + wlr_signal_emit_safe(&device->cursor->events.touch_motion, event); } static void handle_touch_cancel(struct wl_listener *listener, void *data) { struct wlr_event_touch_cancel *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, touch_cancel); - wl_signal_emit(&device->cursor->events.touch_cancel, event); + wlr_signal_emit_safe(&device->cursor->events.touch_cancel, event); } static void handle_tablet_tool_tip(struct wl_listener *listener, void *data) { struct wlr_event_tablet_tool_tip *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, tablet_tool_tip); - wl_signal_emit(&device->cursor->events.tablet_tool_tip, event); + wlr_signal_emit_safe(&device->cursor->events.tablet_tool_tip, event); } static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) { struct wlr_event_tablet_tool_axis *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, tablet_tool_axis); - wl_signal_emit(&device->cursor->events.tablet_tool_axis, event); + wlr_signal_emit_safe(&device->cursor->events.tablet_tool_axis, event); } static void handle_tablet_tool_button(struct wl_listener *listener, @@ -396,7 +397,7 @@ static void handle_tablet_tool_button(struct wl_listener *listener, struct wlr_event_tablet_tool_button *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, tablet_tool_button); - wl_signal_emit(&device->cursor->events.tablet_tool_button, event); + wlr_signal_emit_safe(&device->cursor->events.tablet_tool_button, event); } static void handle_tablet_tool_proximity(struct wl_listener *listener, @@ -404,7 +405,7 @@ static void handle_tablet_tool_proximity(struct wl_listener *listener, struct wlr_event_tablet_tool_proximity *event = data; struct wlr_cursor_device *device; device = wl_container_of(listener, device, tablet_tool_proximity); - wl_signal_emit(&device->cursor->events.tablet_tool_proximity, event); + wlr_signal_emit_safe(&device->cursor->events.tablet_tool_proximity, event); } static void handle_device_destroy(struct wl_listener *listener, void *data) { diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index d7e4aa14c..ae3219f1b 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -290,7 +291,7 @@ static void seat_client_selection_data_source_destroy( seat->selection_data_source = NULL; - wl_signal_emit(&seat->events.selection, seat); + wlr_signal_emit_safe(&seat->events.selection, seat); } void wlr_seat_set_selection(struct wlr_seat *seat, @@ -321,7 +322,7 @@ void wlr_seat_set_selection(struct wlr_seat *seat, wlr_seat_client_send_selection(focused_client); } - wl_signal_emit(&seat->events.selection, seat); + wlr_signal_emit_safe(&seat->events.selection, seat); if (source) { seat->selection_data_source_destroy.notify = @@ -457,7 +458,7 @@ static void wlr_drag_end(struct wlr_drag *drag) { if (drag->icon) { drag->icon->mapped = false; wl_list_remove(&drag->icon_destroy.link); - wl_signal_emit(&drag->icon->events.map, drag->icon); + wlr_signal_emit_safe(&drag->icon->events.map, drag->icon); } free(drag); @@ -634,7 +635,7 @@ static void wlr_drag_icon_destroy(struct wlr_drag_icon *icon) { if (!icon) { return; } - wl_signal_emit(&icon->events.destroy, icon); + wlr_signal_emit_safe(&icon->events.destroy, icon); wlr_surface_set_role_committed(icon->surface, NULL, NULL); wl_list_remove(&icon->surface_destroy.link); wl_list_remove(&icon->seat_client_destroy.link); @@ -691,7 +692,7 @@ static struct wlr_drag_icon *wlr_drag_icon_create( icon->seat_client_destroy.notify = handle_drag_icon_seat_client_destroy; wl_list_insert(&client->seat->drag_icons, &icon->link); - wl_signal_emit(&client->seat->events.new_drag_icon, icon); + wlr_signal_emit_safe(&client->seat->events.new_drag_icon, icon); return icon; } @@ -941,7 +942,7 @@ void wlr_data_source_finish(struct wlr_data_source *source) { return; } - wl_signal_emit(&source->events.destroy, source); + wlr_signal_emit_safe(&source->events.destroy, source); char **p; wl_array_for_each(p, &source->mime_types) { diff --git a/types/wlr_gamma_control.c b/types/wlr_gamma_control.c index eb154b6b9..f7644230a 100644 --- a/types/wlr_gamma_control.c +++ b/types/wlr_gamma_control.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "gamma-control-protocol.h" static void resource_destroy(struct wl_client *client, @@ -15,7 +16,7 @@ static void gamma_control_destroy(struct wlr_gamma_control *gamma_control) { if (gamma_control == NULL) { return; } - wl_signal_emit(&gamma_control->events.destroy, gamma_control); + wlr_signal_emit_safe(&gamma_control->events.destroy, gamma_control); wl_list_remove(&gamma_control->output_destroy_listener.link); wl_resource_set_user_data(gamma_control->resource, NULL); wl_list_remove(&gamma_control->link); diff --git a/types/wlr_idle.c b/types/wlr_idle.c index f2cad42b9..b30bb9d74 100644 --- a/types/wlr_idle.c +++ b/types/wlr_idle.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "idle-protocol.h" static void idle_timeout_destroy(struct wlr_idle_timeout *timer) { @@ -186,5 +187,5 @@ struct wlr_idle *wlr_idle_create(struct wl_display *display) { } void wlr_idle_notify_activity(struct wlr_idle *idle, struct wlr_seat *seat) { - wl_signal_emit(&idle->activity_notify, seat); + wlr_signal_emit_safe(&idle->activity_notify, seat); } diff --git a/types/wlr_input_device.c b/types/wlr_input_device.c index 7015dcba8..468b93f9f 100644 --- a/types/wlr_input_device.c +++ b/types/wlr_input_device.c @@ -10,6 +10,7 @@ #include #include #include +#include void wlr_input_device_init(struct wlr_input_device *dev, enum wlr_input_device_type type, @@ -29,7 +30,7 @@ void wlr_input_device_destroy(struct wlr_input_device *dev) { return; } - wl_signal_emit(&dev->events.destroy, dev); + wlr_signal_emit_safe(&dev->events.destroy, dev); if (dev->_device) { switch (dev->type) { diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 29552eb4e..9fac1843a 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -7,6 +7,7 @@ #include #include #include +#include int os_create_anonymous_file(off_t size); @@ -110,7 +111,7 @@ void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, bool updated = keyboard_modifier_update(keyboard); if (updated) { - wl_signal_emit(&keyboard->events.modifiers, keyboard); + wlr_signal_emit_safe(&keyboard->events.modifiers, keyboard); } } @@ -128,11 +129,11 @@ void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, bool updated = keyboard_modifier_update(keyboard); if (updated) { - wl_signal_emit(&keyboard->events.modifiers, keyboard); + wlr_signal_emit_safe(&keyboard->events.modifiers, keyboard); } keyboard_key_update(keyboard, event); - wl_signal_emit(&keyboard->events.key, event); + wlr_signal_emit_safe(&keyboard->events.key, event); } void wlr_keyboard_init(struct wlr_keyboard *kb, @@ -234,7 +235,7 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, keyboard_modifier_update(kb); - wl_signal_emit(&kb->events.keymap, kb); + wlr_signal_emit_safe(&kb->events.keymap, kb); return; err: @@ -253,7 +254,7 @@ void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate, } kb->repeat_info.rate = rate; kb->repeat_info.delay = delay; - wl_signal_emit(&kb->events.repeat_info, kb); + wlr_signal_emit_safe(&kb->events.repeat_info, kb); } uint32_t wlr_keyboard_get_modifiers(struct wlr_keyboard *kb) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 5f7dca280..bf3ed6ae2 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -13,6 +13,7 @@ #include #include #include +#include static void wl_output_send_to_resource(struct wl_resource *resource) { assert(resource); @@ -139,7 +140,7 @@ void wlr_output_update_enabled(struct wlr_output *output, bool enabled) { } output->enabled = enabled; - wl_signal_emit(&output->events.enable, output); + wlr_signal_emit_safe(&output->events.enable, output); } static void wlr_output_update_matrix(struct wlr_output *output) { @@ -193,7 +194,7 @@ void wlr_output_update_custom_mode(struct wlr_output *output, int32_t width, wlr_output_send_current_mode_to_resource(resource); } - wl_signal_emit(&output->events.mode, output); + wlr_signal_emit_safe(&output->events.mode, output); } void wlr_output_set_transform(struct wlr_output *output, @@ -207,7 +208,7 @@ void wlr_output_set_transform(struct wlr_output *output, wl_output_send_to_resource(resource); } - wl_signal_emit(&output->events.transform, output); + wlr_signal_emit_safe(&output->events.transform, output); } void wlr_output_set_position(struct wlr_output *output, int32_t lx, @@ -239,7 +240,7 @@ void wlr_output_set_scale(struct wlr_output *output, float scale) { wl_output_send_to_resource(resource); } - wl_signal_emit(&output->events.scale, output); + wlr_signal_emit_safe(&output->events.scale, output); } static void handle_display_destroy(struct wl_listener *listener, void *data) { @@ -284,8 +285,8 @@ void wlr_output_destroy(struct wlr_output *output) { wlr_output_destroy_global(output); wlr_output_set_fullscreen_surface(output, NULL); - wl_signal_emit(&output->backend->events.output_remove, output); - wl_signal_emit(&output->events.destroy, output); + wlr_signal_emit_safe(&output->backend->events.output_remove, output); + wlr_signal_emit_safe(&output->events.destroy, output); struct wlr_output_mode *mode, *tmp_mode; wl_list_for_each_safe(mode, tmp_mode, &output->modes, link) { @@ -471,7 +472,7 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when, output->idle_frame = NULL; } - wl_signal_emit(&output->events.swap_buffers, damage); + wlr_signal_emit_safe(&output->events.swap_buffers, damage); int width, height; wlr_output_transformed_resolution(output, &width, &height); @@ -528,7 +529,7 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when, void wlr_output_send_frame(struct wlr_output *output) { output->frame_pending = false; - wl_signal_emit(&output->events.frame, output); + wlr_signal_emit_safe(&output->events.frame, output); } static void schedule_frame_handle_idle_timer(void *data) { @@ -566,7 +567,7 @@ uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { void wlr_output_update_needs_swap(struct wlr_output *output) { output->needs_swap = true; - wl_signal_emit(&output->events.needs_swap, output); + wlr_signal_emit_safe(&output->events.needs_swap, output); } static void output_damage_whole(struct wlr_output *output) { @@ -883,7 +884,7 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) { return; } output_cursor_reset(cursor); - wl_signal_emit(&cursor->events.destroy, cursor); + wlr_signal_emit_safe(&cursor->events.destroy, cursor); if (cursor->output->hardware_cursor == cursor) { // If this cursor was the hardware cursor, disable it if (cursor->output->impl->set_cursor) { diff --git a/types/wlr_output_damage.c b/types/wlr_output_damage.c index 354314b66..2c6e24f0f 100644 --- a/types/wlr_output_damage.c +++ b/types/wlr_output_damage.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,7 @@ static void output_handle_frame(struct wl_listener *listener, void *data) { return; } - wl_signal_emit(&output_damage->events.frame, output_damage); + wlr_signal_emit_safe(&output_damage->events.frame, output_damage); } struct wlr_output_damage *wlr_output_damage_create(struct wlr_output *output) { @@ -85,7 +86,7 @@ void wlr_output_damage_destroy(struct wlr_output_damage *output_damage) { if (output_damage == NULL) { return; } - wl_signal_emit(&output_damage->events.destroy, output_damage); + wlr_signal_emit_safe(&output_damage->events.destroy, output_damage); wl_list_remove(&output_damage->output_destroy.link); wl_list_remove(&output_damage->output_mode.link); wl_list_remove(&output_damage->output_transform.link); diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index 46b0bd2a0..ea8581b34 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -1,11 +1,12 @@ -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include struct wlr_output_layout_state { struct wlr_box _box; // should never be read directly, use the getter @@ -46,7 +47,7 @@ struct wlr_output_layout *wlr_output_layout_create() { static void wlr_output_layout_output_destroy( struct wlr_output_layout_output *l_output) { - wl_signal_emit(&l_output->events.destroy, l_output); + wlr_signal_emit_safe(&l_output->events.destroy, l_output); wl_list_remove(&l_output->state->mode.link); wl_list_remove(&l_output->state->scale.link); wl_list_remove(&l_output->state->transform.link); @@ -61,7 +62,7 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) { return; } - wl_signal_emit(&layout->events.destroy, layout); + wlr_signal_emit_safe(&layout->events.destroy, layout); struct wlr_output_layout_output *l_output, *temp = NULL; wl_list_for_each_safe(l_output, temp, &layout->outputs, link) { @@ -129,7 +130,7 @@ static void wlr_output_layout_reconfigure(struct wlr_output_layout *layout) { wlr_output_set_position(l_output->output, l_output->x, l_output->y); } - wl_signal_emit(&layout->events.change, layout); + wlr_signal_emit_safe(&layout->events.change, layout); } static void handle_output_mode(struct wl_listener *listener, void *data) { @@ -204,7 +205,7 @@ void wlr_output_layout_add(struct wlr_output_layout *layout, l_output->state->auto_configured = false; wlr_output_layout_reconfigure(layout); wlr_output_create_global(output); - wl_signal_emit(&layout->events.add, l_output); + wlr_signal_emit_safe(&layout->events.add, l_output); } struct wlr_output_layout_output *wlr_output_layout_get( @@ -401,7 +402,7 @@ void wlr_output_layout_add_auto(struct wlr_output_layout *layout, l_output->state->auto_configured = true; wlr_output_layout_reconfigure(layout); wlr_output_create_global(output); - wl_signal_emit(&layout->events.add, l_output); + wlr_signal_emit_safe(&layout->events.add, l_output); } struct wlr_output *wlr_output_layout_get_center_output( diff --git a/types/wlr_primary_selection.c b/types/wlr_primary_selection.c index fafde669b..7eb5d97a5 100644 --- a/types/wlr_primary_selection.c +++ b/types/wlr_primary_selection.c @@ -7,6 +7,7 @@ #include #include #include +#include static void offer_handle_receive(struct wl_client *client, struct wl_resource *resource, const char *mime_type, int32_t fd) { @@ -195,7 +196,7 @@ static void seat_client_primary_selection_source_destroy( seat->primary_selection_source = NULL; - wl_signal_emit(&seat->events.primary_selection, seat); + wlr_signal_emit_safe(&seat->events.primary_selection, seat); } void wlr_seat_set_primary_selection(struct wlr_seat *seat, @@ -225,7 +226,7 @@ void wlr_seat_set_primary_selection(struct wlr_seat *seat, wlr_seat_client_send_primary_selection(focused_client); } - wl_signal_emit(&seat->events.primary_selection, seat); + wlr_signal_emit_safe(&seat->events.primary_selection, seat); if (source) { seat->primary_selection_source_destroy.notify = @@ -278,7 +279,7 @@ void wlr_primary_selection_source_finish( return; } - wl_signal_emit(&source->events.destroy, source); + wlr_signal_emit_safe(&source->events.destroy, source); char **p; wl_array_for_each(p, &source->mime_types) { diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 79c4f6f69..b9d8b1b8a 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -49,7 +50,7 @@ static void wl_pointer_set_cursor(struct wl_client *client, event->hotspot_x = hotspot_x; event->hotspot_y = hotspot_y; - wl_signal_emit(&seat_client->seat->events.request_set_cursor, event); + wlr_signal_emit_safe(&seat_client->seat->events.request_set_cursor, event); free(event); } @@ -177,7 +178,7 @@ static void wl_seat_get_touch(struct wl_client *client, static void wlr_seat_client_resource_destroy(struct wl_resource *seat_resource) { struct wlr_seat_client *client = wl_resource_get_user_data(seat_resource); - wl_signal_emit(&client->events.destroy, client); + wlr_signal_emit_safe(&client->events.destroy, client); if (client == client->seat->pointer_state.focused_client) { client->seat->pointer_state.focused_client = NULL; @@ -350,7 +351,7 @@ void wlr_seat_destroy(struct wlr_seat *seat) { return; } - wl_signal_emit(&seat->events.destroy, seat); + wlr_signal_emit_safe(&seat->events.destroy, seat); wl_list_remove(&seat->display_destroy.link); @@ -656,14 +657,14 @@ void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat, assert(grab->seat); wlr_seat->pointer_state.grab = grab; - wl_signal_emit(&wlr_seat->events.pointer_grab_begin, grab); + wlr_signal_emit_safe(&wlr_seat->events.pointer_grab_begin, grab); } void wlr_seat_pointer_end_grab(struct wlr_seat *wlr_seat) { struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab; if (grab != wlr_seat->pointer_state.default_grab) { wlr_seat->pointer_state.grab = wlr_seat->pointer_state.default_grab; - wl_signal_emit(&wlr_seat->events.pointer_grab_end, grab); + wlr_signal_emit_safe(&wlr_seat->events.pointer_grab_end, grab); if (grab->interface->cancel) { grab->interface->cancel(grab); } @@ -812,7 +813,7 @@ void wlr_seat_keyboard_start_grab(struct wlr_seat *wlr_seat, grab->seat = wlr_seat; wlr_seat->keyboard_state.grab = grab; - wl_signal_emit(&wlr_seat->events.keyboard_grab_begin, grab); + wlr_signal_emit_safe(&wlr_seat->events.keyboard_grab_begin, grab); } void wlr_seat_keyboard_end_grab(struct wlr_seat *wlr_seat) { @@ -820,7 +821,7 @@ void wlr_seat_keyboard_end_grab(struct wlr_seat *wlr_seat) { if (grab != wlr_seat->keyboard_state.default_grab) { wlr_seat->keyboard_state.grab = wlr_seat->keyboard_state.default_grab; - wl_signal_emit(&wlr_seat->events.keyboard_grab_end, grab); + wlr_signal_emit_safe(&wlr_seat->events.keyboard_grab_end, grab); if (grab->interface->cancel) { grab->interface->cancel(grab); } @@ -979,7 +980,7 @@ void wlr_seat_touch_start_grab(struct wlr_seat *wlr_seat, grab->seat = wlr_seat; wlr_seat->touch_state.grab = grab; - wl_signal_emit(&wlr_seat->events.touch_grab_begin, grab); + wlr_signal_emit_safe(&wlr_seat->events.touch_grab_begin, grab); } void wlr_seat_touch_end_grab(struct wlr_seat *wlr_seat) { @@ -987,7 +988,7 @@ void wlr_seat_touch_end_grab(struct wlr_seat *wlr_seat) { if (grab != wlr_seat->touch_state.default_grab) { wlr_seat->touch_state.grab = wlr_seat->touch_state.default_grab; - wl_signal_emit(&wlr_seat->events.touch_grab_end, grab); + wlr_signal_emit_safe(&wlr_seat->events.touch_grab_end, grab); if (grab->interface->cancel) { grab->interface->cancel(grab); } @@ -1003,7 +1004,7 @@ static void touch_point_clear_focus(struct wlr_touch_point *point) { } static void touch_point_destroy(struct wlr_touch_point *point) { - wl_signal_emit(&point->events.destroy, point); + wlr_signal_emit_safe(&point->events.destroy, point); touch_point_clear_focus(point); wl_list_remove(&point->surface_destroy.link); diff --git a/types/wlr_server_decoration.c b/types/wlr_server_decoration.c index 09909bb62..f648cce72 100644 --- a/types/wlr_server_decoration.c +++ b/types/wlr_server_decoration.c @@ -4,6 +4,7 @@ #include #include #include +#include static void server_decoration_handle_release(struct wl_client *client, struct wl_resource *resource) { @@ -18,14 +19,14 @@ static void server_decoration_handle_request_mode(struct wl_client *client, return; } decoration->mode = mode; - wl_signal_emit(&decoration->events.mode, decoration); + wlr_signal_emit_safe(&decoration->events.mode, decoration); org_kde_kwin_server_decoration_send_mode(decoration->resource, decoration->mode); } static void server_decoration_destroy( struct wlr_server_decoration *decoration) { - wl_signal_emit(&decoration->events.destroy, decoration); + wlr_signal_emit_safe(&decoration->events.destroy, decoration); wl_list_remove(&decoration->surface_destroy_listener.link); wl_resource_set_user_data(decoration->resource, NULL); wl_list_remove(&decoration->link); @@ -97,7 +98,7 @@ static void server_decoration_manager_handle_create(struct wl_client *client, org_kde_kwin_server_decoration_send_mode(decoration->resource, decoration->mode); - wl_signal_emit(&manager->events.new_decoration, decoration); + wlr_signal_emit_safe(&manager->events.new_decoration, decoration); } static const struct org_kde_kwin_server_decoration_manager_interface diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 045e3670a..e430339b0 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -395,7 +396,7 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) { } // TODO: add the invalid bitfield to this callback - wl_signal_emit(&surface->events.commit, surface); + wlr_signal_emit_safe(&surface->events.commit, surface); pixman_region32_clear(&surface->current->surface_damage); pixman_region32_clear(&surface->current->buffer_damage); @@ -559,7 +560,7 @@ static void wlr_surface_state_destroy(struct wlr_surface_state *state) { } void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) { - wl_signal_emit(&subsurface->events.destroy, subsurface); + wlr_signal_emit_safe(&subsurface->events.destroy, subsurface); wlr_surface_state_destroy(subsurface->cached); @@ -578,7 +579,7 @@ void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) { static void destroy_surface(struct wl_resource *resource) { struct wlr_surface *surface = wl_resource_get_user_data(resource); - wl_signal_emit(&surface->events.destroy, surface); + wlr_signal_emit_safe(&surface->events.destroy, surface); if (surface->subsurface) { wlr_subsurface_destroy(surface->subsurface); @@ -831,7 +832,7 @@ void wlr_surface_make_subsurface(struct wlr_surface *surface, surface->subsurface = subsurface; - wl_signal_emit(&parent->events.new_subsurface, subsurface); + wlr_signal_emit_safe(&parent->events.new_subsurface, subsurface); } diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index dd6514df7..0c4e01fdb 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -1,12 +1,13 @@ #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #endif +#include #include #include #include +#include #include #include -#include #include static const char *wlr_wl_shell_surface_role = "wl-shell-surface"; @@ -123,7 +124,7 @@ static void shell_surface_protocol_move(struct wl_client *client, .serial = serial, }; - wl_signal_emit(&surface->events.request_move, &event); + wlr_signal_emit_safe(&surface->events.request_move, &event); } static struct wlr_wl_shell_popup_grab *shell_popup_grab_from_seat( @@ -187,7 +188,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, .edges = edges, }; - wl_signal_emit(&surface->events.request_resize, &event); + wlr_signal_emit_safe(&surface->events.request_resize, &event); } static void shell_surface_set_state(struct wlr_wl_shell_surface *surface, @@ -200,7 +201,7 @@ static void shell_surface_set_state(struct wlr_wl_shell_surface *surface, shell_surface_destroy_popup_state(surface); surface->popup_state = popup_state; - wl_signal_emit(&surface->events.set_state, surface); + wlr_signal_emit_safe(&surface->events.set_state, surface); } static void shell_surface_protocol_set_toplevel(struct wl_client *client, @@ -221,7 +222,7 @@ static void shell_surface_popup_set_parent(struct wlr_wl_shell_surface *surface, if (parent) { wl_list_remove(&surface->popup_link); wl_list_insert(&parent->popups, &surface->popup_link); - wl_signal_emit(&parent->events.new_popup, surface); + wlr_signal_emit_safe(&parent->events.new_popup, surface); } } @@ -290,7 +291,7 @@ static void shell_surface_protocol_set_fullscreen(struct wl_client *client, .output = output, }; - wl_signal_emit(&surface->events.request_fullscreen, &event); + wlr_signal_emit_safe(&surface->events.request_fullscreen, &event); } static void shell_surface_protocol_set_popup(struct wl_client *client, @@ -368,7 +369,7 @@ static void shell_surface_protocol_set_maximized(struct wl_client *client, .output = output, }; - wl_signal_emit(&surface->events.request_maximize, &event); + wlr_signal_emit_safe(&surface->events.request_maximize, &event); } static void shell_surface_protocol_set_title(struct wl_client *client, @@ -384,7 +385,7 @@ static void shell_surface_protocol_set_title(struct wl_client *client, free(surface->title); surface->title = tmp; - wl_signal_emit(&surface->events.set_title, surface); + wlr_signal_emit_safe(&surface->events.set_title, surface); } static void shell_surface_protocol_set_class(struct wl_client *client, @@ -400,7 +401,7 @@ static void shell_surface_protocol_set_class(struct wl_client *client, free(surface->class); surface->class = tmp; - wl_signal_emit(&surface->events.set_class, surface); + wlr_signal_emit_safe(&surface->events.set_class, surface); } static const struct wl_shell_surface_interface shell_surface_impl = { @@ -417,7 +418,7 @@ static const struct wl_shell_surface_interface shell_surface_impl = { }; static void shell_surface_destroy(struct wlr_wl_shell_surface *surface) { - wl_signal_emit(&surface->events.destroy, surface); + wlr_signal_emit_safe(&surface->events.destroy, surface); shell_surface_destroy_popup_state(surface); wl_resource_set_user_data(surface->resource, NULL); @@ -457,7 +458,7 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface, wlr_surface_has_buffer(surface->surface) && surface->state != WLR_WL_SHELL_SURFACE_STATE_NONE) { surface->configured = true; - wl_signal_emit(&surface->shell->events.new_surface, surface); + wlr_signal_emit_safe(&surface->shell->events.new_surface, surface); } if (surface->popup_mapped && @@ -473,7 +474,7 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface, static int shell_surface_ping_timeout(void *user_data) { struct wlr_wl_shell_surface *surface = user_data; - wl_signal_emit(&surface->events.ping_timeout, surface); + wlr_signal_emit_safe(&surface->events.ping_timeout, surface); surface->ping_serial = 0; return 1; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 5c820edc1..b6eee8752 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "xdg-shell-unstable-v6-protocol.h" static const char *wlr_desktop_xdg_toplevel_role = "xdg_toplevel"; @@ -160,7 +161,7 @@ static struct wlr_xdg_popup_grab_v6 *xdg_shell_popup_grab_from_seat( static void xdg_surface_destroy(struct wlr_xdg_surface_v6 *surface) { // TODO: probably need to ungrab before this event - wl_signal_emit(&surface->events.destroy, surface); + wlr_signal_emit_safe(&surface->events.destroy, surface); if (surface->configure_idle) { wl_event_source_remove(surface->configure_idle); @@ -511,7 +512,7 @@ static void xdg_surface_get_popup(struct wl_client *client, &zxdg_popup_v6_implementation, surface, xdg_popup_resource_destroy); - wl_signal_emit(&parent->events.new_popup, surface->popup_state); + wlr_signal_emit_safe(&parent->events.new_popup, surface->popup_state); } @@ -582,7 +583,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, .y = y, }; - wl_signal_emit(&surface->events.request_show_window_menu, &event); + wlr_signal_emit_safe(&surface->events.request_show_window_menu, &event); } static void xdg_toplevel_protocol_move(struct wl_client *client, @@ -610,7 +611,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, .serial = serial, }; - wl_signal_emit(&surface->events.request_move, &event); + wlr_signal_emit_safe(&surface->events.request_move, &event); } static void xdg_toplevel_protocol_resize(struct wl_client *client, @@ -639,7 +640,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, .edges = edges, }; - wl_signal_emit(&surface->events.request_resize, &event); + wlr_signal_emit_safe(&surface->events.request_resize, &event); } static void xdg_toplevel_protocol_set_max_size(struct wl_client *client, @@ -660,14 +661,14 @@ static void xdg_toplevel_protocol_set_maximized(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.maximized = true; - wl_signal_emit(&surface->events.request_maximize, surface); + wlr_signal_emit_safe(&surface->events.request_maximize, surface); } static void xdg_toplevel_protocol_unset_maximized(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.maximized = false; - wl_signal_emit(&surface->events.request_maximize, surface); + wlr_signal_emit_safe(&surface->events.request_maximize, surface); } static void xdg_toplevel_protocol_set_fullscreen(struct wl_client *client, @@ -687,7 +688,7 @@ static void xdg_toplevel_protocol_set_fullscreen(struct wl_client *client, .output = output, }; - wl_signal_emit(&surface->events.request_fullscreen, &event); + wlr_signal_emit_safe(&surface->events.request_fullscreen, &event); } static void xdg_toplevel_protocol_unset_fullscreen(struct wl_client *client, @@ -702,13 +703,13 @@ static void xdg_toplevel_protocol_unset_fullscreen(struct wl_client *client, .output = NULL, }; - wl_signal_emit(&surface->events.request_fullscreen, &event); + wlr_signal_emit_safe(&surface->events.request_fullscreen, &event); } static void xdg_toplevel_protocol_set_minimized(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - wl_signal_emit(&surface->events.request_minimize, surface); + wlr_signal_emit_safe(&surface->events.request_minimize, surface); } static const struct zxdg_toplevel_v6_interface zxdg_toplevel_v6_implementation = @@ -1123,7 +1124,7 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface, if (surface->configured && !surface->added) { surface->added = true; - wl_signal_emit(&surface->client->shell->events.new_surface, surface); + wlr_signal_emit_safe(&surface->client->shell->events.new_surface, surface); } } @@ -1243,7 +1244,7 @@ static int wlr_xdg_client_v6_ping_timeout(void *user_data) { struct wlr_xdg_surface_v6 *surface; wl_list_for_each(surface, &client->surfaces, link) { - wl_signal_emit(&surface->events.ping_timeout, surface); + wlr_signal_emit_safe(&surface->events.ping_timeout, surface); } client->ping_serial = 0; diff --git a/util/meson.build b/util/meson.build index 34aa428b5..adc52a53c 100644 --- a/util/meson.build +++ b/util/meson.build @@ -4,6 +4,7 @@ lib_wlr_util = static_library( 'log.c', 'os-compatibility.c', 'region.c', + 'signal.c', ), include_directories: wlr_inc, dependencies: [wayland_server, pixman], diff --git a/util/signal.c b/util/signal.c new file mode 100644 index 000000000..91c4f571d --- /dev/null +++ b/util/signal.c @@ -0,0 +1,34 @@ +#include + +static void handle_noop(struct wl_listener *listener, void *data) { + // Do nothing +} + +void wlr_signal_emit_safe(struct wl_signal *signal, void *data) { + struct wl_listener cursor; + struct wl_listener end; + + /* Add two special markers: one cursor and one end marker. This way, we know + * that we've already called listeners on the left of the cursor and that we + * don't want to call listeners on the right of the end marker. The 'it' + * function can remove any element it wants from the list without troubles. + * wl_list_for_each_safe tries to be safe but it fails: it works fine + * if the current item is removed, but not if the next one is. */ + wl_list_insert(&signal->listener_list, &cursor.link); + cursor.notify = handle_noop; + wl_list_insert(signal->listener_list.prev, &end.link); + end.notify = handle_noop; + + while (cursor.link.next != &end.link) { + struct wl_list *pos = cursor.link.next; + struct wl_listener *l = wl_container_of(pos, l, link); + + wl_list_remove(&cursor.link); + wl_list_insert(pos, &cursor.link); + + l->notify(l, data); + } + + wl_list_remove(&cursor.link); + wl_list_remove(&end.link); +} diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 6c700cc55..7c57b6c0e 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -16,8 +16,9 @@ #include #include #include -#include "wlr/util/log.h" -#include "wlr/xwayland.h" +#include +#include +#include #include "sockets.h" #include "wlr/xwm.h" @@ -237,7 +238,7 @@ static int xserver_handle_ready(int signal_number, void *data) { snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display); setenv("DISPLAY", display_name, true); - wl_signal_emit(&wlr_xwayland->events.ready, wlr_xwayland); + wlr_signal_emit_safe(&wlr_xwayland->events.ready, wlr_xwayland); /* ready is a one-shot signal, fire and forget */ wl_signal_init(&wlr_xwayland->events.ready); diff --git a/xwayland/xwm.c b/xwayland/xwm.c index e59c6e660..86d8bde78 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -8,12 +8,13 @@ #include #include #include -#include "wlr/util/log.h" -#include "wlr/util/edges.h" -#include "wlr/types/wlr_surface.h" -#include "wlr/xwayland.h" -#include "wlr/xcursor.h" -#include "wlr/xwm.h" +#include +#include +#include +#include +#include +#include +#include #ifdef WLR_HAS_XCB_ICCCM #include @@ -210,7 +211,7 @@ static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) { static void wlr_xwayland_surface_destroy( struct wlr_xwayland_surface *xsurface) { - wl_signal_emit(&xsurface->events.destroy, xsurface); + wlr_signal_emit_safe(&xsurface->events.destroy, xsurface); if (xsurface == xsurface->xwm->focus_surface) { xwm_surface_activate(xsurface->xwm, NULL); @@ -266,7 +267,7 @@ static void read_surface_class(struct wlr_xwm *xwm, wlr_log(L_DEBUG, "XCB_ATOM_WM_CLASS: %s %s", surface->instance, surface->class); - wl_signal_emit(&surface->events.set_class, surface); + wlr_signal_emit_safe(&surface->events.set_class, surface); } static void read_surface_title(struct wlr_xwm *xwm, @@ -291,7 +292,7 @@ static void read_surface_title(struct wlr_xwm *xwm, } wlr_log(L_DEBUG, "XCB_ATOM_WM_NAME: %s", xsurface->title); - wl_signal_emit(&xsurface->events.set_title, xsurface); + wlr_signal_emit_safe(&xsurface->events.set_title, xsurface); } static void read_surface_parent(struct wlr_xwm *xwm, @@ -316,7 +317,7 @@ static void read_surface_parent(struct wlr_xwm *xwm, } wlr_log(L_DEBUG, "XCB_ATOM_WM_TRANSIENT_FOR: %p", xsurface->parent); - wl_signal_emit(&xsurface->events.set_parent, xsurface); + wlr_signal_emit_safe(&xsurface->events.set_parent, xsurface); } static void read_surface_pid(struct wlr_xwm *xwm, @@ -329,7 +330,7 @@ static void read_surface_pid(struct wlr_xwm *xwm, pid_t *pid = xcb_get_property_value(reply); xsurface->pid = *pid; wlr_log(L_DEBUG, "NET_WM_PID %d", xsurface->pid); - wl_signal_emit(&xsurface->events.set_pid, xsurface); + wlr_signal_emit_safe(&xsurface->events.set_pid, xsurface); } static void read_surface_window_type(struct wlr_xwm *xwm, @@ -352,7 +353,7 @@ static void read_surface_window_type(struct wlr_xwm *xwm, xsurface->window_type_len = atoms_len; wlr_log(L_DEBUG, "NET_WM_WINDOW_TYPE (%zu)", atoms_len); - wl_signal_emit(&xsurface->events.set_window_type, xsurface); + wlr_signal_emit_safe(&xsurface->events.set_window_type, xsurface); } static void read_surface_protocols(struct wlr_xwm *xwm, @@ -535,7 +536,7 @@ static void handle_surface_commit(struct wlr_surface *wlr_surface, if (!xsurface->added && wlr_surface_has_buffer(xsurface->surface) && xsurface->mapped) { - wl_signal_emit(&xsurface->xwm->xwayland->events.new_surface, xsurface); + wlr_signal_emit_safe(&xsurface->xwm->xwayland->events.new_surface, xsurface); xsurface->added = true; } } @@ -578,7 +579,7 @@ static void xwm_map_shell_surface(struct wlr_xwm *xwm, wl_signal_add(&surface->events.destroy, &xsurface->surface_destroy); xsurface->mapped = true; - wl_signal_emit(&xsurface->events.map_notify, xsurface); + wlr_signal_emit_safe(&xsurface->events.map_notify, xsurface); } static void xwm_handle_create_notify(struct wlr_xwm *xwm, @@ -626,7 +627,7 @@ static void xwm_handle_configure_request(struct wlr_xwm *xwm, wlr_event->width = ev->width; wlr_event->height = ev->height; - wl_signal_emit(&xsurface->events.request_configure, wlr_event); + wlr_signal_emit_safe(&xsurface->events.request_configure, wlr_event); free(wlr_event); } @@ -710,7 +711,7 @@ static void xwm_handle_unmap_notify(struct wlr_xwm *xwm, if (xsurface->mapped) { xsurface->mapped = false; - wl_signal_emit(&xsurface->events.unmap_notify, xsurface); + wlr_signal_emit_safe(&xsurface->events.unmap_notify, xsurface); } xsurface_set_wm_state(xsurface, ICCCM_WITHDRAWN_STATE); @@ -814,7 +815,7 @@ static void xwm_handle_net_wm_moveresize_message(struct wlr_xwm *xwm, switch (detail) { case _NET_WM_MOVERESIZE_MOVE: move_event.surface = xsurface; - wl_signal_emit(&xsurface->events.request_move, &move_event); + wlr_signal_emit_safe(&xsurface->events.request_move, &move_event); break; case _NET_WM_MOVERESIZE_SIZE_TOPLEFT: case _NET_WM_MOVERESIZE_SIZE_TOP: @@ -826,7 +827,7 @@ static void xwm_handle_net_wm_moveresize_message(struct wlr_xwm *xwm, case _NET_WM_MOVERESIZE_SIZE_LEFT: resize_event.surface = xsurface; resize_event.edges = net_wm_edges_to_wlr(detail); - wl_signal_emit(&xsurface->events.request_resize, &resize_event); + wlr_signal_emit_safe(&xsurface->events.request_resize, &resize_event); break; case _NET_WM_MOVERESIZE_CANCEL: // handled by the compositor @@ -904,7 +905,7 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm, xsurface->saved_height = xsurface->height; } - wl_signal_emit(&xsurface->events.request_fullscreen, xsurface); + wlr_signal_emit_safe(&xsurface->events.request_fullscreen, xsurface); } if (maximized != xsurface_is_maximized(xsurface)) { @@ -913,7 +914,7 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm, xsurface->saved_height = xsurface->height; } - wl_signal_emit(&xsurface->events.request_maximize, xsurface); + wlr_signal_emit_safe(&xsurface->events.request_maximize, xsurface); } }