From 37128bfd43a3d86d270c09e34f18fe4df48c6b35 Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Mon, 21 Aug 2023 19:36:09 +0200 Subject: internal: Wayland Protocol impl improvements (#2944) --- src/protocols/WaylandProtocol.cpp | 60 ++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 11 deletions(-) (limited to 'src/protocols/WaylandProtocol.cpp') diff --git a/src/protocols/WaylandProtocol.cpp b/src/protocols/WaylandProtocol.cpp index b5acffea..1ddf6f4b 100644 --- a/src/protocols/WaylandProtocol.cpp +++ b/src/protocols/WaylandProtocol.cpp @@ -1,7 +1,12 @@ #include "WaylandProtocol.hpp" #include "../Compositor.hpp" -CWaylandResource::CWaylandResource(wl_client* client, const wl_interface* wlInterface, uint32_t version, uint32_t id, bool destroyInDestructor) { +static void resourceDestroyNotify(wl_listener* listener, void* data) { + CWaylandResource* pResource = wl_container_of(listener, pResource, m_liResourceDestroy); + pResource->markDefunct(); +} + +CWaylandResource::CWaylandResource(wl_client* client, const wl_interface* wlInterface, uint32_t version, uint32_t id) { m_pWLResource = wl_resource_create(client, wlInterface, version, id); if (!m_pWLResource) { @@ -9,21 +14,42 @@ CWaylandResource::CWaylandResource(wl_client* client, const wl_interface* wlInte return; } - m_pWLClient = client; - m_bDestroyInDestructor = destroyInDestructor; + wl_resource_set_user_data(m_pWLResource, this); + + m_pWLClient = client; - Debug::log(LOG, "[wl res %lx] created", m_pWLResource); + wl_list_init(&m_liResourceDestroy.link); + m_liResourceDestroy.notify = resourceDestroyNotify; + wl_resource_add_destroy_listener(m_pWLResource, &m_liResourceDestroy); + + Debug::log(TRACE, "[wl res %lx] created", m_pWLResource); +} + +void CWaylandResource::markDefunct() { + if (m_bDefunct) + return; + + Debug::log(TRACE, "[wl res %lx] now defunct", m_pWLResource); + m_bDefunct = true; } CWaylandResource::~CWaylandResource() { - if (m_pWLResource && m_bDestroyInDestructor) - wl_resource_destroy(m_pWLResource); + const bool DESTROY = m_pWLResource && !m_bDefunct; - Debug::log(LOG, "[wl res %lx] destroyed (wl_resource_destroy %s)", m_pWLResource, (m_pWLResource && m_bDestroyInDestructor ? "sent" : "not sent")); + wl_list_remove(&m_liResourceDestroy.link); + wl_list_init(&m_liResourceDestroy.link); + + if (m_pWLResource) + wl_resource_set_user_data(m_pWLResource, nullptr); + + Debug::log(TRACE, "[wl res %lx] destroying (wl_resource_destroy will be %s)", m_pWLResource, (DESTROY ? "sent" : "not sent")); + + if (DESTROY) + wl_resource_destroy(m_pWLResource); } bool CWaylandResource::good() { - return resource(); + return m_pWLResource && !m_bDefunct; } wl_resource* CWaylandResource::resource() { @@ -31,19 +57,31 @@ wl_resource* CWaylandResource::resource() { } uint32_t CWaylandResource::version() { + RASSERT(good(), "Attempted to call version() on a bad resource"); + return wl_resource_get_version(m_pWLResource); } -void CWaylandResource::setImplementation(const void* impl, void* data, wl_resource_destroy_func_t df) { +void CWaylandResource::setImplementation(const void* impl, wl_resource_destroy_func_t df) { + RASSERT(good(), "Attempted to call setImplementation() on a bad resource"); RASSERT(!m_bImplementationSet, "Wayland Resource %lx already has an implementation, cannot re-set!", m_pWLResource); - wl_resource_set_implementation(m_pWLResource, impl, data, df); + wl_resource_set_implementation(m_pWLResource, impl, this, df); - Debug::log(LOG, "[wl res %lx] set impl to %lx", m_pWLResource, impl); + Debug::log(TRACE, "[wl res %lx] set impl to %lx", m_pWLResource, impl); m_bImplementationSet = true; } +void CWaylandResource::setData(void* data) { + Debug::log(TRACE, "[wl res %lx] set data to %lx", m_pWLResource, data); + m_pData = data; +} + +void* CWaylandResource::data() { + return m_pData; +} + static void bindManagerInternal(wl_client* client, void* data, uint32_t ver, uint32_t id) { ((IWaylandProtocol*)data)->bindManager(client, data, ver, id); } -- cgit v1.2.3