rdprail.c
/* 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