mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-02 01:05:58 +01:00
Merge branch 'master' into xwm-selection
This commit is contained in:
commit
6b42bfad18
45 changed files with 560 additions and 274 deletions
|
@ -34,6 +34,10 @@ static void wlr_drm_backend_destroy(struct wlr_backend *backend) {
|
||||||
wlr_output_destroy(&conn->output);
|
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_resources_free(drm);
|
||||||
wlr_drm_renderer_finish(&drm->renderer);
|
wlr_drm_renderer_finish(&drm->renderer);
|
||||||
wlr_session_close_file(drm->session, drm->fd);
|
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) {
|
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;
|
struct wlr_session *session = data;
|
||||||
|
|
||||||
if (session->active) {
|
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) {
|
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);
|
char *name = drmGetDeviceNameFromFd2(drm->fd);
|
||||||
wlr_log(L_DEBUG, "%s invalidated", name);
|
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);
|
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_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||||
struct wlr_session *session, int gpu_fd, struct wlr_backend *parent) {
|
struct wlr_session *session, int gpu_fd, struct wlr_backend *parent) {
|
||||||
assert(display && session && gpu_fd >= 0);
|
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());
|
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;
|
return &drm->backend;
|
||||||
|
|
||||||
error_event:
|
error_event:
|
||||||
|
|
|
@ -565,8 +565,7 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,
|
||||||
enum wl_output_transform transform =
|
enum wl_output_transform transform =
|
||||||
wlr_output_transform_invert(output->transform);
|
wlr_output_transform_invert(output->transform);
|
||||||
struct wlr_box transformed_hotspot;
|
struct wlr_box transformed_hotspot;
|
||||||
wlr_output_transform_apply_to_box(transform, &hotspot,
|
wlr_box_transform(&hotspot, transform, &transformed_hotspot);
|
||||||
&transformed_hotspot);
|
|
||||||
plane->cursor_hotspot_x = transformed_hotspot.x;
|
plane->cursor_hotspot_x = transformed_hotspot.x;
|
||||||
plane->cursor_hotspot_y = transformed_hotspot.y;
|
plane->cursor_hotspot_y = transformed_hotspot.y;
|
||||||
|
|
||||||
|
@ -628,7 +627,7 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output,
|
||||||
enum wl_output_transform transform =
|
enum wl_output_transform transform =
|
||||||
wlr_output_transform_invert(output->transform);
|
wlr_output_transform_invert(output->transform);
|
||||||
struct wlr_box transformed_box;
|
struct wlr_box transformed_box;
|
||||||
wlr_output_transform_apply_to_box(transform, &box, &transformed_box);
|
wlr_box_transform(&box, transform, &transformed_box);
|
||||||
|
|
||||||
if (plane != NULL) {
|
if (plane != NULL) {
|
||||||
transformed_box.x -= plane->cursor_hotspot_x;
|
transformed_box.x -= plane->cursor_hotspot_x;
|
||||||
|
|
|
@ -39,7 +39,7 @@ bool wlr_drm_renderer_init(struct wlr_drm_backend *drm,
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_egl:
|
error_egl:
|
||||||
wlr_egl_free(&renderer->egl);
|
wlr_egl_finish(&renderer->egl);
|
||||||
error_gbm:
|
error_gbm:
|
||||||
gbm_device_destroy(renderer->gbm);
|
gbm_device_destroy(renderer->gbm);
|
||||||
return false;
|
return false;
|
||||||
|
@ -51,7 +51,7 @@ void wlr_drm_renderer_finish(struct wlr_drm_renderer *renderer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_renderer_destroy(renderer->wlr_rend);
|
wlr_renderer_destroy(renderer->wlr_rend);
|
||||||
wlr_egl_free(&renderer->egl);
|
wlr_egl_finish(&renderer->egl);
|
||||||
gbm_device_destroy(renderer->gbm);
|
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) {
|
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");
|
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) {
|
if (!backend->libinput_context) {
|
||||||
wlr_log(L_ERROR, "Failed to create libinput context");
|
wlr_log(L_ERROR, "Failed to create libinput context");
|
||||||
return false;
|
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 =
|
||||||
(struct wlr_libinput_backend *)_backend;
|
(struct wlr_libinput_backend *)_backend;
|
||||||
|
|
||||||
for (size_t i = 0; i < backend->wlr_device_lists.length; i++) {
|
for (size_t i = 0; i < backend->wlr_device_lists.length; i++) {
|
||||||
struct wl_list *wlr_devices = backend->wlr_device_lists.items[i];
|
struct wl_list *wlr_devices = backend->wlr_device_lists.items[i];
|
||||||
struct wlr_input_device *wlr_dev, *next;
|
struct wlr_input_device *wlr_dev, *next;
|
||||||
|
@ -108,6 +111,10 @@ static void wlr_libinput_backend_destroy(struct wlr_backend *_backend) {
|
||||||
}
|
}
|
||||||
free(wlr_devices);
|
free(wlr_devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_remove(&backend->display_destroy.link);
|
||||||
|
wl_list_remove(&backend->session_signal.link);
|
||||||
|
|
||||||
wlr_list_finish(&backend->wlr_device_lists);
|
wlr_list_finish(&backend->wlr_device_lists);
|
||||||
wl_event_source_remove(backend->input_event);
|
wl_event_source_remove(backend->input_event);
|
||||||
libinput_unref(backend->libinput_context);
|
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) {
|
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;
|
struct wlr_session *session = data;
|
||||||
|
|
||||||
if (!backend->libinput_context) {
|
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_backend *wlr_libinput_backend_create(struct wl_display *display,
|
||||||
struct wlr_session *session) {
|
struct wlr_session *session) {
|
||||||
assert(display && 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;
|
backend->session_signal.notify = session_signal;
|
||||||
wl_signal_add(&session->session_signal, &backend->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;
|
return &backend->backend;
|
||||||
error_backend:
|
error_backend:
|
||||||
free(backend);
|
free(backend);
|
||||||
|
|
|
@ -35,7 +35,6 @@ static void multi_backend_destroy(struct wlr_backend *_backend) {
|
||||||
wlr_backend_destroy(sub->backend);
|
wlr_backend_destroy(sub->backend);
|
||||||
free(sub);
|
free(sub);
|
||||||
}
|
}
|
||||||
wlr_session_destroy(backend->session);
|
|
||||||
free(backend);
|
free(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,12 @@ out:
|
||||||
return 1;
|
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 *wlr_session_create(struct wl_display *disp) {
|
||||||
struct wlr_session *session = NULL;
|
struct wlr_session *session = NULL;
|
||||||
const struct session_impl **iter;
|
const struct session_impl **iter;
|
||||||
|
@ -100,6 +106,9 @@ struct wlr_session *wlr_session_create(struct wl_display *disp) {
|
||||||
goto error_mon;
|
goto error_mon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session->display_destroy.notify = handle_display_destroy;
|
||||||
|
wl_display_add_destroy_listener(disp, &session->display_destroy);
|
||||||
|
|
||||||
return session;
|
return session;
|
||||||
|
|
||||||
error_mon:
|
error_mon:
|
||||||
|
@ -107,7 +116,7 @@ error_mon:
|
||||||
error_udev:
|
error_udev:
|
||||||
udev_unref(session->udev);
|
udev_unref(session->udev);
|
||||||
error_session:
|
error_session:
|
||||||
wlr_session_destroy(session);
|
session->impl->destroy(session);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +125,8 @@ void wlr_session_destroy(struct wlr_session *session) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_remove(&session->display_destroy.link);
|
||||||
|
|
||||||
wl_event_source_remove(session->udev_event);
|
wl_event_source_remove(session->udev_event);
|
||||||
udev_monitor_unref(session->mon);
|
udev_monitor_unref(session->mon);
|
||||||
udev_unref(session->udev);
|
udev_unref(session->udev);
|
||||||
|
|
|
@ -79,10 +79,12 @@ static void wlr_wl_backend_destroy(struct wlr_backend *_backend) {
|
||||||
wlr_input_device_destroy(input_device);
|
wlr_input_device_destroy(input_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_list_remove(&backend->local_display_destroy.link);
|
||||||
|
|
||||||
free(backend->seat_name);
|
free(backend->seat_name);
|
||||||
|
|
||||||
wl_event_source_remove(backend->remote_display_src);
|
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->seat) wl_seat_destroy(backend->seat);
|
||||||
if (backend->shm) wl_shm_destroy(backend->shm);
|
if (backend->shm) wl_shm_destroy(backend->shm);
|
||||||
if (backend->shell) zxdg_shell_v6_destroy(backend->shell);
|
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;
|
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) {
|
struct wlr_backend *wlr_wl_backend_create(struct wl_display *display) {
|
||||||
wlr_log(L_INFO, "Creating wayland backend");
|
wlr_log(L_INFO, "Creating wayland backend");
|
||||||
|
|
||||||
|
@ -176,8 +184,12 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display) {
|
||||||
return false;
|
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);
|
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;
|
return &backend->backend;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,8 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
|
||||||
box.x = wl_fixed_to_int(surface_x);
|
box.x = wl_fixed_to_int(surface_x);
|
||||||
box.y = wl_fixed_to_int(surface_y);
|
box.y = wl_fixed_to_int(surface_y);
|
||||||
struct wlr_box transformed;
|
struct wlr_box transformed;
|
||||||
wlr_output_transform_apply_to_box(wlr_output->transform, &box, &transformed);
|
|
||||||
|
wlr_box_transform(&box, wlr_output->transform, &transformed);
|
||||||
box.x /= wlr_output->scale;
|
box.x /= wlr_output->scale;
|
||||||
box.y /= wlr_output->scale;
|
box.y /= wlr_output->scale;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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) {
|
static bool wlr_x11_backend_start(struct wlr_backend *backend) {
|
||||||
struct wlr_x11_backend *x11 = (struct wlr_x11_backend *)backend;
|
struct wlr_x11_backend *x11 = (struct wlr_x11_backend *)backend;
|
||||||
struct wlr_x11_output *output = &x11->output;
|
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;
|
struct wlr_x11_output *output = &x11->output;
|
||||||
wlr_output_destroy(&output->wlr_output);
|
wlr_output_destroy(&output->wlr_output);
|
||||||
|
|
||||||
|
wl_list_remove(&x11->display_destroy.link);
|
||||||
|
|
||||||
wl_event_source_remove(x11->frame_timer);
|
wl_event_source_remove(x11->frame_timer);
|
||||||
wlr_egl_free(&x11->egl);
|
wlr_egl_finish(&x11->egl);
|
||||||
|
|
||||||
xcb_disconnect(x11->xcb_conn);
|
xcb_disconnect(x11->xcb_conn);
|
||||||
free(x11);
|
free(x11);
|
||||||
|
@ -328,6 +267,78 @@ static struct wlr_backend_impl backend_impl = {
|
||||||
.get_egl = wlr_x11_backend_get_egl,
|
.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,
|
static bool output_set_custom_mode(struct wlr_output *wlr_output, int32_t width,
|
||||||
int32_t height, int32_t refresh) {
|
int32_t height, int32_t refresh) {
|
||||||
struct wlr_x11_output *output = (struct wlr_x11_output *)wlr_output;
|
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_display *display;
|
||||||
struct wl_event_source *drm_event;
|
struct wl_event_source *drm_event;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
struct wl_listener session_signal;
|
struct wl_listener session_signal;
|
||||||
struct wl_listener drm_invalidated;
|
struct wl_listener drm_invalidated;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct wlr_libinput_backend {
|
||||||
struct libinput *libinput_context;
|
struct libinput *libinput_context;
|
||||||
struct wl_event_source *input_event;
|
struct wl_event_source *input_event;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
struct wl_listener session_signal;
|
struct wl_listener session_signal;
|
||||||
|
|
||||||
struct wlr_list wlr_device_lists; // list of struct wl_list
|
struct wlr_list wlr_device_lists; // list of struct wl_list
|
||||||
|
|
|
@ -22,6 +22,7 @@ struct wlr_wl_backend {
|
||||||
struct wl_list outputs;
|
struct wl_list outputs;
|
||||||
struct wlr_egl egl;
|
struct wlr_egl egl;
|
||||||
size_t requested_outputs;
|
size_t requested_outputs;
|
||||||
|
struct wl_listener local_display_destroy;
|
||||||
/* remote state */
|
/* remote state */
|
||||||
struct wl_display *remote_display;
|
struct wl_display *remote_display;
|
||||||
struct wl_event_source *remote_display_src;
|
struct wl_event_source *remote_display_src;
|
||||||
|
|
|
@ -51,6 +51,8 @@ struct wlr_x11_backend {
|
||||||
|
|
||||||
// The time we last received an event
|
// The time we last received an event
|
||||||
xcb_timestamp_t time;
|
xcb_timestamp_t time;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,8 @@ struct wlr_session {
|
||||||
struct wl_event_source *udev_event;
|
struct wl_event_source *udev_event;
|
||||||
|
|
||||||
struct wl_list devices;
|
struct wl_list devices;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -34,8 +34,4 @@ struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output,
|
||||||
struct wl_display *display);
|
struct wl_display *display);
|
||||||
void wlr_output_destroy_global(struct wlr_output *wlr_output);
|
void wlr_output_destroy_global(struct wlr_output *wlr_output);
|
||||||
|
|
||||||
void wlr_output_transform_apply_to_box(enum wl_output_transform transform,
|
|
||||||
struct wlr_box *box, struct wlr_box *dest);
|
|
||||||
enum wl_output_transform wlr_output_transform_invert(enum wl_output_transform);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
struct wlr_egl {
|
struct wlr_egl {
|
||||||
EGLDisplay display;
|
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
|
* Frees all related egl resources, makes the context not-current and
|
||||||
* unbinds a bound wayland display.
|
* 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.
|
* Binds the given display to the egl instance.
|
||||||
|
|
|
@ -10,6 +10,8 @@ void wlr_matrix_rotate(float (*output)[16], float radians);
|
||||||
void wlr_matrix_mul(const float (*x)[16], const float (*y)[16], float (*product)[16]);
|
void wlr_matrix_mul(const float (*x)[16], const float (*y)[16], float (*product)[16]);
|
||||||
|
|
||||||
enum wl_output_transform;
|
enum wl_output_transform;
|
||||||
|
void wlr_matrix_transform(float mat[static 16],
|
||||||
|
enum wl_output_transform transform);
|
||||||
void wlr_matrix_texture(float mat[static 16], int32_t width, int32_t height,
|
void wlr_matrix_texture(float mat[static 16], int32_t width, int32_t height,
|
||||||
enum wl_output_transform transform);
|
enum wl_output_transform transform);
|
||||||
|
|
||||||
|
|
|
@ -18,4 +18,8 @@ bool wlr_box_contains_point(struct wlr_box *box, double x, double y);
|
||||||
|
|
||||||
bool wlr_box_empty(struct wlr_box *box);
|
bool wlr_box_empty(struct wlr_box *box);
|
||||||
|
|
||||||
|
enum wl_output_transform;
|
||||||
|
void wlr_box_transform(struct wlr_box *box, enum wl_output_transform transform,
|
||||||
|
struct wlr_box *dest);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,7 +9,8 @@ struct wlr_compositor {
|
||||||
struct wl_list wl_resources;
|
struct wl_list wl_resources;
|
||||||
struct wlr_renderer *renderer;
|
struct wlr_renderer *renderer;
|
||||||
struct wl_list surfaces;
|
struct wl_list surfaces;
|
||||||
struct wl_listener destroy_surface_listener;
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal create_surface;
|
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_compositor *wlr_compositor_create(struct wl_display *display,
|
||||||
struct wlr_renderer *renderer);
|
struct wlr_renderer *renderer);
|
||||||
|
|
||||||
struct wlr_surface;
|
|
||||||
void wl_compositor_surface_destroyed(struct wlr_compositor *wlr_compositor,
|
|
||||||
struct wlr_surface *surface);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,8 @@ wlr_touch_grab_interface wlr_data_device_touch_drag_interface;
|
||||||
|
|
||||||
struct wlr_data_device_manager {
|
struct wlr_data_device_manager {
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_data_offer {
|
struct wlr_data_offer {
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
|
|
||||||
struct wlr_gamma_control_manager {
|
struct wlr_gamma_control_manager {
|
||||||
struct wl_global *wl_global;
|
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;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,6 +77,8 @@ struct wlr_output {
|
||||||
// the output position in layout space reported to clients
|
// the output position in layout space reported to clients
|
||||||
int32_t lx, ly;
|
int32_t lx, ly;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,4 +117,6 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor,
|
||||||
double x, double y);
|
double x, double y);
|
||||||
void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor);
|
void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor);
|
||||||
|
|
||||||
|
enum wl_output_transform wlr_output_transform_invert(enum wl_output_transform);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
struct wlr_screenshooter {
|
struct wlr_screenshooter {
|
||||||
struct wl_global *wl_global;
|
struct wl_global *wl_global;
|
||||||
struct wlr_renderer *renderer;
|
struct wlr_renderer *renderer;
|
||||||
|
struct wl_list screenshots; // wlr_screenshot::link
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
@ -12,6 +15,7 @@ struct wlr_screenshooter {
|
||||||
struct wlr_screenshot {
|
struct wlr_screenshot {
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wl_resource *output_resource;
|
struct wl_resource *output_resource;
|
||||||
|
struct wl_list link;
|
||||||
|
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
struct wlr_screenshooter *screenshooter;
|
struct wlr_screenshooter *screenshooter;
|
||||||
|
|
|
@ -184,6 +184,7 @@ struct wlr_seat {
|
||||||
struct wlr_seat_keyboard_state keyboard_state;
|
struct wlr_seat_keyboard_state keyboard_state;
|
||||||
struct wlr_seat_touch_state touch_state;
|
struct wlr_seat_touch_state touch_state;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
struct wl_listener selection_data_source_destroy;
|
struct wl_listener selection_data_source_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -33,6 +33,8 @@ struct wlr_server_decoration_manager {
|
||||||
|
|
||||||
uint32_t default_mode; // enum wlr_server_decoration_manager_mode
|
uint32_t default_mode; // enum wlr_server_decoration_manager_mode
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal new_decoration;
|
struct wl_signal new_decoration;
|
||||||
} events;
|
} events;
|
||||||
|
|
|
@ -12,6 +12,8 @@ struct wlr_wl_shell {
|
||||||
struct wl_list popup_grabs;
|
struct wl_list popup_grabs;
|
||||||
uint32_t ping_timeout;
|
uint32_t ping_timeout;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal new_surface;
|
struct wl_signal new_surface;
|
||||||
} events;
|
} events;
|
||||||
|
|
|
@ -11,6 +11,8 @@ struct wlr_xdg_shell_v6 {
|
||||||
struct wl_list popup_grabs;
|
struct wl_list popup_grabs;
|
||||||
uint32_t ping_timeout;
|
uint32_t ping_timeout;
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal new_surface;
|
struct wl_signal new_surface;
|
||||||
} events;
|
} events;
|
||||||
|
|
|
@ -25,7 +25,8 @@ struct wlr_xwayland {
|
||||||
time_t server_start;
|
time_t server_start;
|
||||||
|
|
||||||
struct wl_event_source *sigusr1_source;
|
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_xwm *xwm;
|
||||||
struct wlr_xwayland_cursor *cursor;
|
struct wlr_xwayland_cursor *cursor;
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ error:
|
||||||
return false;
|
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);
|
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
if (egl->wl_display && eglUnbindWaylandDisplayWL) {
|
if (egl->wl_display && eglUnbindWaylandDisplayWL) {
|
||||||
eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
|
eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
|
||||||
|
|
|
@ -86,38 +86,55 @@ void wlr_matrix_mul(const float (*x)[16], const float (*y)[16], float (*product)
|
||||||
static const float transforms[][4] = {
|
static const float transforms[][4] = {
|
||||||
[WL_OUTPUT_TRANSFORM_NORMAL] = {
|
[WL_OUTPUT_TRANSFORM_NORMAL] = {
|
||||||
1.0f, 0.0f,
|
1.0f, 0.0f,
|
||||||
0.0f, -1.0f,
|
0.0f, 1.0f,
|
||||||
},
|
},
|
||||||
[WL_OUTPUT_TRANSFORM_90] = {
|
[WL_OUTPUT_TRANSFORM_90] = {
|
||||||
0.0f, -1.0f,
|
0.0f, -1.0f,
|
||||||
-1.0f, 0.0f,
|
1.0f, 0.0f,
|
||||||
},
|
},
|
||||||
[WL_OUTPUT_TRANSFORM_180] = {
|
[WL_OUTPUT_TRANSFORM_180] = {
|
||||||
-1.0f, 0.0f,
|
-1.0f, 0.0f,
|
||||||
0.0f, 1.0f,
|
0.0f, -1.0f,
|
||||||
},
|
},
|
||||||
[WL_OUTPUT_TRANSFORM_270] = {
|
[WL_OUTPUT_TRANSFORM_270] = {
|
||||||
0.0f, 1.0f,
|
0.0f, 1.0f,
|
||||||
1.0f, 0.0f,
|
-1.0f, 0.0f,
|
||||||
},
|
},
|
||||||
[WL_OUTPUT_TRANSFORM_FLIPPED] = {
|
[WL_OUTPUT_TRANSFORM_FLIPPED] = {
|
||||||
-1.0f, 0.0f,
|
-1.0f, 0.0f,
|
||||||
0.0f, -1.0f,
|
0.0f, 1.0f,
|
||||||
},
|
},
|
||||||
[WL_OUTPUT_TRANSFORM_FLIPPED_90] = {
|
[WL_OUTPUT_TRANSFORM_FLIPPED_90] = {
|
||||||
0.0f, 1.0f,
|
0.0f, -1.0f,
|
||||||
-1.0f, 0.0f,
|
-1.0f, 0.0f,
|
||||||
},
|
},
|
||||||
[WL_OUTPUT_TRANSFORM_FLIPPED_180] = {
|
[WL_OUTPUT_TRANSFORM_FLIPPED_180] = {
|
||||||
1.0f, 0.0f,
|
1.0f, 0.0f,
|
||||||
0.0f, 1.0f,
|
0.0f, -1.0f,
|
||||||
},
|
},
|
||||||
[WL_OUTPUT_TRANSFORM_FLIPPED_270] = {
|
[WL_OUTPUT_TRANSFORM_FLIPPED_270] = {
|
||||||
0.0f, -1.0f,
|
0.0f, 1.0f,
|
||||||
1.0f, 0.0f,
|
1.0f, 0.0f,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void wlr_matrix_transform(float mat[static 16],
|
||||||
|
enum wl_output_transform transform) {
|
||||||
|
memset(mat, 0, sizeof(*mat) * 16);
|
||||||
|
|
||||||
|
const float *t = transforms[transform];
|
||||||
|
|
||||||
|
// Rotation + reflection
|
||||||
|
mat[0] = t[0];
|
||||||
|
mat[1] = t[1];
|
||||||
|
mat[4] = t[2];
|
||||||
|
mat[5] = t[3];
|
||||||
|
|
||||||
|
// Identity
|
||||||
|
mat[10] = 1.0f;
|
||||||
|
mat[15] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// Equivilent to glOrtho(0, width, 0, height, 1, -1) with the transform applied
|
// Equivilent to glOrtho(0, width, 0, height, 1, -1) with the transform applied
|
||||||
void wlr_matrix_texture(float mat[static 16], int32_t width, int32_t height,
|
void wlr_matrix_texture(float mat[static 16], int32_t width, int32_t height,
|
||||||
enum wl_output_transform transform) {
|
enum wl_output_transform transform) {
|
||||||
|
@ -127,11 +144,11 @@ void wlr_matrix_texture(float mat[static 16], int32_t width, int32_t height,
|
||||||
float x = 2.0f / width;
|
float x = 2.0f / width;
|
||||||
float y = 2.0f / height;
|
float y = 2.0f / height;
|
||||||
|
|
||||||
// Rotation + relection
|
// Rotation + reflection
|
||||||
mat[0] = x * t[0];
|
mat[0] = x * t[0];
|
||||||
mat[1] = x * t[1];
|
mat[1] = x * t[1];
|
||||||
mat[4] = y * t[2];
|
mat[4] = y * -t[2];
|
||||||
mat[5] = y * t[3];
|
mat[5] = y * -t[3];
|
||||||
|
|
||||||
// Translation
|
// Translation
|
||||||
mat[3] = -copysign(1.0f, mat[0] + mat[1]);
|
mat[3] = -copysign(1.0f, mat[0] + mat[1]);
|
||||||
|
|
|
@ -294,10 +294,8 @@ static bool view_at(struct roots_view *view, double lx, double ly,
|
||||||
|
|
||||||
struct wlr_surface_state *state = view->wlr_surface->current;
|
struct wlr_surface_state *state = view->wlr_surface->current;
|
||||||
struct wlr_box box = {
|
struct wlr_box box = {
|
||||||
.x = 0,
|
.x = 0, .y = 0,
|
||||||
.y = 0,
|
.width = state->width, .height = state->height,
|
||||||
.width = state->buffer_width / state->scale,
|
|
||||||
.height = state->buffer_height / state->scale,
|
|
||||||
};
|
};
|
||||||
if (view->rotation != 0.0) {
|
if (view->rotation != 0.0) {
|
||||||
// Coordinates relative to the center of the view
|
// Coordinates relative to the center of the view
|
||||||
|
|
|
@ -51,6 +51,7 @@ int main(int argc, char **argv) {
|
||||||
if (!wlr_backend_start(server.backend)) {
|
if (!wlr_backend_start(server.backend)) {
|
||||||
wlr_log(L_ERROR, "Failed to start backend");
|
wlr_log(L_ERROR, "Failed to start backend");
|
||||||
wlr_backend_destroy(server.backend);
|
wlr_backend_destroy(server.backend);
|
||||||
|
wl_display_destroy(server.wl_display);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,5 +73,6 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
wl_display_run(server.wl_display);
|
wl_display_run(server.wl_display);
|
||||||
wlr_backend_destroy(server.backend);
|
wlr_backend_destroy(server.backend);
|
||||||
|
wl_display_destroy(server.wl_display);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,24 +48,43 @@ static void render_surface(struct wlr_surface *surface,
|
||||||
lx, ly, lx + render_width, ly + render_height)) {
|
lx, ly, lx + render_width, ly + render_height)) {
|
||||||
float matrix[16];
|
float matrix[16];
|
||||||
|
|
||||||
float translate_origin[16];
|
float translate_center[16];
|
||||||
wlr_matrix_translate(&translate_origin,
|
wlr_matrix_translate(&translate_center,
|
||||||
(int)ox + render_width / 2, (int)oy + render_height / 2, 0);
|
(int)ox + render_width / 2, (int)oy + render_height / 2, 0);
|
||||||
|
|
||||||
float rotate[16];
|
float rotate[16];
|
||||||
wlr_matrix_rotate(&rotate, rotation);
|
wlr_matrix_rotate(&rotate, rotation);
|
||||||
|
|
||||||
float translate_center[16];
|
float translate_origin[16];
|
||||||
wlr_matrix_translate(&translate_center, -render_width / 2,
|
wlr_matrix_translate(&translate_origin, -render_width / 2,
|
||||||
-render_height / 2, 0);
|
-render_height / 2, 0);
|
||||||
|
|
||||||
float scale[16];
|
float scale[16];
|
||||||
wlr_matrix_scale(&scale, render_width, render_height, 1);
|
wlr_matrix_scale(&scale, render_width, render_height, 1);
|
||||||
|
|
||||||
float transform[16];
|
float transform[16];
|
||||||
wlr_matrix_mul(&translate_origin, &rotate, &transform);
|
wlr_matrix_mul(&translate_center, &rotate, &transform);
|
||||||
wlr_matrix_mul(&transform, &translate_center, &transform);
|
wlr_matrix_mul(&transform, &translate_origin, &transform);
|
||||||
wlr_matrix_mul(&transform, &scale, &transform);
|
wlr_matrix_mul(&transform, &scale, &transform);
|
||||||
|
|
||||||
|
if (surface->current->transform != WL_OUTPUT_TRANSFORM_NORMAL) {
|
||||||
|
float surface_translate_center[16];
|
||||||
|
wlr_matrix_translate(&surface_translate_center, 0.5, 0.5, 0);
|
||||||
|
|
||||||
|
float surface_transform[16];
|
||||||
|
wlr_matrix_transform(surface_transform,
|
||||||
|
wlr_output_transform_invert(surface->current->transform));
|
||||||
|
|
||||||
|
float surface_translate_origin[16];
|
||||||
|
wlr_matrix_translate(&surface_translate_origin, -0.5, -0.5, 0);
|
||||||
|
|
||||||
|
wlr_matrix_mul(&transform, &surface_translate_center,
|
||||||
|
&transform);
|
||||||
|
wlr_matrix_mul(&transform, &surface_transform, &transform);
|
||||||
|
wlr_matrix_mul(&transform, &surface_translate_origin,
|
||||||
|
&transform);
|
||||||
|
}
|
||||||
|
|
||||||
wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix);
|
wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix);
|
||||||
|
|
||||||
wlr_render_with_matrix(desktop->server->renderer, surface->texture,
|
wlr_render_with_matrix(desktop->server->renderer, surface->texture,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <wayland-server-protocol.h>
|
||||||
#include <wlr/types/wlr_box.h>
|
#include <wlr/types/wlr_box.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
@ -65,3 +66,49 @@ bool wlr_box_contains_point(struct wlr_box *box, double x, double y) {
|
||||||
y >= box->y && y <= box->y + box->height;
|
y >= box->y && y <= box->y + box->height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_box_transform(struct wlr_box *box,
|
||||||
|
enum wl_output_transform transform, struct wlr_box *dest) {
|
||||||
|
if (transform % 2 == 0) {
|
||||||
|
dest->width = box->width;
|
||||||
|
dest->height = box->height;
|
||||||
|
} else {
|
||||||
|
dest->width = box->height;
|
||||||
|
dest->height = box->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (transform) {
|
||||||
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
||||||
|
dest->x = box->x;
|
||||||
|
dest->y = box->y;
|
||||||
|
break;
|
||||||
|
case WL_OUTPUT_TRANSFORM_90:
|
||||||
|
dest->x = box->y;
|
||||||
|
dest->y = box->width - box->x;
|
||||||
|
break;
|
||||||
|
case WL_OUTPUT_TRANSFORM_180:
|
||||||
|
dest->x = box->width - box->x;
|
||||||
|
dest->y = box->height - box->y;
|
||||||
|
break;
|
||||||
|
case WL_OUTPUT_TRANSFORM_270:
|
||||||
|
dest->x = box->height - box->y;
|
||||||
|
dest->y = box->x;
|
||||||
|
break;
|
||||||
|
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
||||||
|
dest->x = box->width - box->x;
|
||||||
|
dest->y = box->y;
|
||||||
|
break;
|
||||||
|
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||||
|
dest->x = box->height - box->y;
|
||||||
|
dest->y = box->width - box->x;
|
||||||
|
break;
|
||||||
|
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||||
|
dest->x = box->x;
|
||||||
|
dest->y = box->height - box->y;
|
||||||
|
break;
|
||||||
|
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||||
|
dest->x = box->y;
|
||||||
|
dest->y = box->x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -78,6 +78,10 @@ static void wl_compositor_bind(struct wl_client *wl_client, void *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_compositor_destroy(struct wlr_compositor *compositor) {
|
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);
|
wl_global_destroy(compositor->wl_global);
|
||||||
free(compositor);
|
free(compositor);
|
||||||
}
|
}
|
||||||
|
@ -151,6 +155,12 @@ static void subcompositor_bind(struct wl_client *client, void *data,
|
||||||
compositor, NULL);
|
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_compositor *wlr_compositor_create(struct wl_display *display,
|
||||||
struct wlr_renderer *renderer) {
|
struct wlr_renderer *renderer) {
|
||||||
struct wlr_compositor *compositor =
|
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,
|
struct wl_global *compositor_global = wl_global_create(display,
|
||||||
&wl_compositor_interface, 4, compositor, wl_compositor_bind);
|
&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->wl_global = compositor_global;
|
||||||
compositor->renderer = renderer;
|
compositor->renderer = renderer;
|
||||||
|
|
||||||
|
@ -173,5 +187,8 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
|
||||||
wl_list_init(&compositor->surfaces);
|
wl_list_init(&compositor->surfaces);
|
||||||
wl_signal_init(&compositor->events.create_surface);
|
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;
|
return compositor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -949,6 +949,21 @@ static void data_device_manager_bind(struct wl_client *client,
|
||||||
NULL, NULL);
|
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 wlr_data_device_manager *wlr_data_device_manager_create(
|
||||||
struct wl_display *display) {
|
struct wl_display *display) {
|
||||||
struct wlr_data_device_manager *manager =
|
struct wlr_data_device_manager *manager =
|
||||||
|
@ -967,13 +982,8 @@ struct wlr_data_device_manager *wlr_data_device_manager_create(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
manager->display_destroy.notify = handle_display_destroy;
|
||||||
|
wl_display_add_destroy_listener(display, &manager->display_destroy);
|
||||||
|
|
||||||
return manager;
|
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) {
|
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_signal_emit(&gamma_control->events.destroy, gamma_control);
|
||||||
wl_list_remove(&gamma_control->output_destroy_listener.link);
|
wl_list_remove(&gamma_control->output_destroy_listener.link);
|
||||||
wl_resource_set_user_data(gamma_control->resource, NULL);
|
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,
|
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 *gamma_control_manager_resource, uint32_t id,
|
||||||
struct wl_resource *output_resource) {
|
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);
|
wl_resource_get_user_data(gamma_control_manager_resource);
|
||||||
struct wlr_output *output = wl_resource_get_user_data(output_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->output_destroy_listener.notify =
|
||||||
gamma_control_handle_output_destroy;
|
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,
|
gamma_control_send_gamma_size(gamma_control->resource,
|
||||||
wlr_output_get_gamma_size(output));
|
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,
|
static void gamma_control_manager_bind(struct wl_client *client, void *data,
|
||||||
uint32_t version, uint32_t id) {
|
uint32_t version, uint32_t id) {
|
||||||
struct wlr_gamma_control_manager *gamma_control_manager = data;
|
struct wlr_gamma_control_manager *manager = data;
|
||||||
assert(client && gamma_control_manager);
|
assert(client && manager);
|
||||||
|
|
||||||
struct wl_resource *resource = wl_resource_create(client,
|
struct wl_resource *resource = wl_resource_create(client,
|
||||||
&gamma_control_manager_interface, version, id);
|
&gamma_control_manager_interface, version, id);
|
||||||
|
@ -121,41 +124,49 @@ static void gamma_control_manager_bind(struct wl_client *client, void *data,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_resource_set_implementation(resource, &gamma_control_manager_impl,
|
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 wlr_gamma_control_manager *wlr_gamma_control_manager_create(
|
||||||
struct wl_display *display) {
|
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));
|
calloc(1, sizeof(struct wlr_gamma_control_manager));
|
||||||
if (!gamma_control_manager) {
|
if (!manager) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
struct wl_global *wl_global = wl_global_create(display,
|
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);
|
gamma_control_manager_bind);
|
||||||
if (!wl_global) {
|
if (!wl_global) {
|
||||||
free(gamma_control_manager);
|
free(manager);
|
||||||
return NULL;
|
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;
|
manager->display_destroy.notify = handle_display_destroy;
|
||||||
}
|
wl_display_add_destroy_listener(display, &manager->display_destroy);
|
||||||
|
|
||||||
void wlr_gamma_control_manager_destroy(
|
return manager;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,12 @@ static void wl_output_bind(struct wl_client *wl_client, void *data,
|
||||||
wl_output_send_to_resource(wl_resource);
|
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_global *wlr_output_create_global(struct wlr_output *wlr_output,
|
||||||
struct wl_display *display) {
|
struct wl_display *display) {
|
||||||
if (wlr_output->wl_global != NULL) {
|
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,
|
struct wl_global *wl_global = wl_global_create(display,
|
||||||
&wl_output_interface, 3, wlr_output, wl_output_bind);
|
&wl_output_interface, 3, wlr_output, wl_output_bind);
|
||||||
wlr_output->wl_global = wl_global;
|
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;
|
return wl_global;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +137,7 @@ void wlr_output_destroy_global(struct wlr_output *wlr_output) {
|
||||||
if (wlr_output->wl_global == NULL) {
|
if (wlr_output->wl_global == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
wl_list_remove(&wlr_output->display_destroy.link);
|
||||||
struct wl_resource *resource, *tmp;
|
struct wl_resource *resource, *tmp;
|
||||||
wl_resource_for_each_safe(resource, tmp, &wlr_output->wl_resources) {
|
wl_resource_for_each_safe(resource, tmp, &wlr_output->wl_resources) {
|
||||||
struct wl_list *link = wl_resource_get_link(resource);
|
struct wl_list *link = wl_resource_get_link(resource);
|
||||||
|
@ -702,52 +713,6 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) {
|
||||||
free(cursor);
|
free(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_output_transform_apply_to_box(enum wl_output_transform transform,
|
|
||||||
struct wlr_box *box, struct wlr_box *dest) {
|
|
||||||
if (transform % 2 == 0) {
|
|
||||||
dest->width = box->width;
|
|
||||||
dest->height = box->height;
|
|
||||||
} else {
|
|
||||||
dest->width = box->height;
|
|
||||||
dest->height = box->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (transform) {
|
|
||||||
case WL_OUTPUT_TRANSFORM_NORMAL:
|
|
||||||
dest->x = box->x;
|
|
||||||
dest->y = box->y;
|
|
||||||
break;
|
|
||||||
case WL_OUTPUT_TRANSFORM_90:
|
|
||||||
dest->x = box->y;
|
|
||||||
dest->y = box->width - box->x;
|
|
||||||
break;
|
|
||||||
case WL_OUTPUT_TRANSFORM_180:
|
|
||||||
dest->x = box->width - box->x;
|
|
||||||
dest->y = box->height - box->y;
|
|
||||||
break;
|
|
||||||
case WL_OUTPUT_TRANSFORM_270:
|
|
||||||
dest->x = box->height - box->y;
|
|
||||||
dest->y = box->x;
|
|
||||||
break;
|
|
||||||
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
|
||||||
dest->x = box->width - box->x;
|
|
||||||
dest->y = box->y;
|
|
||||||
break;
|
|
||||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
|
||||||
dest->x = box->y;
|
|
||||||
dest->y = box->x;
|
|
||||||
break;
|
|
||||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
|
||||||
dest->x = box->x;
|
|
||||||
dest->y = box->height - box->y;
|
|
||||||
break;
|
|
||||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
|
||||||
dest->x = box->height - box->y;
|
|
||||||
dest->y = box->width - box->x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum wl_output_transform wlr_output_transform_invert(
|
enum wl_output_transform wlr_output_transform_invert(
|
||||||
enum wl_output_transform transform) {
|
enum wl_output_transform transform) {
|
||||||
if ((transform & WL_OUTPUT_TRANSFORM_90) &&
|
if ((transform & WL_OUTPUT_TRANSFORM_90) &&
|
||||||
|
|
|
@ -26,6 +26,21 @@ struct screenshot_state {
|
||||||
struct wl_listener frame_listener;
|
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) {
|
static void output_frame_notify(struct wl_listener *listener, void *_data) {
|
||||||
struct screenshot_state *state = wl_container_of(listener, state,
|
struct screenshot_state *state = wl_container_of(listener, state,
|
||||||
frame_listener);
|
frame_listener);
|
||||||
|
@ -102,7 +117,8 @@ static void screenshooter_shoot(struct wl_client *client,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_resource_set_implementation(screenshot->resource, NULL, screenshot,
|
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,
|
wlr_log(L_DEBUG, "new screenshot %p (res %p)", screenshot,
|
||||||
screenshot->resource);
|
screenshot->resource);
|
||||||
|
@ -144,6 +160,25 @@ static void screenshooter_bind(struct wl_client *wl_client, void *data,
|
||||||
screenshooter, NULL);
|
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_screenshooter *wlr_screenshooter_create(struct wl_display *display,
|
||||||
struct wlr_renderer *renderer) {
|
struct wlr_renderer *renderer) {
|
||||||
struct wlr_screenshooter *screenshooter =
|
struct wlr_screenshooter *screenshooter =
|
||||||
|
@ -153,6 +188,11 @@ struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display,
|
||||||
}
|
}
|
||||||
screenshooter->renderer = renderer;
|
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,
|
screenshooter->wl_global = wl_global_create(display,
|
||||||
&orbital_screenshooter_interface, 1, screenshooter, screenshooter_bind);
|
&orbital_screenshooter_interface, 1, screenshooter, screenshooter_bind);
|
||||||
if (screenshooter->wl_global == NULL) {
|
if (screenshooter->wl_global == NULL) {
|
||||||
|
@ -162,12 +202,3 @@ struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display,
|
||||||
|
|
||||||
return screenshooter;
|
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_create(struct wl_display *display, const char *name) {
|
||||||
struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat));
|
struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat));
|
||||||
if (!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_begin);
|
||||||
wl_signal_init(&wlr_seat->events.touch_grab_end);
|
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;
|
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 wlr_seat_client *wlr_seat_client_for_wl_client(struct wlr_seat *wlr_seat,
|
||||||
struct wl_client *wl_client) {
|
struct wl_client *wl_client) {
|
||||||
assert(wlr_seat);
|
assert(wlr_seat);
|
||||||
|
|
|
@ -140,6 +140,31 @@ static void server_decoration_manager_bind(struct wl_client *client, void *data,
|
||||||
manager->default_mode);
|
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 wlr_server_decoration_manager *wlr_server_decoration_manager_create(
|
||||||
struct wl_display *display) {
|
struct wl_display *display) {
|
||||||
struct wlr_server_decoration_manager *manager =
|
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->wl_resources);
|
||||||
wl_list_init(&manager->decorations);
|
wl_list_init(&manager->decorations);
|
||||||
wl_signal_init(&manager->events.new_decoration);
|
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;
|
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));
|
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 *wlr_wl_shell_create(struct wl_display *display) {
|
||||||
struct wlr_wl_shell *wl_shell = calloc(1, sizeof(struct wlr_wl_shell));
|
struct wlr_wl_shell *wl_shell = calloc(1, sizeof(struct wlr_wl_shell));
|
||||||
if (!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->surfaces);
|
||||||
wl_list_init(&wl_shell->popup_grabs);
|
wl_list_init(&wl_shell->popup_grabs);
|
||||||
wl_signal_init(&wl_shell->events.new_surface);
|
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;
|
return wl_shell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,14 +598,14 @@ void wlr_wl_shell_destroy(struct wlr_wl_shell *wlr_wl_shell) {
|
||||||
if (!wlr_wl_shell) {
|
if (!wlr_wl_shell) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
wl_list_remove(&wlr_wl_shell->display_destroy.link);
|
||||||
struct wl_resource *resource = NULL, *temp = NULL;
|
struct wl_resource *resource = NULL, *temp = NULL;
|
||||||
wl_resource_for_each_safe(resource, temp, &wlr_wl_shell->wl_resources) {
|
wl_resource_for_each_safe(resource, temp, &wlr_wl_shell->wl_resources) {
|
||||||
struct wl_list *link = wl_resource_get_link(resource);
|
// shell_destroy will remove the resource from the list
|
||||||
wl_list_remove(link);
|
wl_resource_destroy(resource);
|
||||||
}
|
}
|
||||||
// TODO: destroy surfaces
|
// 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);
|
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 *wlr_xdg_shell_v6_create(struct wl_display *display) {
|
||||||
struct wlr_xdg_shell_v6 *xdg_shell =
|
struct wlr_xdg_shell_v6 *xdg_shell =
|
||||||
calloc(1, sizeof(struct wlr_xdg_shell_v6));
|
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);
|
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;
|
return xdg_shell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1279,8 +1288,8 @@ void wlr_xdg_shell_v6_destroy(struct wlr_xdg_shell_v6 *xdg_shell) {
|
||||||
if (!xdg_shell) {
|
if (!xdg_shell) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: this segfault (wl_display->registry_resource_list is not init)
|
wl_list_remove(&xdg_shell->display_destroy.link);
|
||||||
// wl_global_destroy(xdg_shell->wl_global);
|
wl_global_destroy(xdg_shell->wl_global);
|
||||||
free(xdg_shell);
|
free(xdg_shell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,38 +125,25 @@ static void exec_xwayland(struct wlr_xwayland *wlr_xwayland) {
|
||||||
execvp("Xwayland", argv);
|
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) {
|
static void wlr_xwayland_finish(struct wlr_xwayland *wlr_xwayland) {
|
||||||
if (!wlr_xwayland || wlr_xwayland->display == -1) {
|
if (!wlr_xwayland || wlr_xwayland->display == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wlr_xwayland->cursor != NULL) {
|
||||||
|
free(wlr_xwayland->cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
xwm_destroy(wlr_xwayland->xwm);
|
||||||
|
|
||||||
if (wlr_xwayland->client) {
|
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);
|
wl_client_destroy(wlr_xwayland->client);
|
||||||
}
|
}
|
||||||
if (wlr_xwayland->sigusr1_source) {
|
if (wlr_xwayland->sigusr1_source) {
|
||||||
wl_event_source_remove(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[0]);
|
||||||
safe_close(wlr_xwayland->x_fd[1]);
|
safe_close(wlr_xwayland->x_fd[1]);
|
||||||
safe_close(wlr_xwayland->wl_fd[0]);
|
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[0]);
|
||||||
safe_close(wlr_xwayland->wm_fd[1]);
|
safe_close(wlr_xwayland->wm_fd[1]);
|
||||||
|
|
||||||
|
wl_list_remove(&wlr_xwayland->display_destroy.link);
|
||||||
|
|
||||||
unlink_display_sockets(wlr_xwayland->display);
|
unlink_display_sockets(wlr_xwayland->display);
|
||||||
wlr_xwayland->display = -1;
|
wlr_xwayland->display = -1;
|
||||||
unsetenv("DISPLAY");
|
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) {
|
static int xserver_handle_ready(int signal_number, void *data) {
|
||||||
struct wlr_xwayland *wlr_xwayland = data;
|
struct wlr_xwayland *wlr_xwayland = data;
|
||||||
|
|
||||||
|
@ -231,6 +253,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.new_surface);
|
||||||
wl_signal_init(&wlr_xwayland->events.ready);
|
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);
|
wlr_xwayland->display = open_display_sockets(wlr_xwayland->x_fd);
|
||||||
if (wlr_xwayland->display < 0) {
|
if (wlr_xwayland->display < 0) {
|
||||||
wlr_xwayland_finish(wlr_xwayland);
|
wlr_xwayland_finish(wlr_xwayland);
|
||||||
|
@ -256,11 +281,13 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland,
|
||||||
|
|
||||||
wlr_xwayland->wl_fd[0] = -1; /* not ours anymore */
|
wlr_xwayland->wl_fd[0] = -1; /* not ours anymore */
|
||||||
|
|
||||||
wlr_xwayland->destroy_listener.notify = xwayland_destroy_event;
|
wlr_xwayland->client_destroy.notify = handle_client_destroy;
|
||||||
wl_client_add_destroy_listener(wlr_xwayland->client, &wlr_xwayland->destroy_listener);
|
wl_client_add_destroy_listener(wlr_xwayland->client,
|
||||||
|
&wlr_xwayland->client_destroy);
|
||||||
|
|
||||||
struct wl_event_loop *loop = wl_display_get_event_loop(wl_display);
|
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) {
|
if ((wlr_xwayland->pid = fork()) == 0) {
|
||||||
/* Double-fork, but we need to forward SIGUSR1 once Xserver(1)
|
/* Double-fork, but we need to forward SIGUSR1 once Xserver(1)
|
||||||
|
|
|
@ -1093,6 +1093,12 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
||||||
if (xwm->cursor) {
|
if (xwm->cursor) {
|
||||||
xcb_free_cursor(xwm->xcb_conn, 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) {
|
if (xwm->event_source) {
|
||||||
wl_event_source_remove(xwm->event_source);
|
wl_event_source_remove(xwm->event_source);
|
||||||
}
|
}
|
||||||
|
@ -1100,6 +1106,9 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
||||||
wl_list_for_each_safe(xsurface, tmp, &xwm->surfaces, link) {
|
wl_list_for_each_safe(xsurface, tmp, &xwm->surfaces, link) {
|
||||||
wlr_xwayland_surface_destroy(xsurface);
|
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);
|
wl_list_remove(&xwm->compositor_surface_create.link);
|
||||||
xcb_disconnect(xwm->xcb_conn);
|
xcb_disconnect(xwm->xcb_conn);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue