From 6967a31450441fc5605c05db6f65505dace4b263 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Sat, 8 Jun 2024 10:07:59 +0200 Subject: wayland/core: move to new impl (#6268) * wayland/core/dmabuf: move to new impl it's the final countdown --- src/protocols/Viewporter.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/protocols/Viewporter.cpp (limited to 'src/protocols/Viewporter.cpp') diff --git a/src/protocols/Viewporter.cpp b/src/protocols/Viewporter.cpp new file mode 100644 index 00000000..8cb69dbe --- /dev/null +++ b/src/protocols/Viewporter.cpp @@ -0,0 +1,126 @@ +#include "Viewporter.hpp" +#include "core/Compositor.hpp" +#include + +#define LOGM PROTO::viewport->protoLog + +CViewportResource::CViewportResource(SP resource_, SP surface_) : surface(surface_), resource(resource_) { + if (!good()) + return; + + resource->setDestroy([this](CWpViewport* r) { PROTO::viewport->destroyResource(this); }); + resource->setOnDestroy([this](CWpViewport* r) { PROTO::viewport->destroyResource(this); }); + + resource->setSetDestination([this](CWpViewport* r, int32_t x, int32_t y) { + if (!surface) { + r->error(WP_VIEWPORT_ERROR_NO_SURFACE, "Surface is gone"); + return; + } + + if (x == -1 && y == -1) { + surface->pending.viewport.hasDestination = false; + return; + } + + if (x <= 0 || y <= 0) { + r->error(WP_VIEWPORT_ERROR_BAD_SIZE, "Size was <= 0"); + return; + } + + surface->pending.viewport.hasDestination = true; + surface->pending.viewport.destination = {x, y}; + }); + + resource->setSetSource([this](CWpViewport* r, wl_fixed_t fx, wl_fixed_t fy, wl_fixed_t fw, wl_fixed_t fh) { + if (!surface) { + r->error(WP_VIEWPORT_ERROR_NO_SURFACE, "Surface is gone"); + return; + } + + double x = wl_fixed_to_double(fx), y = wl_fixed_to_double(fy), w = wl_fixed_to_double(fw), h = wl_fixed_to_double(fh); + + if (x == -1 && y == -1 && w == -1 && h == -1) { + surface->pending.viewport.hasSource = false; + return; + } + + if (x < 0 || y < 0) { + r->error(WP_VIEWPORT_ERROR_BAD_SIZE, "Pos was < 0"); + return; + } + + surface->pending.viewport.hasSource = true; + surface->pending.viewport.source = {x, y, w, h}; + }); +} + +CViewportResource::~CViewportResource() { + if (!surface) + return; + + surface->pending.viewport.hasDestination = false; + surface->pending.viewport.hasSource = false; +} + +bool CViewportResource::good() { + return resource->resource(); +} + +void CViewportResource::verify() { + if (!surface) + return; + + if (surface->pending.viewport.hasSource) { + auto& src = surface->pending.viewport.source; + + if (src.w + src.x > surface->pending.size.x || src.h + src.y > surface->pending.size.y) { + resource->error(WP_VIEWPORT_ERROR_BAD_VALUE, "Box doesn't fit"); + return; + } + } +} + +CViewporterResource::CViewporterResource(SP resource_) : resource(resource_) { + if (!good()) + return; + + resource->setDestroy([this](CWpViewporter* r) { PROTO::viewport->destroyResource(this); }); + resource->setOnDestroy([this](CWpViewporter* r) { PROTO::viewport->destroyResource(this); }); + + resource->setGetViewport([](CWpViewporter* r, uint32_t id, wl_resource* surf) { + const auto RESOURCE = PROTO::viewport->m_vViewports.emplace_back( + makeShared(makeShared(r->client(), r->version(), id), CWLSurfaceResource::fromResource(surf))); + + if (!RESOURCE->good()) { + r->noMemory(); + PROTO::viewport->m_vViewports.pop_back(); + return; + } + }); +} + +bool CViewporterResource::good() { + return resource->resource(); +} + +CViewporterProtocol::CViewporterProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { + ; +} + +void CViewporterProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) { + const auto RESOURCE = m_vManagers.emplace_back(makeShared(makeShared(client, ver, id))); + + if (!RESOURCE->good()) { + wl_client_post_no_memory(client); + m_vManagers.pop_back(); + return; + } +} + +void CViewporterProtocol::destroyResource(CViewporterResource* resource) { + std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; }); +} + +void CViewporterProtocol::destroyResource(CViewportResource* resource) { + std::erase_if(m_vViewports, [&](const auto& other) { return other.get() == resource; }); +} -- cgit v1.2.3