rdprail.c

 avatar
unknown
plain_text
a month ago
4.1 kB
1
Indexable
/* rdprail.c */
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wlr/render/allocator.h>
#include <wlr/render/drm_format_set.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/util/log.h>
#include <drm/drm_fourcc.h>

#include "rdprail.h"

// Declare external functions
extern void wlr_buffer_init(struct wlr_buffer *buffer, 
                             void (*destroy)(struct wlr_buffer *buffer), 
                             int width, int height);

// Placeholder implementation for shared memory retrieval
void* rdp_get_shared_memory(uint32_t pool_id, size_t *size) {
    // In a real implementation, this would use platform-specific 
    // shared memory APIs or the RDP library's memory allocation
    *size = 1024 * 1024;  // 1MB
    return malloc(*size);  // Dummy allocation
}

static void wlr_rdp_buffer_destroy(struct wlr_buffer *buffer) {
    struct wlr_rdp_buffer *rdp_buffer = 
        wl_container_of(buffer, rdp_buffer, buffer);
    
    // Free RDP-specific resources
    if (rdp_buffer->rdp_memory) {
        free(rdp_buffer->rdp_memory);
    }
    
    free(rdp_buffer);
}

// The external function provided by wlroots to compute readable data
extern bool wlr_buffer_compute_readable_data(
    struct wlr_buffer *buffer,
    void **data,
    uint32_t *format,
    size_t *stride
);

static struct wlr_buffer *rdp_allocator_create_buffer(
        struct wlr_allocator *alloc,
        int width, int height,
        const struct wlr_drm_format *format) {
    struct wlr_rdp_allocator *rdp_alloc = 
        wl_container_of(alloc, rdp_alloc, base);
    
    // Create RDP pool and buffer
    GFXREDIR_OPEN_POOL_PDU open_pool = {0};
    
    // Call OpenPool method
    if (rdp_alloc->redir_ctx->OpenPool(rdp_alloc->redir_ctx, &open_pool) != 0) {
        wlr_log(WLR_ERROR, "Failed to open RDP pool");
        return NULL;
    }

    GFXREDIR_CREATE_BUFFER_PDU create_buffer = {
        .poolId = open_pool.poolId,
        .width = width,
        .height = height,
        .format = 1  // Placeholder for GFXREDIR_BUFFER_PIXEL_FORMAT_ARGB_8888
    };

    // Call CreateBuffer method
    if (rdp_alloc->redir_ctx->CreateBuffer(rdp_alloc->redir_ctx, &create_buffer) != 0) {
        wlr_log(WLR_ERROR, "Failed to create RDP buffer");
        return NULL;
    }

    // Allocate wlroots buffer
    struct wlr_rdp_buffer *buffer = calloc(1, sizeof(struct wlr_rdp_buffer));
    if (!buffer) {
        wlr_log(WLR_ERROR, "Failed to allocate RDP buffer struct");
        return NULL;
    }

    // Set RDP-specific properties
    buffer->pool_id = open_pool.poolId;
    buffer->buffer_id = create_buffer.bufferId;
    buffer->width = width;
    buffer->height = height;
    
    // Get shared memory for the buffer
    buffer->rdp_memory = rdp_get_shared_memory(open_pool.poolId, &buffer->rdp_memory_size);
    if (!buffer->rdp_memory) {
        wlr_log(WLR_ERROR, "Failed to get shared memory");
        free(buffer);
        return NULL;
    }

    // Initialize buffer with custom destroy method
    wlr_buffer_init(&buffer->buffer, wlr_rdp_buffer_destroy, width, height);

    return &buffer->buffer;
}

static void rdp_allocator_destroy(struct wlr_allocator *alloc) {
    struct wlr_rdp_allocator *rdp_alloc = 
        wl_container_of(alloc, rdp_alloc, base);
    
    free(rdp_alloc);
}

static const struct wlr_allocator_interface rdp_allocator_impl = {
    .create_buffer = rdp_allocator_create_buffer,
    .destroy = rdp_allocator_destroy,
};

struct wlr_allocator *wlr_rdp_allocator_create(
        GfxRedirServerContext *redir_ctx) {
    if (!redir_ctx) {
        wlr_log(WLR_ERROR, "Invalid RDP context");
        return NULL;
    }
    
    struct wlr_rdp_allocator *alloc = 
        calloc(1, sizeof(struct wlr_rdp_allocator));
    if (!alloc) {
        wlr_log(WLR_ERROR, "Failed to allocate RDP allocator");
        return NULL;
    }
    
    // Initialize allocator
    wlr_allocator_init(&alloc->base, &rdp_allocator_impl, 0);
    
    // Store RDP context
    alloc->redir_ctx = redir_ctx;
    
    return &alloc->base;
}
Leave a Comment