Untitled

 avatar
unknown
plain_text
a month ago
3.2 kB
1
Indexable
#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