mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-23 02:19:49 +01:00
Merge pull request #468 from emersion/display-destroy
Use destroy listeners on wl_display
This commit is contained in:
commit
46ac8e1243
36 changed files with 446 additions and 199 deletions
|
@ -34,6 +34,10 @@ static void wlr_drm_backend_destroy(struct wlr_backend *backend) {
|
|||
wlr_output_destroy(&conn->output);
|
||||
}
|
||||
|
||||
wl_list_remove(&drm->display_destroy.link);
|
||||
wl_list_remove(&drm->session_signal.link);
|
||||
wl_list_remove(&drm->drm_invalidated.link);
|
||||
|
||||
wlr_drm_resources_free(drm);
|
||||
wlr_drm_renderer_finish(&drm->renderer);
|
||||
wlr_session_close_file(drm->session, drm->fd);
|
||||
|
@ -57,7 +61,8 @@ bool wlr_backend_is_drm(struct wlr_backend *b) {
|
|||
}
|
||||
|
||||
static void session_signal(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend *drm = wl_container_of(listener, drm, session_signal);
|
||||
struct wlr_drm_backend *drm =
|
||||
wl_container_of(listener, drm, session_signal);
|
||||
struct wlr_session *session = data;
|
||||
|
||||
if (session->active) {
|
||||
|
@ -84,7 +89,8 @@ static void session_signal(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
static void drm_invalidated(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend *drm = wl_container_of(listener, drm, drm_invalidated);
|
||||
struct wlr_drm_backend *drm =
|
||||
wl_container_of(listener, drm, drm_invalidated);
|
||||
|
||||
char *name = drmGetDeviceNameFromFd2(drm->fd);
|
||||
wlr_log(L_DEBUG, "%s invalidated", name);
|
||||
|
@ -93,6 +99,12 @@ static void drm_invalidated(struct wl_listener *listener, void *data) {
|
|||
wlr_drm_scan_connectors(drm);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend *drm =
|
||||
wl_container_of(listener, drm, display_destroy);
|
||||
wlr_drm_backend_destroy(&drm->backend);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||
struct wlr_session *session, int gpu_fd, struct wlr_backend *parent) {
|
||||
assert(display && session && gpu_fd >= 0);
|
||||
|
@ -150,6 +162,9 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
|||
wlr_log(L_INFO, "Failed to bind egl/wl display: %s", egl_error());
|
||||
}
|
||||
|
||||
drm->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &drm->display_destroy);
|
||||
|
||||
return &drm->backend;
|
||||
|
||||
error_event:
|
||||
|
|
|
@ -39,7 +39,7 @@ bool wlr_drm_renderer_init(struct wlr_drm_backend *drm,
|
|||
return true;
|
||||
|
||||
error_egl:
|
||||
wlr_egl_free(&renderer->egl);
|
||||
wlr_egl_finish(&renderer->egl);
|
||||
error_gbm:
|
||||
gbm_device_destroy(renderer->gbm);
|
||||
return false;
|
||||
|
@ -51,7 +51,7 @@ void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer) {
|
|||
}
|
||||
|
||||
wlr_renderer_destroy(renderer->wlr_rend);
|
||||
wlr_egl_free(&renderer->egl);
|
||||
wlr_egl_finish(&renderer->egl);
|
||||
gbm_device_destroy(renderer->gbm);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,12 @@ static void wlr_libinput_log(struct libinput *libinput_context,
|
|||
}
|
||||
|
||||
static bool wlr_libinput_backend_start(struct wlr_backend *_backend) {
|
||||
struct wlr_libinput_backend *backend = (struct wlr_libinput_backend *)_backend;
|
||||
struct wlr_libinput_backend *backend =
|
||||
(struct wlr_libinput_backend *)_backend;
|
||||
wlr_log(L_DEBUG, "Initializing libinput");
|
||||
backend->libinput_context = libinput_udev_create_context(&libinput_impl, backend,
|
||||
backend->session->udev);
|
||||
|
||||
backend->libinput_context = libinput_udev_create_context(&libinput_impl,
|
||||
backend, backend->session->udev);
|
||||
if (!backend->libinput_context) {
|
||||
wlr_log(L_ERROR, "Failed to create libinput context");
|
||||
return false;
|
||||
|
@ -99,6 +101,7 @@ static void wlr_libinput_backend_destroy(struct wlr_backend *_backend) {
|
|||
}
|
||||
struct wlr_libinput_backend *backend =
|
||||
(struct wlr_libinput_backend *)_backend;
|
||||
|
||||
for (size_t i = 0; i < backend->wlr_device_lists.length; i++) {
|
||||
struct wl_list *wlr_devices = backend->wlr_device_lists.items[i];
|
||||
struct wlr_input_device *wlr_dev, *next;
|
||||
|
@ -108,6 +111,10 @@ static void wlr_libinput_backend_destroy(struct wlr_backend *_backend) {
|
|||
}
|
||||
free(wlr_devices);
|
||||
}
|
||||
|
||||
wl_list_remove(&backend->display_destroy.link);
|
||||
wl_list_remove(&backend->session_signal.link);
|
||||
|
||||
wlr_list_finish(&backend->wlr_device_lists);
|
||||
wl_event_source_remove(backend->input_event);
|
||||
libinput_unref(backend->libinput_context);
|
||||
|
@ -124,7 +131,8 @@ bool wlr_backend_is_libinput(struct wlr_backend *b) {
|
|||
}
|
||||
|
||||
static void session_signal(struct wl_listener *listener, void *data) {
|
||||
struct wlr_libinput_backend *backend = wl_container_of(listener, backend, session_signal);
|
||||
struct wlr_libinput_backend *backend =
|
||||
wl_container_of(listener, backend, session_signal);
|
||||
struct wlr_session *session = data;
|
||||
|
||||
if (!backend->libinput_context) {
|
||||
|
@ -138,6 +146,12 @@ static void session_signal(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_libinput_backend *backend =
|
||||
wl_container_of(listener, backend, display_destroy);
|
||||
wlr_libinput_backend_destroy(&backend->backend);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display,
|
||||
struct wlr_session *session) {
|
||||
assert(display && session);
|
||||
|
@ -160,6 +174,9 @@ struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display,
|
|||
backend->session_signal.notify = session_signal;
|
||||
wl_signal_add(&session->session_signal, &backend->session_signal);
|
||||
|
||||
backend->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &backend->display_destroy);
|
||||
|
||||
return &backend->backend;
|
||||
error_backend:
|
||||
free(backend);
|
||||
|
|
|
@ -35,7 +35,6 @@ static void multi_backend_destroy(struct wlr_backend *_backend) {
|
|||
wlr_backend_destroy(sub->backend);
|
||||
free(sub);
|
||||
}
|
||||
wlr_session_destroy(backend->session);
|
||||
free(backend);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,12 @@ out:
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_session *session =
|
||||
wl_container_of(listener, session, display_destroy);
|
||||
wlr_session_destroy(session);
|
||||
}
|
||||
|
||||
struct wlr_session *wlr_session_create(struct wl_display *disp) {
|
||||
struct wlr_session *session = NULL;
|
||||
const struct session_impl **iter;
|
||||
|
@ -100,6 +106,9 @@ struct wlr_session *wlr_session_create(struct wl_display *disp) {
|
|||
goto error_mon;
|
||||
}
|
||||
|
||||
session->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(disp, &session->display_destroy);
|
||||
|
||||
return session;
|
||||
|
||||
error_mon:
|
||||
|
@ -107,7 +116,7 @@ error_mon:
|
|||
error_udev:
|
||||
udev_unref(session->udev);
|
||||
error_session:
|
||||
wlr_session_destroy(session);
|
||||
session->impl->destroy(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -116,6 +125,8 @@ void wlr_session_destroy(struct wlr_session *session) {
|
|||
return;
|
||||
}
|
||||
|
||||
wl_list_remove(&session->display_destroy.link);
|
||||
|
||||
wl_event_source_remove(session->udev_event);
|
||||
udev_monitor_unref(session->mon);
|
||||
udev_unref(session->udev);
|
||||
|
|
|
@ -79,10 +79,12 @@ static void wlr_wl_backend_destroy(struct wlr_backend *_backend) {
|
|||
wlr_input_device_destroy(input_device);
|
||||
}
|
||||
|
||||
wl_list_remove(&backend->local_display_destroy.link);
|
||||
|
||||
free(backend->seat_name);
|
||||
|
||||
wl_event_source_remove(backend->remote_display_src);
|
||||
wlr_egl_free(&backend->egl);
|
||||
wlr_egl_finish(&backend->egl);
|
||||
if (backend->seat) wl_seat_destroy(backend->seat);
|
||||
if (backend->shm) wl_shm_destroy(backend->shm);
|
||||
if (backend->shell) zxdg_shell_v6_destroy(backend->shell);
|
||||
|
@ -150,6 +152,12 @@ void wlr_wl_output_layout_get_box(struct wlr_wl_backend *backend,
|
|||
box->height = max_y - min_y;
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_wl_backend *backend =
|
||||
wl_container_of(listener, backend, local_display_destroy);
|
||||
wlr_wl_backend_destroy(&backend->backend);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_wl_backend_create(struct wl_display *display) {
|
||||
wlr_log(L_INFO, "Creating wayland backend");
|
||||
|
||||
|
@ -176,8 +184,12 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display) {
|
|||
return false;
|
||||
}
|
||||
|
||||
wlr_egl_init(&backend->egl, EGL_PLATFORM_WAYLAND_EXT, WL_SHM_FORMAT_ARGB8888, backend->remote_display);
|
||||
wlr_egl_init(&backend->egl, EGL_PLATFORM_WAYLAND_EXT,
|
||||
WL_SHM_FORMAT_ARGB8888, backend->remote_display);
|
||||
wlr_egl_bind_display(&backend->egl, backend->local_display);
|
||||
|
||||
backend->local_display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &backend->local_display_destroy);
|
||||
|
||||
return &backend->backend;
|
||||
}
|
||||
|
|
|
@ -183,69 +183,6 @@ static void init_atom(struct wlr_x11_backend *x11, struct wlr_x11_atom *atom,
|
|||
atom->reply = xcb_intern_atom_reply(x11->xcb_conn, atom->cookie, NULL);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
||||
const char *x11_display) {
|
||||
struct wlr_x11_backend *x11 = calloc(1, sizeof(*x11));
|
||||
if (!x11) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlr_backend_init(&x11->backend, &backend_impl);
|
||||
x11->wl_display = display;
|
||||
|
||||
x11->xlib_conn = XOpenDisplay(x11_display);
|
||||
if (!x11->xlib_conn) {
|
||||
wlr_log(L_ERROR, "Failed to open X connection");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
x11->xcb_conn = XGetXCBConnection(x11->xlib_conn);
|
||||
if (!x11->xcb_conn || xcb_connection_has_error(x11->xcb_conn)) {
|
||||
wlr_log(L_ERROR, "Failed to open xcb connection");
|
||||
goto error_x11;
|
||||
}
|
||||
|
||||
XSetEventQueueOwner(x11->xlib_conn, XCBOwnsEventQueue);
|
||||
|
||||
int fd = xcb_get_file_descriptor(x11->xcb_conn);
|
||||
struct wl_event_loop *ev = wl_display_get_event_loop(display);
|
||||
int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP;
|
||||
x11->event_source = wl_event_loop_add_fd(ev, fd, events, x11_event, x11);
|
||||
if (!x11->event_source) {
|
||||
wlr_log(L_ERROR, "Could not create event source");
|
||||
goto error_x11;
|
||||
}
|
||||
|
||||
x11->frame_timer = wl_event_loop_add_timer(ev, signal_frame, x11);
|
||||
|
||||
x11->screen = xcb_setup_roots_iterator(xcb_get_setup(x11->xcb_conn)).data;
|
||||
|
||||
if (!wlr_egl_init(&x11->egl, EGL_PLATFORM_X11_KHR,
|
||||
x11->screen->root_visual, x11->xlib_conn)) {
|
||||
goto error_event;
|
||||
}
|
||||
|
||||
wlr_input_device_init(&x11->keyboard_dev, WLR_INPUT_DEVICE_KEYBOARD,
|
||||
NULL, "X11 keyboard", 0, 0);
|
||||
wlr_keyboard_init(&x11->keyboard, NULL);
|
||||
x11->keyboard_dev.keyboard = &x11->keyboard;
|
||||
|
||||
wlr_input_device_init(&x11->pointer_dev, WLR_INPUT_DEVICE_POINTER,
|
||||
NULL, "X11 pointer", 0, 0);
|
||||
wlr_pointer_init(&x11->pointer, NULL);
|
||||
x11->pointer_dev.pointer = &x11->pointer;
|
||||
|
||||
return &x11->backend;
|
||||
|
||||
error_event:
|
||||
wl_event_source_remove(x11->event_source);
|
||||
error_x11:
|
||||
xcb_disconnect(x11->xcb_conn);
|
||||
XCloseDisplay(x11->xlib_conn);
|
||||
free(x11);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool wlr_x11_backend_start(struct wlr_backend *backend) {
|
||||
struct wlr_x11_backend *x11 = (struct wlr_x11_backend *)backend;
|
||||
struct wlr_x11_output *output = &x11->output;
|
||||
|
@ -306,8 +243,10 @@ static void wlr_x11_backend_destroy(struct wlr_backend *backend) {
|
|||
struct wlr_x11_output *output = &x11->output;
|
||||
wlr_output_destroy(&output->wlr_output);
|
||||
|
||||
wl_list_remove(&x11->display_destroy.link);
|
||||
|
||||
wl_event_source_remove(x11->frame_timer);
|
||||
wlr_egl_free(&x11->egl);
|
||||
wlr_egl_finish(&x11->egl);
|
||||
|
||||
xcb_disconnect(x11->xcb_conn);
|
||||
free(x11);
|
||||
|
@ -328,6 +267,78 @@ static struct wlr_backend_impl backend_impl = {
|
|||
.get_egl = wlr_x11_backend_get_egl,
|
||||
};
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_x11_backend *x11 =
|
||||
wl_container_of(listener, x11, display_destroy);
|
||||
wlr_x11_backend_destroy(&x11->backend);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
||||
const char *x11_display) {
|
||||
struct wlr_x11_backend *x11 = calloc(1, sizeof(*x11));
|
||||
if (!x11) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlr_backend_init(&x11->backend, &backend_impl);
|
||||
x11->wl_display = display;
|
||||
|
||||
x11->xlib_conn = XOpenDisplay(x11_display);
|
||||
if (!x11->xlib_conn) {
|
||||
wlr_log(L_ERROR, "Failed to open X connection");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
x11->xcb_conn = XGetXCBConnection(x11->xlib_conn);
|
||||
if (!x11->xcb_conn || xcb_connection_has_error(x11->xcb_conn)) {
|
||||
wlr_log(L_ERROR, "Failed to open xcb connection");
|
||||
goto error_x11;
|
||||
}
|
||||
|
||||
XSetEventQueueOwner(x11->xlib_conn, XCBOwnsEventQueue);
|
||||
|
||||
int fd = xcb_get_file_descriptor(x11->xcb_conn);
|
||||
struct wl_event_loop *ev = wl_display_get_event_loop(display);
|
||||
int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP;
|
||||
x11->event_source = wl_event_loop_add_fd(ev, fd, events, x11_event, x11);
|
||||
if (!x11->event_source) {
|
||||
wlr_log(L_ERROR, "Could not create event source");
|
||||
goto error_x11;
|
||||
}
|
||||
|
||||
x11->frame_timer = wl_event_loop_add_timer(ev, signal_frame, x11);
|
||||
|
||||
x11->screen = xcb_setup_roots_iterator(xcb_get_setup(x11->xcb_conn)).data;
|
||||
|
||||
if (!wlr_egl_init(&x11->egl, EGL_PLATFORM_X11_KHR,
|
||||
x11->screen->root_visual, x11->xlib_conn)) {
|
||||
goto error_event;
|
||||
}
|
||||
|
||||
wlr_input_device_init(&x11->keyboard_dev, WLR_INPUT_DEVICE_KEYBOARD,
|
||||
NULL, "X11 keyboard", 0, 0);
|
||||
wlr_keyboard_init(&x11->keyboard, NULL);
|
||||
x11->keyboard_dev.keyboard = &x11->keyboard;
|
||||
|
||||
wlr_input_device_init(&x11->pointer_dev, WLR_INPUT_DEVICE_POINTER,
|
||||
NULL, "X11 pointer", 0, 0);
|
||||
wlr_pointer_init(&x11->pointer, NULL);
|
||||
x11->pointer_dev.pointer = &x11->pointer;
|
||||
|
||||
x11->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &x11->display_destroy);
|
||||
|
||||
return &x11->backend;
|
||||
|
||||
error_event:
|
||||
wl_event_source_remove(x11->event_source);
|
||||
error_x11:
|
||||
xcb_disconnect(x11->xcb_conn);
|
||||
XCloseDisplay(x11->xlib_conn);
|
||||
free(x11);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool output_set_custom_mode(struct wlr_output *wlr_output, int32_t width,
|
||||
int32_t height, int32_t refresh) {
|
||||
struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output;
|
||||
|
|
|
@ -91,6 +91,7 @@ struct wlr_drm_backend {
|
|||
struct wl_display *display;
|
||||
struct wl_event_source *drm_event;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
struct wl_listener session_signal;
|
||||
struct wl_listener drm_invalidated;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ struct wlr_libinput_backend {
|
|||
struct libinput *libinput_context;
|
||||
struct wl_event_source *input_event;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
struct wl_listener session_signal;
|
||||
|
||||
struct wlr_list wlr_device_lists; // list of struct wl_list
|
||||
|
|
|
@ -22,6 +22,7 @@ struct wlr_wl_backend {
|
|||
struct wl_list outputs;
|
||||
struct wlr_egl egl;
|
||||
size_t requested_outputs;
|
||||
struct wl_listener local_display_destroy;
|
||||
/* remote state */
|
||||
struct wl_display *remote_display;
|
||||
struct wl_event_source *remote_display_src;
|
||||
|
|
|
@ -51,6 +51,8 @@ struct wlr_x11_backend {
|
|||
|
||||
// The time we last received an event
|
||||
xcb_timestamp_t time;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,6 +33,8 @@ struct wlr_session {
|
|||
struct wl_event_source *udev_event;
|
||||
|
||||
struct wl_list devices;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <stdbool.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
struct wlr_egl {
|
||||
EGLDisplay display;
|
||||
|
@ -27,7 +28,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, EGLint visual_id, void
|
|||
* Frees all related egl resources, makes the context not-current and
|
||||
* unbinds a bound wayland display.
|
||||
*/
|
||||
void wlr_egl_free(struct wlr_egl *egl);
|
||||
void wlr_egl_finish(struct wlr_egl *egl);
|
||||
|
||||
/**
|
||||
* Binds the given display to the egl instance.
|
||||
|
|
|
@ -9,7 +9,8 @@ struct wlr_compositor {
|
|||
struct wl_list wl_resources;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wl_list surfaces;
|
||||
struct wl_listener destroy_surface_listener;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
struct {
|
||||
struct wl_signal create_surface;
|
||||
|
@ -20,8 +21,4 @@ void wlr_compositor_destroy(struct wlr_compositor *wlr_compositor);
|
|||
struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
|
||||
struct wlr_renderer *renderer);
|
||||
|
||||
struct wlr_surface;
|
||||
void wl_compositor_surface_destroyed(struct wlr_compositor *wlr_compositor,
|
||||
struct wlr_surface *surface);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,8 @@ wlr_touch_grab_interface wlr_data_device_touch_drag_interface;
|
|||
|
||||
struct wlr_data_device_manager {
|
||||
struct wl_global *global;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
};
|
||||
|
||||
struct wlr_data_offer {
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
struct wlr_gamma_control_manager {
|
||||
struct wl_global *wl_global;
|
||||
struct wl_list controls; // list of wlr_gamma_control
|
||||
struct wl_list controls; // wlr_gamma_control::link
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
|
|
@ -77,6 +77,8 @@ struct wlr_output {
|
|||
// the output position in layout space reported to clients
|
||||
int32_t lx, ly;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
struct wlr_screenshooter {
|
||||
struct wl_global *wl_global;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wl_list screenshots; // wlr_screenshot::link
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
@ -12,6 +15,7 @@ struct wlr_screenshooter {
|
|||
struct wlr_screenshot {
|
||||
struct wl_resource *resource;
|
||||
struct wl_resource *output_resource;
|
||||
struct wl_list link;
|
||||
|
||||
struct wlr_output *output;
|
||||
struct wlr_screenshooter *screenshooter;
|
||||
|
|
|
@ -184,6 +184,7 @@ struct wlr_seat {
|
|||
struct wlr_seat_keyboard_state keyboard_state;
|
||||
struct wlr_seat_touch_state touch_state;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
struct wl_listener selection_data_source_destroy;
|
||||
|
||||
struct {
|
||||
|
|
|
@ -33,6 +33,8 @@ struct wlr_server_decoration_manager {
|
|||
|
||||
uint32_t default_mode; // enum wlr_server_decoration_manager_mode
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
struct {
|
||||
struct wl_signal new_decoration;
|
||||
} events;
|
||||
|
|
|
@ -12,6 +12,8 @@ struct wlr_wl_shell {
|
|||
struct wl_list popup_grabs;
|
||||
uint32_t ping_timeout;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
struct {
|
||||
struct wl_signal new_surface;
|
||||
} events;
|
||||
|
|
|
@ -11,6 +11,8 @@ struct wlr_xdg_shell_v6 {
|
|||
struct wl_list popup_grabs;
|
||||
uint32_t ping_timeout;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
struct {
|
||||
struct wl_signal new_surface;
|
||||
} events;
|
||||
|
|
|
@ -23,7 +23,8 @@ struct wlr_xwayland {
|
|||
time_t server_start;
|
||||
|
||||
struct wl_event_source *sigusr1_source;
|
||||
struct wl_listener destroy_listener;
|
||||
struct wl_listener client_destroy;
|
||||
struct wl_listener display_destroy;
|
||||
struct wlr_xwm *xwm;
|
||||
struct wlr_xwayland_cursor *cursor;
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ error:
|
|||
return false;
|
||||
}
|
||||
|
||||
void wlr_egl_free(struct wlr_egl *egl) {
|
||||
void wlr_egl_finish(struct wlr_egl *egl) {
|
||||
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (egl->wl_display && eglUnbindWaylandDisplayWL) {
|
||||
eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
|
||||
|
|
|
@ -51,6 +51,7 @@ int main(int argc, char **argv) {
|
|||
if (!wlr_backend_start(server.backend)) {
|
||||
wlr_log(L_ERROR, "Failed to start backend");
|
||||
wlr_backend_destroy(server.backend);
|
||||
wl_display_destroy(server.wl_display);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -69,5 +70,6 @@ int main(int argc, char **argv) {
|
|||
|
||||
wl_display_run(server.wl_display);
|
||||
wlr_backend_destroy(server.backend);
|
||||
wl_display_destroy(server.wl_display);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -78,6 +78,10 @@ static void wl_compositor_bind(struct wl_client *wl_client, void *data,
|
|||
}
|
||||
|
||||
void wlr_compositor_destroy(struct wlr_compositor *compositor) {
|
||||
if (compositor == NULL) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&compositor->display_destroy.link);
|
||||
wl_global_destroy(compositor->wl_global);
|
||||
free(compositor);
|
||||
}
|
||||
|
@ -151,6 +155,12 @@ static void subcompositor_bind(struct wl_client *client, void *data,
|
|||
compositor, NULL);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_compositor *compositor =
|
||||
wl_container_of(listener, compositor, display_destroy);
|
||||
wlr_compositor_destroy(compositor);
|
||||
}
|
||||
|
||||
struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
|
||||
struct wlr_renderer *renderer) {
|
||||
struct wlr_compositor *compositor =
|
||||
|
@ -162,7 +172,11 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
|
|||
|
||||
struct wl_global *compositor_global = wl_global_create(display,
|
||||
&wl_compositor_interface, 4, compositor, wl_compositor_bind);
|
||||
|
||||
if (!compositor_global) {
|
||||
wlr_log_errno(L_ERROR, "Could not allocate compositor global");
|
||||
free(compositor);
|
||||
return NULL;
|
||||
}
|
||||
compositor->wl_global = compositor_global;
|
||||
compositor->renderer = renderer;
|
||||
|
||||
|
@ -173,5 +187,8 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
|
|||
wl_list_init(&compositor->surfaces);
|
||||
wl_signal_init(&compositor->events.create_surface);
|
||||
|
||||
compositor->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &compositor->display_destroy);
|
||||
|
||||
return compositor;
|
||||
}
|
||||
|
|
|
@ -949,6 +949,21 @@ static void data_device_manager_bind(struct wl_client *client,
|
|||
NULL, NULL);
|
||||
}
|
||||
|
||||
void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) {
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&manager->display_destroy.link);
|
||||
wl_global_destroy(manager->global);
|
||||
free(manager);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_data_device_manager *manager =
|
||||
wl_container_of(listener, manager, display_destroy);
|
||||
wlr_data_device_manager_destroy(manager);
|
||||
}
|
||||
|
||||
struct wlr_data_device_manager *wlr_data_device_manager_create(
|
||||
struct wl_display *display) {
|
||||
struct wlr_data_device_manager *manager =
|
||||
|
@ -967,13 +982,8 @@ struct wlr_data_device_manager *wlr_data_device_manager_create(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
manager->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &manager->display_destroy);
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) {
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
wl_global_destroy(manager->global);
|
||||
free(manager);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ static void resource_destroy(struct wl_client *client,
|
|||
}
|
||||
|
||||
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);
|
||||
wl_list_remove(&gamma_control->output_destroy_listener.link);
|
||||
wl_resource_set_user_data(gamma_control->resource, NULL);
|
||||
|
@ -67,7 +70,7 @@ static const struct gamma_control_interface gamma_control_impl = {
|
|||
static void gamma_control_manager_get_gamma_control(struct wl_client *client,
|
||||
struct wl_resource *gamma_control_manager_resource, uint32_t id,
|
||||
struct wl_resource *output_resource) {
|
||||
struct wlr_gamma_control_manager *gamma_control_manager =
|
||||
struct wlr_gamma_control_manager *manager =
|
||||
wl_resource_get_user_data(gamma_control_manager_resource);
|
||||
struct wlr_output *output = wl_resource_get_user_data(output_resource);
|
||||
|
||||
|
@ -99,7 +102,7 @@ static void gamma_control_manager_get_gamma_control(struct wl_client *client,
|
|||
gamma_control->output_destroy_listener.notify =
|
||||
gamma_control_handle_output_destroy;
|
||||
|
||||
wl_list_insert(&gamma_control_manager->controls, &gamma_control->link);
|
||||
wl_list_insert(&manager->controls, &gamma_control->link);
|
||||
|
||||
gamma_control_send_gamma_size(gamma_control->resource,
|
||||
wlr_output_get_gamma_size(output));
|
||||
|
@ -111,8 +114,8 @@ static struct gamma_control_manager_interface gamma_control_manager_impl = {
|
|||
|
||||
static void gamma_control_manager_bind(struct wl_client *client, void *data,
|
||||
uint32_t version, uint32_t id) {
|
||||
struct wlr_gamma_control_manager *gamma_control_manager = data;
|
||||
assert(client && gamma_control_manager);
|
||||
struct wlr_gamma_control_manager *manager = data;
|
||||
assert(client && manager);
|
||||
|
||||
struct wl_resource *resource = wl_resource_create(client,
|
||||
&gamma_control_manager_interface, version, id);
|
||||
|
@ -121,41 +124,49 @@ static void gamma_control_manager_bind(struct wl_client *client, void *data,
|
|||
return;
|
||||
}
|
||||
wl_resource_set_implementation(resource, &gamma_control_manager_impl,
|
||||
gamma_control_manager, NULL);
|
||||
manager, NULL);
|
||||
}
|
||||
|
||||
void wlr_gamma_control_manager_destroy(
|
||||
struct wlr_gamma_control_manager *manager) {
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&manager->display_destroy.link);
|
||||
struct wlr_gamma_control *gamma_control, *tmp;
|
||||
wl_list_for_each_safe(gamma_control, tmp, &manager->controls, link) {
|
||||
gamma_control_destroy(gamma_control);
|
||||
}
|
||||
wl_global_destroy(manager->wl_global);
|
||||
free(manager);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_gamma_control_manager *manager =
|
||||
wl_container_of(listener, manager, display_destroy);
|
||||
wlr_gamma_control_manager_destroy(manager);
|
||||
}
|
||||
|
||||
struct wlr_gamma_control_manager *wlr_gamma_control_manager_create(
|
||||
struct wl_display *display) {
|
||||
struct wlr_gamma_control_manager *gamma_control_manager =
|
||||
struct wlr_gamma_control_manager *manager =
|
||||
calloc(1, sizeof(struct wlr_gamma_control_manager));
|
||||
if (!gamma_control_manager) {
|
||||
if (!manager) {
|
||||
return NULL;
|
||||
}
|
||||
struct wl_global *wl_global = wl_global_create(display,
|
||||
&gamma_control_manager_interface, 1, gamma_control_manager,
|
||||
&gamma_control_manager_interface, 1, manager,
|
||||
gamma_control_manager_bind);
|
||||
if (!wl_global) {
|
||||
free(gamma_control_manager);
|
||||
free(manager);
|
||||
return NULL;
|
||||
}
|
||||
gamma_control_manager->wl_global = wl_global;
|
||||
manager->wl_global = wl_global;
|
||||
|
||||
wl_list_init(&gamma_control_manager->controls);
|
||||
wl_list_init(&manager->controls);
|
||||
|
||||
return gamma_control_manager;
|
||||
}
|
||||
|
||||
void wlr_gamma_control_manager_destroy(
|
||||
struct wlr_gamma_control_manager *gamma_control_manager) {
|
||||
if (!gamma_control_manager) {
|
||||
return;
|
||||
}
|
||||
struct wlr_gamma_control *gamma_control, *tmp;
|
||||
wl_list_for_each_safe(gamma_control, tmp, &gamma_control_manager->controls,
|
||||
link) {
|
||||
gamma_control_destroy(gamma_control);
|
||||
}
|
||||
// TODO: this segfault (wl_display->registry_resource_list is not init)
|
||||
// wl_global_destroy(gamma_control_manager->wl_global);
|
||||
free(gamma_control_manager);
|
||||
manager->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &manager->display_destroy);
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
|
|
@ -112,6 +112,12 @@ static void wl_output_bind(struct wl_client *wl_client, void *data,
|
|||
wl_output_send_to_resource(wl_resource);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output =
|
||||
wl_container_of(listener, output, display_destroy);
|
||||
wlr_output_destroy_global(output);
|
||||
}
|
||||
|
||||
struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output,
|
||||
struct wl_display *display) {
|
||||
if (wlr_output->wl_global != NULL) {
|
||||
|
@ -120,6 +126,10 @@ struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output,
|
|||
struct wl_global *wl_global = wl_global_create(display,
|
||||
&wl_output_interface, 3, wlr_output, wl_output_bind);
|
||||
wlr_output->wl_global = wl_global;
|
||||
|
||||
wlr_output->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &wlr_output->display_destroy);
|
||||
|
||||
return wl_global;
|
||||
}
|
||||
|
||||
|
@ -127,6 +137,7 @@ void wlr_output_destroy_global(struct wlr_output *wlr_output) {
|
|||
if (wlr_output->wl_global == NULL) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&wlr_output->display_destroy.link);
|
||||
struct wl_resource *resource, *tmp;
|
||||
wl_resource_for_each_safe(resource, tmp, &wlr_output->wl_resources) {
|
||||
struct wl_list *link = wl_resource_get_link(resource);
|
||||
|
|
|
@ -26,6 +26,21 @@ struct screenshot_state {
|
|||
struct wl_listener frame_listener;
|
||||
};
|
||||
|
||||
static void screenshot_destroy(struct wlr_screenshot *screenshot) {
|
||||
wl_list_remove(&screenshot->link);
|
||||
wl_resource_set_user_data(screenshot->resource, NULL);
|
||||
free(screenshot);
|
||||
}
|
||||
|
||||
static void handle_screenshot_resource_destroy(
|
||||
struct wl_resource *screenshot_resource) {
|
||||
struct wlr_screenshot *screenshot =
|
||||
wl_resource_get_user_data(screenshot_resource);
|
||||
if (screenshot != NULL) {
|
||||
screenshot_destroy(screenshot);
|
||||
}
|
||||
}
|
||||
|
||||
static void output_frame_notify(struct wl_listener *listener, void *_data) {
|
||||
struct screenshot_state *state = wl_container_of(listener, state,
|
||||
frame_listener);
|
||||
|
@ -102,7 +117,8 @@ static void screenshooter_shoot(struct wl_client *client,
|
|||
return;
|
||||
}
|
||||
wl_resource_set_implementation(screenshot->resource, NULL, screenshot,
|
||||
NULL);
|
||||
handle_screenshot_resource_destroy);
|
||||
wl_list_insert(&screenshooter->screenshots, &screenshot->link);
|
||||
|
||||
wlr_log(L_DEBUG, "new screenshot %p (res %p)", screenshot,
|
||||
screenshot->resource);
|
||||
|
@ -144,6 +160,25 @@ static void screenshooter_bind(struct wl_client *wl_client, void *data,
|
|||
screenshooter, NULL);
|
||||
}
|
||||
|
||||
void wlr_screenshooter_destroy(struct wlr_screenshooter *screenshooter) {
|
||||
if (!screenshooter) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&screenshooter->display_destroy.link);
|
||||
struct wlr_screenshot *screenshot, *tmp;
|
||||
wl_list_for_each_safe(screenshot, tmp, &screenshooter->screenshots, link) {
|
||||
screenshot_destroy(screenshot);
|
||||
}
|
||||
wl_global_destroy(screenshooter->wl_global);
|
||||
free(screenshooter);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_screenshooter *screenshooter =
|
||||
wl_container_of(listener, screenshooter, display_destroy);
|
||||
wlr_screenshooter_destroy(screenshooter);
|
||||
}
|
||||
|
||||
struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display,
|
||||
struct wlr_renderer *renderer) {
|
||||
struct wlr_screenshooter *screenshooter =
|
||||
|
@ -153,6 +188,11 @@ struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display,
|
|||
}
|
||||
screenshooter->renderer = renderer;
|
||||
|
||||
wl_list_init(&screenshooter->screenshots);
|
||||
|
||||
screenshooter->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &screenshooter->display_destroy);
|
||||
|
||||
screenshooter->wl_global = wl_global_create(display,
|
||||
&orbital_screenshooter_interface, 1, screenshooter, screenshooter_bind);
|
||||
if (screenshooter->wl_global == NULL) {
|
||||
|
@ -162,12 +202,3 @@ struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display,
|
|||
|
||||
return screenshooter;
|
||||
}
|
||||
|
||||
void wlr_screenshooter_destroy(struct wlr_screenshooter *screenshooter) {
|
||||
if (!screenshooter) {
|
||||
return;
|
||||
}
|
||||
// TODO: this segfault (wl_display->registry_resource_list is not init)
|
||||
// wl_global_destroy(screenshooter->wl_global);
|
||||
free(screenshooter);
|
||||
}
|
||||
|
|
|
@ -346,6 +346,34 @@ static const struct wlr_touch_grab_interface default_touch_grab_impl = {
|
|||
};
|
||||
|
||||
|
||||
void wlr_seat_destroy(struct wlr_seat *wlr_seat) {
|
||||
if (!wlr_seat) {
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_remove(&wlr_seat->display_destroy.link);
|
||||
|
||||
struct wlr_seat_client *client, *tmp;
|
||||
wl_list_for_each_safe(client, tmp, &wlr_seat->clients, link) {
|
||||
// will destroy other resources as well
|
||||
wl_resource_destroy(client->wl_resource);
|
||||
}
|
||||
|
||||
wl_global_destroy(wlr_seat->wl_global);
|
||||
free(wlr_seat->pointer_state.default_grab);
|
||||
free(wlr_seat->keyboard_state.default_grab);
|
||||
free(wlr_seat->touch_state.default_grab);
|
||||
free(wlr_seat->data_device);
|
||||
free(wlr_seat->name);
|
||||
free(wlr_seat);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_seat *seat =
|
||||
wl_container_of(listener, seat, display_destroy);
|
||||
wlr_seat_destroy(seat);
|
||||
}
|
||||
|
||||
struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
|
||||
struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat));
|
||||
if (!wlr_seat) {
|
||||
|
@ -427,29 +455,12 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
|
|||
wl_signal_init(&wlr_seat->events.touch_grab_begin);
|
||||
wl_signal_init(&wlr_seat->events.touch_grab_end);
|
||||
|
||||
wlr_seat->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &wlr_seat->display_destroy);
|
||||
|
||||
return wlr_seat;
|
||||
}
|
||||
|
||||
void wlr_seat_destroy(struct wlr_seat *wlr_seat) {
|
||||
if (!wlr_seat) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_seat_client *client, *tmp;
|
||||
wl_list_for_each_safe(client, tmp, &wlr_seat->clients, link) {
|
||||
// will destroy other resources as well
|
||||
wl_resource_destroy(client->wl_resource);
|
||||
}
|
||||
|
||||
wl_global_destroy(wlr_seat->wl_global);
|
||||
free(wlr_seat->pointer_state.default_grab);
|
||||
free(wlr_seat->keyboard_state.default_grab);
|
||||
free(wlr_seat->touch_state.default_grab);
|
||||
free(wlr_seat->data_device);
|
||||
free(wlr_seat->name);
|
||||
free(wlr_seat);
|
||||
}
|
||||
|
||||
struct wlr_seat_client *wlr_seat_client_for_wl_client(struct wlr_seat *wlr_seat,
|
||||
struct wl_client *wl_client) {
|
||||
assert(wlr_seat);
|
||||
|
|
|
@ -140,6 +140,31 @@ static void server_decoration_manager_bind(struct wl_client *client, void *data,
|
|||
manager->default_mode);
|
||||
}
|
||||
|
||||
void wlr_server_decoration_manager_destroy(
|
||||
struct wlr_server_decoration_manager *manager) {
|
||||
if (manager == NULL) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&manager->display_destroy.link);
|
||||
struct wlr_server_decoration *decoration, *tmp_decoration;
|
||||
wl_list_for_each_safe(decoration, tmp_decoration, &manager->decorations,
|
||||
link) {
|
||||
server_decoration_destroy(decoration);
|
||||
}
|
||||
struct wl_resource *resource, *tmp_resource;
|
||||
wl_resource_for_each_safe(resource, tmp_resource, &manager->wl_resources) {
|
||||
server_decoration_manager_destroy_resource(resource);
|
||||
}
|
||||
wl_global_destroy(manager->wl_global);
|
||||
free(manager);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_server_decoration_manager *manager =
|
||||
wl_container_of(listener, manager, display_destroy);
|
||||
wlr_server_decoration_manager_destroy(manager);
|
||||
}
|
||||
|
||||
struct wlr_server_decoration_manager *wlr_server_decoration_manager_create(
|
||||
struct wl_display *display) {
|
||||
struct wlr_server_decoration_manager *manager =
|
||||
|
@ -158,23 +183,9 @@ struct wlr_server_decoration_manager *wlr_server_decoration_manager_create(
|
|||
wl_list_init(&manager->wl_resources);
|
||||
wl_list_init(&manager->decorations);
|
||||
wl_signal_init(&manager->events.new_decoration);
|
||||
|
||||
manager->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &manager->display_destroy);
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
void wlr_server_decoration_manager_destroy(
|
||||
struct wlr_server_decoration_manager *manager) {
|
||||
if (manager == NULL) {
|
||||
return;
|
||||
}
|
||||
struct wlr_server_decoration *decoration, *tmp_decoration;
|
||||
wl_list_for_each_safe(decoration, tmp_decoration, &manager->decorations,
|
||||
link) {
|
||||
server_decoration_destroy(decoration);
|
||||
}
|
||||
struct wl_resource *resource, *tmp_resource;
|
||||
wl_resource_for_each_safe(resource, tmp_resource, &manager->wl_resources) {
|
||||
server_decoration_manager_destroy_resource(resource);
|
||||
}
|
||||
wl_global_destroy(manager->wl_global);
|
||||
free(manager);
|
||||
}
|
||||
|
|
|
@ -564,6 +564,12 @@ static void shell_bind(struct wl_client *wl_client, void *data,
|
|||
wl_list_insert(&wl_shell->wl_resources, wl_resource_get_link(wl_resource));
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_wl_shell *wl_shell =
|
||||
wl_container_of(listener, wl_shell, display_destroy);
|
||||
wlr_wl_shell_destroy(wl_shell);
|
||||
}
|
||||
|
||||
struct wlr_wl_shell *wlr_wl_shell_create(struct wl_display *display) {
|
||||
struct wlr_wl_shell *wl_shell = calloc(1, sizeof(struct wlr_wl_shell));
|
||||
if (!wl_shell) {
|
||||
|
@ -581,6 +587,10 @@ struct wlr_wl_shell *wlr_wl_shell_create(struct wl_display *display) {
|
|||
wl_list_init(&wl_shell->surfaces);
|
||||
wl_list_init(&wl_shell->popup_grabs);
|
||||
wl_signal_init(&wl_shell->events.new_surface);
|
||||
|
||||
wl_shell->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &wl_shell->display_destroy);
|
||||
|
||||
return wl_shell;
|
||||
}
|
||||
|
||||
|
@ -588,14 +598,14 @@ void wlr_wl_shell_destroy(struct wlr_wl_shell *wlr_wl_shell) {
|
|||
if (!wlr_wl_shell) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&wlr_wl_shell->display_destroy.link);
|
||||
struct wl_resource *resource = NULL, *temp = NULL;
|
||||
wl_resource_for_each_safe(resource, temp, &wlr_wl_shell->wl_resources) {
|
||||
struct wl_list *link = wl_resource_get_link(resource);
|
||||
wl_list_remove(link);
|
||||
// shell_destroy will remove the resource from the list
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
// TODO: destroy surfaces
|
||||
// TODO: this segfault (wl_display->registry_resource_list is not init)
|
||||
// wl_global_destroy(wlr_wl_shell->wl_global);
|
||||
wl_global_destroy(wlr_wl_shell->wl_global);
|
||||
free(wlr_wl_shell);
|
||||
}
|
||||
|
||||
|
|
|
@ -1250,6 +1250,12 @@ static void xdg_shell_bind(struct wl_client *wl_client, void *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_shell_v6 *xdg_shell =
|
||||
wl_container_of(listener, xdg_shell, display_destroy);
|
||||
wlr_xdg_shell_v6_destroy(xdg_shell);
|
||||
}
|
||||
|
||||
struct wlr_xdg_shell_v6 *wlr_xdg_shell_v6_create(struct wl_display *display) {
|
||||
struct wlr_xdg_shell_v6 *xdg_shell =
|
||||
calloc(1, sizeof(struct wlr_xdg_shell_v6));
|
||||
|
@ -1272,6 +1278,9 @@ struct wlr_xdg_shell_v6 *wlr_xdg_shell_v6_create(struct wl_display *display) {
|
|||
|
||||
wl_signal_init(&xdg_shell->events.new_surface);
|
||||
|
||||
xdg_shell->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &xdg_shell->display_destroy);
|
||||
|
||||
return xdg_shell;
|
||||
}
|
||||
|
||||
|
@ -1279,8 +1288,8 @@ void wlr_xdg_shell_v6_destroy(struct wlr_xdg_shell_v6 *xdg_shell) {
|
|||
if (!xdg_shell) {
|
||||
return;
|
||||
}
|
||||
// TODO: this segfault (wl_display->registry_resource_list is not init)
|
||||
// wl_global_destroy(xdg_shell->wl_global);
|
||||
wl_list_remove(&xdg_shell->display_destroy.link);
|
||||
wl_global_destroy(xdg_shell->wl_global);
|
||||
free(xdg_shell);
|
||||
}
|
||||
|
||||
|
|
|
@ -125,38 +125,25 @@ static void exec_xwayland(struct wlr_xwayland *wlr_xwayland) {
|
|||
execvp("Xwayland", argv);
|
||||
}
|
||||
|
||||
static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland,
|
||||
struct wl_display *wl_display, struct wlr_compositor *compositor);
|
||||
static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland);
|
||||
|
||||
static void xwayland_destroy_event(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xwayland *wlr_xwayland = wl_container_of(listener, wlr_xwayland, destroy_listener);
|
||||
|
||||
/* don't call client destroy */
|
||||
wlr_xwayland->client = NULL;
|
||||
wl_list_remove(&wlr_xwayland->destroy_listener.link);
|
||||
wlr_xwayland_finish(wlr_xwayland);
|
||||
|
||||
if (time(NULL) - wlr_xwayland->server_start > 5) {
|
||||
wlr_xwayland_init(wlr_xwayland, wlr_xwayland->wl_display,
|
||||
wlr_xwayland->compositor);
|
||||
}
|
||||
}
|
||||
|
||||
static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) {
|
||||
if (!wlr_xwayland || wlr_xwayland->display == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlr_xwayland->cursor != NULL) {
|
||||
free(wlr_xwayland->cursor);
|
||||
}
|
||||
|
||||
xwm_destroy(wlr_xwayland->xwm);
|
||||
|
||||
if (wlr_xwayland->client) {
|
||||
wl_list_remove(&wlr_xwayland->destroy_listener.link);
|
||||
wl_list_remove(&wlr_xwayland->client_destroy.link);
|
||||
wl_client_destroy(wlr_xwayland->client);
|
||||
}
|
||||
if (wlr_xwayland->sigusr1_source) {
|
||||
wl_event_source_remove(wlr_xwayland->sigusr1_source);
|
||||
}
|
||||
|
||||
xwm_destroy(wlr_xwayland->xwm);
|
||||
|
||||
safe_close(wlr_xwayland->x_fd[0]);
|
||||
safe_close(wlr_xwayland->x_fd[1]);
|
||||
safe_close(wlr_xwayland->wl_fd[0]);
|
||||
|
@ -164,6 +151,8 @@ static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) {
|
|||
safe_close(wlr_xwayland->wm_fd[0]);
|
||||
safe_close(wlr_xwayland->wm_fd[1]);
|
||||
|
||||
wl_list_remove(&wlr_xwayland->display_destroy.link);
|
||||
|
||||
unlink_display_sockets(wlr_xwayland->display);
|
||||
wlr_xwayland->display = -1;
|
||||
unsetenv("DISPLAY");
|
||||
|
@ -173,6 +162,39 @@ static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) {
|
|||
*/
|
||||
}
|
||||
|
||||
static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland,
|
||||
struct wl_display *wl_display, struct wlr_compositor *compositor);
|
||||
|
||||
static void handle_client_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xwayland *wlr_xwayland =
|
||||
wl_container_of(listener, wlr_xwayland, client_destroy);
|
||||
|
||||
// Don't call client destroy: it's being destroyed already
|
||||
wlr_xwayland->client = NULL;
|
||||
wl_list_remove(&wlr_xwayland->client_destroy.link);
|
||||
|
||||
wlr_xwayland_finish(wlr_xwayland);
|
||||
|
||||
if (time(NULL) - wlr_xwayland->server_start > 5) {
|
||||
wlr_log(L_INFO, "Restarting Xwayland");
|
||||
wlr_xwayland_init(wlr_xwayland, wlr_xwayland->wl_display,
|
||||
wlr_xwayland->compositor);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xwayland *wlr_xwayland =
|
||||
wl_container_of(listener, wlr_xwayland, display_destroy);
|
||||
|
||||
// Don't call client destroy: the display is being destroyed, it's too late
|
||||
if (wlr_xwayland->client) {
|
||||
wlr_xwayland->client = NULL;
|
||||
wl_list_remove(&wlr_xwayland->client_destroy.link);
|
||||
}
|
||||
|
||||
wlr_xwayland_destroy(wlr_xwayland);
|
||||
}
|
||||
|
||||
static int xserver_handle_ready(int signal_number, void *data) {
|
||||
struct wlr_xwayland *wlr_xwayland = data;
|
||||
|
||||
|
@ -227,6 +249,9 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland,
|
|||
wl_signal_init(&wlr_xwayland->events.new_surface);
|
||||
wl_signal_init(&wlr_xwayland->events.ready);
|
||||
|
||||
wlr_xwayland->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(wl_display, &wlr_xwayland->display_destroy);
|
||||
|
||||
wlr_xwayland->display = open_display_sockets(wlr_xwayland->x_fd);
|
||||
if (wlr_xwayland->display < 0) {
|
||||
wlr_xwayland_finish(wlr_xwayland);
|
||||
|
@ -252,11 +277,13 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland,
|
|||
|
||||
wlr_xwayland->wl_fd[0] = -1; /* not ours anymore */
|
||||
|
||||
wlr_xwayland->destroy_listener.notify = xwayland_destroy_event;
|
||||
wl_client_add_destroy_listener(wlr_xwayland->client, &wlr_xwayland->destroy_listener);
|
||||
wlr_xwayland->client_destroy.notify = handle_client_destroy;
|
||||
wl_client_add_destroy_listener(wlr_xwayland->client,
|
||||
&wlr_xwayland->client_destroy);
|
||||
|
||||
struct wl_event_loop *loop = wl_display_get_event_loop(wl_display);
|
||||
wlr_xwayland->sigusr1_source = wl_event_loop_add_signal(loop, SIGUSR1, xserver_handle_ready, wlr_xwayland);
|
||||
wlr_xwayland->sigusr1_source = wl_event_loop_add_signal(loop, SIGUSR1,
|
||||
xserver_handle_ready, wlr_xwayland);
|
||||
|
||||
if ((wlr_xwayland->pid = fork()) == 0) {
|
||||
/* Double-fork, but we need to forward SIGUSR1 once Xserver(1)
|
||||
|
|
|
@ -1081,6 +1081,12 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
|||
if (xwm->cursor) {
|
||||
xcb_free_cursor(xwm->xcb_conn, xwm->cursor);
|
||||
}
|
||||
if (xwm->colormap) {
|
||||
xcb_free_colormap(xwm->xcb_conn, xwm->colormap);
|
||||
}
|
||||
if (xwm->window) {
|
||||
xcb_destroy_window(xwm->xcb_conn, xwm->window);
|
||||
}
|
||||
if (xwm->event_source) {
|
||||
wl_event_source_remove(xwm->event_source);
|
||||
}
|
||||
|
@ -1088,6 +1094,9 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
|||
wl_list_for_each_safe(xsurface, tmp, &xwm->surfaces, link) {
|
||||
wlr_xwayland_surface_destroy(xsurface);
|
||||
}
|
||||
wl_list_for_each_safe(xsurface, tmp, &xwm->unpaired_surfaces, link) {
|
||||
wlr_xwayland_surface_destroy(xsurface);
|
||||
}
|
||||
wl_list_remove(&xwm->compositor_surface_create.link);
|
||||
xcb_disconnect(xwm->xcb_conn);
|
||||
|
||||
|
|
Loading…
Reference in a new issue