Untitled

 avatar
unknown
plain_text
a month ago
4.1 kB
2
Indexable
#include <wayfire/compositor.hpp>
#include <wayfire/output.hpp>
#include <wayfire/core.hpp>
#include <wayfire/util.hpp>
#include <wayland-server.h>
#include <gbm.h>
#include <fcntl.h>
#include "rdprail.h"
#include "rdprail_backend.h"

class wayfire_rdp_backend 
{
    private:
        wf::compositor_core_t *core;
        GfxRedirServerContext *rdp_ctx;
        struct gbm_device *gbm;
        struct wlr_backend *backend;

    public:
        wayfire_rdp_backend(wf::compositor_core_t *core) : core(core) 
        {
            // Initialize GPU support
            int gpu_fd = open("/dev/dri/card0", O_RDWR);
            if (gpu_fd < 0) {
                LOGE("Failed to open GPU device");
                throw std::runtime_error("Failed to open GPU device");
            }

            gbm = gbm_create_device(gpu_fd);
            if (!gbm) {
                close(gpu_fd);
                LOGE("Failed to create GBM device");
                throw std::runtime_error("Failed to create GBM device");
            }

            // Initialize RDP context
            rdp_ctx = new GfxRedirServerContext();
            if (!rdp_ctx) {
                gbm_device_destroy(gbm);
                LOGE("Failed to allocate RDP context");
                throw std::runtime_error("Failed to create RDP context");
            }

            // Set up RDP callbacks
            rdp_ctx->OpenPool = [](GfxRedirServerContext *ctx, 
                GFXREDIR_OPEN_POOL_PDU *open_pool) -> int {
                static uint32_t next_pool_id = 1;
                open_pool->poolId = next_pool_id++;
                LOGD("RDP: Created pool %u", open_pool->poolId);
                return 0;
            };

            rdp_ctx->CreateBuffer = [](GfxRedirServerContext *ctx, 
                GFXREDIR_CREATE_BUFFER_PDU *create_buffer) -> int {
                static uint32_t next_buffer_id = 1;
                create_buffer->bufferId = next_buffer_id++;
                LOGD("RDP: Created buffer %u in pool %u", 
                    create_buffer->bufferId, create_buffer->poolId);
                return 0;
            };

            // Create RDP backend
            backend = wlr_rdp_backend_create(core->get_display(), 
                NULL, rdp_ctx);
            if (!backend) {
                delete rdp_ctx;
                gbm_device_destroy(gbm);
                LOGE("Failed to create RDP backend");
                throw std::runtime_error("Failed to create RDP backend");
            }

            // Set up GBM allocator
            struct wlr_rdp_backend *rdp = 
                get_rdp_backend_from_backend(backend);
            rdp->allocator = wlr_rdp_gbm_allocator_create(rdp_ctx, gbm);
            if (!rdp->allocator) {
                wlr_backend_destroy(backend);
                delete rdp_ctx;
                gbm_device_destroy(gbm);
                LOGE("Failed to create GBM allocator");
                throw std::runtime_error("Failed to create GBM allocator");
            }

            LOGI("RDP backend initialized successfully");
        }

        ~wayfire_rdp_backend() 
        {
            if (backend) {
                wlr_backend_destroy(backend);
            }
            if (rdp_ctx) {
                delete rdp_ctx;
            }
            if (gbm) {
                gbm_device_destroy(gbm);
            }
        }

        bool start() 
        {
            if (!wlr_backend_start(backend)) {
                LOGE("Failed to start RDP backend");
                return false;
            }
            LOGI("RDP backend started");
            return true;
        }
};

void wayfire_rdp_init(wf::compositor_core_t *core)
{
    static std::unique_ptr<wayfire_rdp_backend> rdp_backend;

    try {
        rdp_backend = std::make_unique<wayfire_rdp_backend>(core);
        if (!rdp_backend->start()) {
            LOGE("Failed to start RDP support");
            rdp_backend.reset();
            return;
        }
        LOGI("RDP support initialized successfully");
    } catch (const std::exception &e) {
        LOGE("Failed to initialize RDP support: %s", e.what());
        rdp_backend.reset();
    }
}
Leave a Comment