#pragma once #include #include #include #include "WaylandProtocol.hpp" #include "wlr-output-management-unstable-v1.hpp" #include "../helpers/signal/Listener.hpp" class CMonitor; class COutputHead; class COutputMode; class COutputManager { public: COutputManager(SP resource_); bool good(); void ensureMonitorSent(CMonitor* pMonitor); void sendDone(); private: SP resource; bool stopped = false; WP self; std::vector> heads; void makeAndSendNewHead(CMonitor* pMonitor); friend class COutputManagementProtocol; }; class COutputMode { public: COutputMode(SP resource_, wlr_output_mode* mode_); bool good(); wlr_output_mode* getMode(); void sendAllData(); private: SP resource; wlr_output_mode* mode = nullptr; friend class COutputHead; friend class COutputManagementProtocol; }; class COutputHead { public: COutputHead(SP resource_, CMonitor* pMonitor_); bool good(); void sendAllData(); // this has to be separate as we need to send the head first, then set the data void updateMode(); CMonitor* monitor(); private: SP resource; CMonitor* pMonitor = nullptr; void makeAndSendNewMode(wlr_output_mode* mode); void sendCurrentMode(); std::vector> modes; struct { CHyprSignalListener monitorDestroy; CHyprSignalListener monitorModeChange; } listeners; friend class COutputManager; friend class COutputManagementProtocol; }; class COutputConfigurationHead { public: COutputConfigurationHead(SP resource_, CMonitor* pMonitor_); bool good(); enum eCommittedProperties : uint32_t { OUTPUT_HEAD_COMMITTED_MODE = (1 << 0), OUTPUT_HEAD_COMMITTED_CUSTOM_MODE = (1 << 1), OUTPUT_HEAD_COMMITTED_POSITION = (1 << 2), OUTPUT_HEAD_COMMITTED_TRANSFORM = (1 << 3), OUTPUT_HEAD_COMMITTED_SCALE = (1 << 4), OUTPUT_HEAD_COMMITTED_ADAPTIVE_SYNC = (1 << 5), }; uint32_t committedProperties = 0; struct { WP mode; struct { Vector2D size; uint32_t refresh = 0; } customMode; Vector2D position; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; float scale = 1.F; bool adaptiveSync = false; } state; private: SP resource; CMonitor* pMonitor = nullptr; struct { CHyprSignalListener monitorDestroy; } listeners; friend class COutputConfiguration; }; class COutputConfiguration { public: COutputConfiguration(SP resource_, SP owner_); bool good(); private: SP resource; std::vector> heads; WP owner; bool applyTestConfiguration(bool test); }; class COutputManagementProtocol : public IWaylandProtocol { public: COutputManagementProtocol(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); private: void destroyResource(COutputManager* resource); void destroyResource(COutputHead* resource); void destroyResource(COutputMode* resource); void destroyResource(COutputConfiguration* resource); void destroyResource(COutputConfigurationHead* resource); void updateAllOutputs(); // std::vector> m_vManagers; std::vector> m_vHeads; std::vector> m_vModes; std::vector> m_vConfigurations; std::vector> m_vConfigurationHeads; SP headFromResource(wl_resource* r); SP modeFromResource(wl_resource* r); friend class COutputManager; friend class COutputHead; friend class COutputMode; friend class COutputConfiguration; friend class COutputConfigurationHead; }; namespace PROTO { inline UP outputManagement; };