aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/protocols/SinglePixel.cpp
blob: d800539d84b8b4dfcb068c941d00023a86e53eb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "SinglePixel.hpp"
#include <limits>
#include "render/Renderer.hpp"

CSinglePixelBuffer::CSinglePixelBuffer(uint32_t id, wl_client* client, CColor col_) {
    LOGM(LOG, "New single-pixel buffer with color 0x{:x}", col_.getAsHex());

    color = col_.getAsHex();

    g_pHyprRenderer->makeEGLCurrent();

    opaque = col_.a >= 1.F;

    texture = makeShared<CTexture>(DRM_FORMAT_ARGB8888, (uint8_t*)&color, 4, Vector2D{1, 1});

    resource = CWLBufferResource::create(makeShared<CWlBuffer>(client, 1, id));

    success = texture->m_iTexID;

    size = {1, 1};

    if (!success)
        Debug::log(ERR, "Failed creating a single pixel texture: null texture id");
}

CSinglePixelBuffer::~CSinglePixelBuffer() {
    ;
}

Aquamarine::eBufferCapability CSinglePixelBuffer::caps() {
    return Aquamarine::eBufferCapability::BUFFER_CAPABILITY_DATAPTR;
}

Aquamarine::eBufferType CSinglePixelBuffer::type() {
    return Aquamarine::eBufferType::BUFFER_TYPE_SHM;
}

bool CSinglePixelBuffer::isSynchronous() {
    return true;
}

void CSinglePixelBuffer::update(const CRegion& damage) {
    ;
}

Aquamarine::SDMABUFAttrs CSinglePixelBuffer::dmabuf() {
    return {.success = false};
}

std::tuple<uint8_t*, uint32_t, size_t> CSinglePixelBuffer::beginDataPtr(uint32_t flags) {
    return {(uint8_t*)&color, DRM_FORMAT_ARGB8888, 4};
}

void CSinglePixelBuffer::endDataPtr() {
    ;
}

bool CSinglePixelBuffer::good() {
    return resource->good();
}

CSinglePixelBufferResource::CSinglePixelBufferResource(uint32_t id, wl_client* client, CColor color) {
    buffer = makeShared<CSinglePixelBuffer>(id, client, color);

    if (!buffer->good())
        return;

    buffer->resource->buffer = buffer;

    listeners.bufferResourceDestroy = buffer->events.destroy.registerListener([this](std::any d) {
        listeners.bufferResourceDestroy.reset();
        PROTO::singlePixel->destroyResource(this);
    });
}

CSinglePixelBufferResource::~CSinglePixelBufferResource() {
    ;
}

bool CSinglePixelBufferResource::good() {
    return buffer->good();
}

CSinglePixelBufferManagerResource::CSinglePixelBufferManagerResource(SP<CWpSinglePixelBufferManagerV1> resource_) : resource(resource_) {
    if (!good())
        return;

    resource->setDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });
    resource->setOnDestroy([this](CWpSinglePixelBufferManagerV1* r) { PROTO::singlePixel->destroyResource(this); });

    resource->setCreateU32RgbaBuffer([this](CWpSinglePixelBufferManagerV1* res, uint32_t id, uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
        CColor     color{r / (float)std::numeric_limits<uint32_t>::max(), g / (float)std::numeric_limits<uint32_t>::max(), b / (float)std::numeric_limits<uint32_t>::max(),
                     a / (float)std::numeric_limits<uint32_t>::max()};
        const auto RESOURCE = PROTO::singlePixel->m_vBuffers.emplace_back(makeShared<CSinglePixelBufferResource>(id, resource->client(), color));

        if (!RESOURCE->good()) {
            res->noMemory();
            PROTO::singlePixel->m_vBuffers.pop_back();
            return;
        }
    });
}

bool CSinglePixelBufferManagerResource::good() {
    return resource->resource();
}

CSinglePixelProtocol::CSinglePixelProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
    ;
}

void CSinglePixelProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
    const auto RESOURCE = m_vManagers.emplace_back(makeShared<CSinglePixelBufferManagerResource>(makeShared<CWpSinglePixelBufferManagerV1>(client, ver, id)));

    if (!RESOURCE->good()) {
        wl_client_post_no_memory(client);
        m_vManagers.pop_back();
        return;
    }
}

void CSinglePixelProtocol::destroyResource(CSinglePixelBufferManagerResource* res) {
    std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == res; });
}

void CSinglePixelProtocol::destroyResource(CSinglePixelBufferResource* surf) {
    std::erase_if(m_vBuffers, [&](const auto& other) { return other.get() == surf; });
}