#include #include #include #include #include #include "types/wlr_region.h" #include "types/wlr_surface.h" #include "util/signal.h" #define COMPOSITOR_VERSION 4 static const struct wl_compositor_interface compositor_impl; static struct wlr_compositor *compositor_from_resource( struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &wl_compositor_interface, &compositor_impl)); return wl_resource_get_user_data(resource); } static void compositor_create_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id) { struct wlr_compositor *compositor = compositor_from_resource(resource); struct wlr_surface *surface = surface_create(client, wl_resource_get_version(resource), id, compositor->renderer); if (surface == NULL) { wl_client_post_no_memory(client); return; } wlr_signal_emit_safe(&compositor->events.new_surface, surface); } static void compositor_create_region(struct wl_client *client, struct wl_resource *resource, uint32_t id) { region_create(client, wl_resource_get_version(resource), id); } static const struct wl_compositor_interface compositor_impl = { .create_surface = compositor_create_surface, .create_region = compositor_create_region, }; static void compositor_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id) { struct wlr_compositor *compositor = data; struct wl_resource *resource = wl_resource_create(wl_client, &wl_compositor_interface, version, id); if (resource == NULL) { wl_client_post_no_memory(wl_client); return; } wl_resource_set_implementation(resource, &compositor_impl, compositor, NULL); } static void compositor_handle_display_destroy( struct wl_listener *listener, void *data) { struct wlr_compositor *compositor = wl_container_of(listener, compositor, display_destroy); wlr_signal_emit_safe(&compositor->events.destroy, NULL); wl_list_remove(&compositor->display_destroy.link); wl_global_destroy(compositor->global); free(compositor); } struct wlr_compositor *wlr_compositor_create(struct wl_display *display, struct wlr_renderer *renderer) { struct wlr_compositor *compositor = calloc(1, sizeof(*compositor)); if (!compositor) { return NULL; } compositor->global = wl_global_create(display, &wl_compositor_interface, COMPOSITOR_VERSION, compositor, compositor_bind); if (!compositor->global) { free(compositor); return NULL; } compositor->renderer = renderer; wl_signal_init(&compositor->events.new_surface); wl_signal_init(&compositor->events.destroy); compositor->display_destroy.notify = compositor_handle_display_destroy; wl_display_add_destroy_listener(display, &compositor->display_destroy); return compositor; }