2022-03-17 16:56:33 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "../defines.hpp"
|
2022-03-17 18:25:16 +01:00
|
|
|
#include <deque>
|
|
|
|
#include "WLClasses.hpp"
|
2022-07-23 15:48:08 +02:00
|
|
|
#include <vector>
|
2022-03-19 13:54:24 +01:00
|
|
|
#include <array>
|
2022-07-23 15:48:08 +02:00
|
|
|
#include <memory>
|
2023-05-09 15:01:45 +02:00
|
|
|
#include <xf86drmMode.h>
|
2023-03-24 20:23:16 +01:00
|
|
|
#include "Timer.hpp"
|
2023-07-19 20:09:49 +02:00
|
|
|
#include "Region.hpp"
|
2023-08-11 17:37:52 +02:00
|
|
|
#include <optional>
|
2022-03-17 16:56:33 +01:00
|
|
|
|
2023-08-11 17:37:52 +02:00
|
|
|
struct SMonitorRule {
|
|
|
|
std::string name = "";
|
|
|
|
Vector2D resolution = Vector2D(1280, 720);
|
|
|
|
Vector2D offset = Vector2D(0, 0);
|
|
|
|
float scale = 1;
|
|
|
|
float refreshRate = 60;
|
|
|
|
bool disabled = false;
|
|
|
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
|
|
std::string mirrorOf = "";
|
|
|
|
bool enable10bit = false;
|
|
|
|
drmModeModeInfo drmMode = {};
|
|
|
|
std::optional<int> vrr;
|
|
|
|
};
|
2022-09-13 15:25:42 +02:00
|
|
|
|
2024-01-28 02:57:13 +01:00
|
|
|
class CMonitor;
|
|
|
|
|
|
|
|
// Class for wrapping the wlr state
|
|
|
|
class CMonitorState {
|
|
|
|
public:
|
|
|
|
CMonitorState(CMonitor* owner);
|
|
|
|
~CMonitorState();
|
|
|
|
|
|
|
|
wlr_output_state* wlr();
|
|
|
|
void clear();
|
|
|
|
// commit() will also clear()
|
|
|
|
bool commit();
|
|
|
|
bool test();
|
|
|
|
|
|
|
|
private:
|
|
|
|
wlr_output_state m_state = {0};
|
|
|
|
CMonitor* m_pOwner;
|
|
|
|
};
|
|
|
|
|
2022-07-27 12:32:00 +02:00
|
|
|
class CMonitor {
|
2022-12-16 18:17:31 +01:00
|
|
|
public:
|
2023-04-07 13:18:40 +02:00
|
|
|
CMonitor();
|
|
|
|
~CMonitor();
|
|
|
|
|
2023-08-15 19:15:37 +02:00
|
|
|
Vector2D vecPosition = Vector2D(-1, -1); // means unset
|
|
|
|
Vector2D vecXWaylandPosition = Vector2D(-1, -1); // means unset
|
|
|
|
Vector2D vecSize = Vector2D(0, 0);
|
|
|
|
Vector2D vecPixelSize = Vector2D(0, 0);
|
|
|
|
Vector2D vecTransformedSize = Vector2D(0, 0);
|
2022-03-17 16:56:33 +01:00
|
|
|
|
2023-05-09 15:01:45 +02:00
|
|
|
bool primary = false;
|
2022-03-17 16:56:33 +01:00
|
|
|
|
2023-05-09 15:01:45 +02:00
|
|
|
uint64_t ID = -1;
|
|
|
|
int activeWorkspace = -1;
|
2023-12-22 19:54:05 +01:00
|
|
|
float setScale = 1; // scale set by cfg
|
|
|
|
float scale = 1; // real scale
|
2022-03-17 16:56:33 +01:00
|
|
|
|
2023-12-06 23:54:56 +01:00
|
|
|
std::string szName = "";
|
2023-11-30 02:48:10 +01:00
|
|
|
std::string szDescription = "";
|
2022-03-17 16:56:33 +01:00
|
|
|
|
2023-05-09 15:01:45 +02:00
|
|
|
Vector2D vecReservedTopLeft = Vector2D(0, 0);
|
|
|
|
Vector2D vecReservedBottomRight = Vector2D(0, 0);
|
|
|
|
|
|
|
|
drmModeModeInfo customDrmMode = {};
|
2022-03-17 18:25:16 +01:00
|
|
|
|
2024-01-28 02:57:13 +01:00
|
|
|
CMonitorState state;
|
|
|
|
|
2022-03-17 18:25:16 +01:00
|
|
|
// WLR stuff
|
2024-02-14 23:05:36 +01:00
|
|
|
wlr_damage_ring damage;
|
|
|
|
wlr_output* output = nullptr;
|
|
|
|
float refreshRate = 60;
|
|
|
|
int framesToSkip = 0;
|
|
|
|
int forceFullFrames = 0;
|
|
|
|
bool noFrameSchedule = false;
|
|
|
|
bool scheduledRecalc = false;
|
|
|
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
|
|
bool gammaChanged = false;
|
|
|
|
float xwaylandScale = 1.f;
|
|
|
|
std::array<float, 9> projMatrix = {0};
|
|
|
|
std::optional<Vector2D> forceSize;
|
|
|
|
|
|
|
|
bool dpmsStatus = true;
|
|
|
|
bool vrrActive = false; // this can be TRUE even if VRR is not active in the case that this display does not support it.
|
|
|
|
bool enabled10bit = false; // as above, this can be TRUE even if 10 bit failed.
|
|
|
|
bool createdByUser = false;
|
|
|
|
uint32_t drmFormat = DRM_FORMAT_INVALID;
|
|
|
|
bool isUnsafeFallback = false;
|
|
|
|
|
|
|
|
bool pendingFrame = false; // if we schedule a frame during rendering, reschedule it after
|
|
|
|
bool renderingActive = false;
|
|
|
|
|
|
|
|
wl_event_source* renderTimer = nullptr; // for RAT
|
|
|
|
bool RATScheduled = false;
|
|
|
|
CTimer lastPresentationTimer;
|
|
|
|
|
|
|
|
SMonitorRule activeMonitorRule;
|
2023-08-11 17:37:52 +02:00
|
|
|
|
2022-09-13 15:25:42 +02:00
|
|
|
// mirroring
|
2022-12-16 18:17:31 +01:00
|
|
|
CMonitor* pMirrorOf = nullptr;
|
2022-09-13 15:25:42 +02:00
|
|
|
std::vector<CMonitor*> mirrors;
|
|
|
|
|
2023-07-19 20:09:49 +02:00
|
|
|
CRegion lastFrameDamage; // stores last frame damage
|
2023-07-10 13:21:00 +02:00
|
|
|
|
2023-09-28 22:48:33 +02:00
|
|
|
// for tearing
|
2023-09-30 18:07:50 +02:00
|
|
|
CWindow* solitaryClient = nullptr;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
bool canTear = false;
|
|
|
|
bool nextRenderTorn = false;
|
|
|
|
bool activelyTearing = false;
|
|
|
|
|
|
|
|
bool busy = false;
|
|
|
|
bool frameScheduledWhileBusy = false;
|
|
|
|
} tearingState;
|
2023-09-28 22:48:33 +02:00
|
|
|
|
2022-11-27 23:42:22 +01:00
|
|
|
// for the special workspace. 0 means not open.
|
2023-01-22 17:03:25 +01:00
|
|
|
int specialWorkspaceID = 0;
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2023-01-22 17:03:25 +01:00
|
|
|
std::array<std::vector<std::unique_ptr<SLayerSurface>>, 4> m_aLayerSurfaceLayers;
|
2022-03-17 18:25:16 +01:00
|
|
|
|
|
|
|
DYNLISTENER(monitorFrame);
|
|
|
|
DYNLISTENER(monitorDestroy);
|
2022-11-19 17:28:04 +01:00
|
|
|
DYNLISTENER(monitorStateRequest);
|
2023-04-07 17:31:51 +02:00
|
|
|
DYNLISTENER(monitorDamage);
|
2023-04-07 18:25:56 +02:00
|
|
|
DYNLISTENER(monitorNeedsFrame);
|
2023-04-12 22:40:51 +02:00
|
|
|
DYNLISTENER(monitorCommit);
|
2023-06-23 21:14:04 +02:00
|
|
|
DYNLISTENER(monitorBind);
|
2022-03-18 22:35:51 +01:00
|
|
|
|
2022-07-27 12:32:00 +02:00
|
|
|
// methods
|
2023-11-01 19:53:36 +01:00
|
|
|
void onConnect(bool noRule);
|
2023-11-12 14:14:05 +01:00
|
|
|
void onDisconnect(bool destroy = false);
|
2023-11-01 19:53:36 +01:00
|
|
|
void addDamage(const pixman_region32_t* rg);
|
|
|
|
void addDamage(const CRegion* rg);
|
2023-11-04 18:03:05 +01:00
|
|
|
void addDamage(const CBox* box);
|
2023-11-01 19:53:36 +01:00
|
|
|
void setMirror(const std::string&);
|
|
|
|
bool isMirror();
|
|
|
|
float getDefaultScale();
|
2024-01-15 16:30:46 +01:00
|
|
|
void changeWorkspace(CWorkspace* const pWorkspace, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
2024-02-10 00:47:00 +01:00
|
|
|
void changeWorkspace(const int& id, bool internal = false, bool noMouseMove = false, bool noFocus = false);
|
2023-11-01 19:53:36 +01:00
|
|
|
void setSpecialWorkspace(CWorkspace* const pWorkspace);
|
|
|
|
void setSpecialWorkspace(const int& id);
|
|
|
|
void moveTo(const Vector2D& pos);
|
|
|
|
Vector2D middle();
|
2023-11-24 11:54:21 +01:00
|
|
|
void updateMatrix();
|
2023-11-01 19:53:36 +01:00
|
|
|
|
|
|
|
bool m_bEnabled = false;
|
|
|
|
bool m_bRenderingInitPassed = false;
|
2022-07-27 12:32:00 +02:00
|
|
|
|
2022-03-18 22:35:51 +01:00
|
|
|
// For the list lookup
|
|
|
|
|
2022-07-27 12:32:00 +02:00
|
|
|
bool operator==(const CMonitor& rhs) {
|
2022-03-18 22:35:51 +01:00
|
|
|
return vecPosition == rhs.vecPosition && vecSize == rhs.vecSize && szName == rhs.szName;
|
|
|
|
}
|
2022-09-13 15:25:42 +02:00
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
private:
|
|
|
|
void setupDefaultWS(const SMonitorRule&);
|
|
|
|
int findAvailableDefaultWS();
|
2022-09-25 20:07:48 +02:00
|
|
|
};
|