#pragma once #include #include #include #include #include "WaylandProtocol.hpp" #include "wlr-output-management-unstable-v1.hpp" #include "../helpers/signal/Signal.hpp" #include class CMonitor; class COutputHead; class COutputMode; struct SMonitorRule; enum eWlrOutputCommittedProperties : 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), }; struct SWlrManagerOutputState { uint32_t committedProperties = 0; 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; bool enabled = true; }; struct SWlrManagerSavedOutputState { uint32_t committedProperties = 0; Vector2D resolution; uint32_t refresh = 0; Vector2D position; wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL; float scale = 1.F; bool adaptiveSync = false; bool enabled = true; }; class COutputManager { public: COutputManager(SP resource_); bool good(); void ensureMonitorSent(PHLMONITOR pMonitor); void sendDone(); // holds the states for this manager. std::unordered_map monitorStates; private: SP resource; bool stopped = false; WP self; std::vector> heads; void makeAndSendNewHead(PHLMONITOR pMonitor); friend class COutputManagementProtocol; }; class COutputMode { public: COutputMode(SP resource_, SP mode_); bool good(); SP getMode(); void sendAllData(); private: SP resource; WP mode; friend class COutputHead; friend class COutputManagementProtocol; }; class COutputHead { public: COutputHead(SP resource_, PHLMONITOR pMonitor_); bool good(); void sendAllData(); // this has to be separate as we need to send the head first, then set the data void updateMode(); PHLMONITOR monitor(); private: SP resource; PHLMONITORREF pMonitor; void makeAndSendNewMode(SP mode); void sendCurrentMode(); std::vector> modes; struct { CHyprSignalListener monitorDestroy; CHyprSignalListener monitorModeChange; } listeners; friend class COutputManager; friend class COutputManagementProtocol; }; class COutputConfigurationHead { public: COutputConfigurationHead(SP resource_, PHLMONITOR pMonitor_); bool good(); SWlrManagerOutputState state; private: SP resource; PHLMONITORREF pMonitor; 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); // doesn't have to return one SP getOutputStateFor(PHLMONITOR pMonitor); 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; };