Untitled
#include <assert.h> #include <stdlib.h> #include <wlr/backend.h> #include <wlr/util/log.h> #include <wayland-server-core.h> #include "rdprail.h" #include "rdprail_backend.h" #include "rdprail_output.h" // Function prototypes static void handle_display_destroy(struct wl_listener *listener, void *data); static bool rdp_backend_start(struct wlr_backend *wlr_backend); static void rdp_backend_destroy(struct wlr_backend *wlr_backend); // Backend implementation structure static const struct wlr_backend_impl backend_impl = { .start = rdp_backend_start, .destroy = rdp_backend_destroy, }; static bool rdp_backend_start(struct wlr_backend *wlr_backend) { struct wlr_rdp_backend *backend = wl_container_of(wlr_backend, backend, base); if (backend->started) { return true; } // Create an initial output if (!wlr_rdp_output_create(backend)) { wlr_log(WLR_ERROR, "Failed to create RDP output"); return false; } backend->started = true; return true; } static void rdp_backend_destroy(struct wlr_backend *wlr_backend) { struct wlr_rdp_backend *backend = wl_container_of(wlr_backend, backend, base); if (!backend) { return; } // Remove display destroy listener wl_list_remove(&backend->listeners.display_destroy.link); // Emit destroy signal before cleanup wlr_signal_emit_safe(&backend->events.destroy, backend); // Destroy allocator if it exists if (backend->allocator) { wlr_allocator_destroy(backend->allocator); } free(backend); } static void handle_display_destroy(struct wl_listener *listener, void *data) { struct wlr_rdp_backend *backend = wl_container_of(listener, backend, listeners.display_destroy); // Clean up backend resources wlr_backend_destroy(&backend->base); } struct wlr_backend *wlr_rdp_backend_create(struct wl_display *display, struct wlr_session *session, void *redir_ctx) { struct wlr_rdp_backend *backend = calloc(1, sizeof(*backend)); if (!backend) { wlr_log(WLR_ERROR, "Failed to allocate RDP backend"); return NULL; } // Initialize backend backend->base.impl = &backend_impl; backend->display = display; backend->session = session; backend->redir_ctx = (GfxRedirServerContext *)redir_ctx; // Initialize lists wl_list_init(&backend->outputs); // Initialize signals wl_signal_init(&backend->events.destroy); wl_signal_init(&backend->events.new_output); wl_signal_init(&backend->events.new_input); // Setup display destruction listener backend->listeners.display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(display, &backend->listeners.display_destroy); return &backend->base; } bool wlr_backend_is_rdp(struct wlr_backend *backend) { return backend && backend->impl == &backend_impl; } struct wlr_rdp_backend *get_rdp_backend_from_backend(struct wlr_backend *backend) { if (!wlr_backend_is_rdp(backend)) { return NULL; } return wl_container_of(backend, backend, base); }
Leave a Comment