#pragma once /* Implementations for: - wl_compositor - wl_surface - wl_region - wl_callback */ #include #include #include #include "../WaylandProtocol.hpp" #include "../../render/Texture.hpp" #include "../types/SurfaceStateQueue.hpp" #include "wayland.hpp" #include "../../desktop/view/WLSurface.hpp" #include "../../helpers/signal/Signal.hpp" #include "../../helpers/math/Math.hpp" #include "../../helpers/time/Time.hpp" #include "../types/Buffer.hpp" #include "../../helpers/cm/ColorManagement.hpp" #include "../types/SurfaceRole.hpp" #include "../types/SurfaceState.hpp" class CWLOutputResource; class CMonitor; class CWLSurfaceResource; class CWLSubsurfaceResource; class CViewportResource; class CDRMSyncobjSurfaceResource; class CFifoResource; class CCommitTimerResource; class CColorManagementSurface; class CContentType; class CWLCallbackResource { public: CWLCallbackResource(SP&& resource_); ~CWLCallbackResource() noexcept = default; // disable copy CWLCallbackResource(const CWLCallbackResource&) = delete; CWLCallbackResource& operator=(const CWLCallbackResource&) = delete; // allow move CWLCallbackResource(CWLCallbackResource&&) noexcept = default; CWLCallbackResource& operator=(CWLCallbackResource&&) noexcept = default; bool good(); void send(const Time::steady_tp& now); private: SP m_resource; }; class CWLRegionResource { public: CWLRegionResource(SP resource_); static SP fromResource(wl_resource* res); bool good(); CRegion m_region; WP m_self; private: SP m_resource; }; class CWLSurfaceResource { public: CWLSurfaceResource(SP resource_); ~CWLSurfaceResource(); static SP fromResource(wl_resource* res); bool good(); wl_client* client(); void enter(PHLMONITOR monitor); void leave(PHLMONITOR monitor); void sendPreferredTransform(wl_output_transform t); void sendPreferredScale(int32_t scale); void frame(const Time::steady_tp& now); uint32_t id(); void map(); void unmap(); void error(int code, const std::string& str); SP getResource(); CBox extends(); void resetRole(); struct { CSignalT<> precommit; // before commit CSignalT> stateCommit; // when placing state in queue CSignalT> stateCommit2; // when placing state in queue used for commit timing so we apply fifo/fences first. CSignalT<> commit; // after commit CSignalT<> map; CSignalT<> unmap; CSignalT> newSubsurface; CSignalT<> destroy; CSignalT> enter; CSignalT> leave; } m_events; SSurfaceState m_current; SSurfaceState m_pending; CSurfaceStateQueue m_stateQueue; WP m_self; WP m_hlSurface; std::vector m_enteredOutputs; bool m_mapped = false; std::vector> m_subsurfaces; SP m_role; WP m_syncobj; // may not be present WP m_fifo; // may not be present WP m_commitTimer; // may not be present WP m_colorManagement; WP m_contentType; void breadthfirst(std::function, const Vector2D&, void*)> fn, void* data); SP findFirstPreorder(std::function)> fn); SP findWithCM(); void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false); void scheduleState(WP state); void commitState(SSurfaceState& state); NColorManagement::PImageDescription getPreferredImageDescription(); void sortSubsurfaces(); bool hasVisibleSubsurface(); bool isTearing(); // returns a pair: found surface (null if not found) and surface local coords. // localCoords param is relative to 0,0 of this surface std::pair, Vector2D> at(const Vector2D& localCoords, bool allowsInput = false); private: SP m_resource; wl_client* m_client = nullptr; void destroy(); void releaseBuffers(bool onlyCurrent = true); void dropPendingBuffer(); void dropCurrentBuffer(); void bfHelper(std::vector> const& nodes, std::function, const Vector2D&, void*)> fn, void* data); SP findFirstPreorderHelper(SP root, std::function)> fn); void updateCursorShm(CRegion damage = CBox{0, 0, INT16_MAX, INT16_MAX}); friend class CWLPointerResource; }; class CWLCompositorResource { public: CWLCompositorResource(SP resource_); bool good(); private: SP m_resource; }; class CWLCompositorProtocol : public IWaylandProtocol { public: CWLCompositorProtocol(const wl_interface* iface, const int& ver, const std::string& name); virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); void forEachSurface(std::function)> fn); struct { CSignalT> newSurface; } m_events; private: void destroyResource(CWLCompositorResource* resource); void destroyResource(CWLSurfaceResource* resource); void destroyResource(CWLRegionResource* resource); // std::vector> m_managers; std::vector> m_surfaces; std::vector> m_regions; friend class CWLSurfaceResource; friend class CWLCompositorResource; friend class CWLRegionResource; friend class CWLCallbackResource; }; namespace PROTO { inline UP compositor; };