Hyprland/src/protocols/OutputManagement.hpp

186 lines
5.4 KiB
C++
Raw Normal View History

2024-05-03 17:58:40 +01:00
#pragma once
#include <vector>
#include <cstdint>
#include <unordered_map>
2024-05-03 17:58:40 +01:00
#include "WaylandProtocol.hpp"
#include "wlr-output-management-unstable-v1.hpp"
#include "../helpers/signal/Signal.hpp"
#include <aquamarine/output/Output.hpp>
2024-05-03 17:58:40 +01:00
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<COutputMode> 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;
};
2024-05-03 17:58:40 +01:00
class COutputManager {
public:
COutputManager(SP<CZwlrOutputManagerV1> resource_);
bool good();
void ensureMonitorSent(PHLMONITOR pMonitor);
2024-05-03 17:58:40 +01:00
void sendDone();
// holds the states for this manager.
std::unordered_map<std::string, SWlrManagerSavedOutputState> m_monitorStates;
2024-05-03 17:58:40 +01:00
private:
SP<CZwlrOutputManagerV1> m_resource;
bool m_stopped = false;
2024-05-03 17:58:40 +01:00
WP<COutputManager> m_self;
2024-05-03 17:58:40 +01:00
std::vector<WP<COutputHead>> m_heads;
2024-05-03 17:58:40 +01:00
void makeAndSendNewHead(PHLMONITOR pMonitor);
2024-05-03 17:58:40 +01:00
friend class COutputManagementProtocol;
};
class COutputMode {
public:
COutputMode(SP<CZwlrOutputModeV1> resource_, SP<Aquamarine::SOutputMode> mode_);
2024-05-03 17:58:40 +01:00
bool good();
SP<Aquamarine::SOutputMode> getMode();
void sendAllData();
2024-05-03 17:58:40 +01:00
private:
SP<CZwlrOutputModeV1> m_resource;
WP<Aquamarine::SOutputMode> m_mode;
2024-05-03 17:58:40 +01:00
friend class COutputHead;
friend class COutputManagementProtocol;
};
class COutputHead {
public:
COutputHead(SP<CZwlrOutputHeadV1> resource_, PHLMONITOR pMonitor_);
2024-05-03 17:58:40 +01:00
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();
2024-05-03 17:58:40 +01:00
private:
SP<CZwlrOutputHeadV1> m_resource;
PHLMONITORREF m_monitor;
2024-05-03 17:58:40 +01:00
void makeAndSendNewMode(SP<Aquamarine::SOutputMode> mode);
2024-05-03 17:58:40 +01:00
void sendCurrentMode();
std::vector<WP<COutputMode>> m_modes;
2024-05-03 17:58:40 +01:00
struct {
CHyprSignalListener monitorDestroy;
CHyprSignalListener monitorModeChange;
} m_listeners;
2024-05-03 17:58:40 +01:00
friend class COutputManager;
friend class COutputManagementProtocol;
};
class COutputConfigurationHead {
public:
COutputConfigurationHead(SP<CZwlrOutputConfigurationHeadV1> resource_, PHLMONITOR pMonitor_);
2024-05-03 17:58:40 +01:00
bool good();
2024-05-03 17:58:40 +01:00
SWlrManagerOutputState m_state;
2024-05-03 17:58:40 +01:00
private:
SP<CZwlrOutputConfigurationHeadV1> m_resource;
PHLMONITORREF m_monitor;
2024-05-03 17:58:40 +01:00
friend class COutputConfiguration;
};
class COutputConfiguration {
public:
COutputConfiguration(SP<CZwlrOutputConfigurationV1> resource_, SP<COutputManager> owner_);
bool good();
private:
SP<CZwlrOutputConfigurationV1> m_resource;
std::vector<WP<COutputConfigurationHead>> m_heads;
WP<COutputManager> m_owner;
2024-05-03 17:58:40 +01:00
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<SWlrManagerSavedOutputState> getOutputStateFor(PHLMONITOR pMonitor);
2024-05-03 17:58:40 +01:00
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<SP<COutputManager>> m_managers;
std::vector<SP<COutputHead>> m_heads;
std::vector<SP<COutputMode>> m_modes;
std::vector<SP<COutputConfiguration>> m_configurations;
std::vector<SP<COutputConfigurationHead>> m_configurationHeads;
2024-05-03 17:58:40 +01:00
SP<COutputHead> headFromResource(wl_resource* r);
SP<COutputMode> modeFromResource(wl_resource* r);
friend class COutputManager;
friend class COutputHead;
friend class COutputMode;
friend class COutputConfiguration;
friend class COutputConfigurationHead;
};
namespace PROTO {
inline UP<COutputManagementProtocol> outputManagement;
};