File indexing completed on 2024-05-05 09:51:13

0001 /*
0002  *  SPDX-FileCopyrightText: 2012 Alejandro Fiestas Olivares <afiestas@kde.org>
0003  *  SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.1-or-later
0006  */
0007 
0008 #pragma once
0009 
0010 #include "kscreen_export.h"
0011 #include "types.h"
0012 
0013 #include <QDebug>
0014 #include <QMetaType>
0015 #include <QObject>
0016 #include <QPoint>
0017 #include <QSize>
0018 #include <QStringList>
0019 #include <optional>
0020 
0021 namespace KScreen
0022 {
0023 class Edid;
0024 class Mode;
0025 
0026 class KSCREEN_EXPORT Output : public QObject
0027 {
0028     Q_OBJECT
0029     Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
0030 public:
0031     Q_PROPERTY(int id READ id CONSTANT)
0032     Q_PROPERTY(QString name READ name WRITE setName NOTIFY outputChanged)
0033     Q_PROPERTY(Type type READ type WRITE setType NOTIFY outputChanged)
0034     Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY outputChanged)
0035     Q_PROPERTY(ModeList modes READ modes NOTIFY modesChanged)
0036     Q_PROPERTY(QPoint pos READ pos WRITE setPos NOTIFY posChanged)
0037     Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged)
0038     Q_PROPERTY(Rotation rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
0039     Q_PROPERTY(QString currentModeId READ currentModeId WRITE setCurrentModeId NOTIFY currentModeIdChanged)
0040     Q_PROPERTY(QString preferredModeId READ preferredModeId CONSTANT)
0041     Q_PROPERTY(bool connected READ isConnected WRITE setConnected NOTIFY isConnectedChanged)
0042     Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY isEnabledChanged)
0043     Q_PROPERTY(bool primary READ isPrimary WRITE setPrimary NOTIFY priorityChanged)
0044     Q_PROPERTY(uint32_t priority READ priority WRITE setPriority NOTIFY priorityChanged)
0045     Q_PROPERTY(QList<int> clones READ clones WRITE setClones NOTIFY clonesChanged)
0046     Q_PROPERTY(int replicationSource READ replicationSource WRITE setReplicationSource NOTIFY replicationSourceChanged)
0047     Q_PROPERTY(KScreen::Edid *edid READ edid CONSTANT)
0048     Q_PROPERTY(QSize sizeMm READ sizeMm CONSTANT)
0049     Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
0050     Q_PROPERTY(bool followPreferredMode READ followPreferredMode WRITE setFollowPreferredMode NOTIFY followPreferredModeChanged)
0051     Q_PROPERTY(QSizeF explicitLogicalSize READ explicitLogicalSize WRITE setExplicitLogicalSize NOTIFY explicitLogicalSizeChanged)
0052     Q_PROPERTY(Capabilities capabilities READ capabilities NOTIFY capabilitiesChanged)
0053     Q_PROPERTY(uint32_t overscan READ overscan WRITE setOverscan NOTIFY overscanChanged)
0054     Q_PROPERTY(VrrPolicy vrrPolicy READ vrrPolicy WRITE setVrrPolicy NOTIFY vrrPolicyChanged)
0055     Q_PROPERTY(RgbRange rgbRange READ rgbRange WRITE setRgbRange NOTIFY rgbRangeChanged)
0056     Q_PROPERTY(bool hdrEnabled READ isHdrEnabled WRITE setHdrEnabled NOTIFY hdrEnabledChanged)
0057     Q_PROPERTY(uint32_t sdrBrightness READ sdrBrightness WRITE setSdrBrightness NOTIFY sdrBrightnessChanged)
0058     Q_PROPERTY(bool wcgEnabled READ isWcgEnabled WRITE setWcgEnabled NOTIFY wcgEnabledChanged)
0059     Q_PROPERTY(AutoRotatePolicy autoRotatePolicy READ autoRotatePolicy WRITE setAutoRotatePolicy NOTIFY autoRotatePolicyChanged)
0060     Q_PROPERTY(QString iccProfilePath READ iccProfilePath WRITE setIccProfilePath NOTIFY iccProfilePathChanged)
0061 
0062     enum Type {
0063         Unknown,
0064         VGA,
0065         DVI,
0066         DVII,
0067         DVIA,
0068         DVID,
0069         HDMI,
0070         Panel,
0071         TV,
0072         TVComposite,
0073         TVSVideo,
0074         TVComponent,
0075         TVSCART,
0076         TVC4,
0077         DisplayPort,
0078     };
0079     Q_ENUM(Type)
0080 
0081     enum Rotation {
0082         None = 1 << 0,
0083         Left = 1 << 1,
0084         Inverted = 1 << 2,
0085         Right = 1 << 3,
0086         Flipped = 1 << 4,
0087         Flipped90 = 1 << 5,
0088         Flipped180 = 1 << 6,
0089         Flipped270 = 1 << 7,
0090     };
0091     Q_ENUM(Rotation)
0092 
0093     enum class Capability {
0094         Overscan = 1 << 0,
0095         Vrr = 1 << 1,
0096         RgbRange = 1 << 2,
0097         HighDynamicRange = 1 << 3,
0098         WideColorGamut = 1 << 4,
0099         AutoRotation = 1 << 5,
0100         IccProfile = 1 << 6,
0101     };
0102     Q_ENUM(Capability)
0103     Q_DECLARE_FLAGS(Capabilities, Capability)
0104     Q_FLAG(Capabilities)
0105 
0106     enum class VrrPolicy {
0107         Never = 0,
0108         Always = 1,
0109         Automatic = 2,
0110     };
0111     Q_ENUM(VrrPolicy)
0112 
0113     enum class RgbRange {
0114         Automatic = 0,
0115         Full = 1,
0116         Limited = 2,
0117     };
0118     Q_ENUM(RgbRange)
0119 
0120     enum class AutoRotatePolicy {
0121         Never = 0,
0122         InTabletMode = 1,
0123         Always = 2,
0124     };
0125     Q_ENUM(AutoRotatePolicy)
0126 
0127     explicit Output();
0128     ~Output() override;
0129 
0130     OutputPtr clone() const;
0131 
0132     int id() const;
0133     void setId(int id);
0134 
0135     QString name() const;
0136     void setName(const QString &name);
0137 
0138     /**
0139      * Returns an identifying hash for this output.
0140      *
0141      * The hash is calculated either via the edid hash or if no
0142      * edid is available by the output name.
0143      *
0144      * @return identifying hash of this output
0145      * @since 5.15
0146      * @deprecated
0147      * @see hashMd5
0148      */
0149     QString hash() const;
0150 
0151     /**
0152      * Returns an identifying hex encoded MD5-hash for this output.
0153      *
0154      * The hash is calculated either via the edid hash or if no
0155      * edid is available by the output name, which is hashed as well.
0156      *
0157      * @return identifying hash of this output
0158      * @since 5.17
0159      */
0160     QString hashMd5() const;
0161 
0162     Type type() const;
0163     QString typeName() const;
0164     void setType(Type type);
0165 
0166     QString icon() const;
0167     void setIcon(const QString &icon);
0168 
0169     Q_INVOKABLE ModePtr mode(const QString &id) const;
0170     ModeList modes() const;
0171     void setModes(const ModeList &modes);
0172 
0173     QString currentModeId() const;
0174     void setCurrentModeId(const QString &mode);
0175     Q_INVOKABLE ModePtr currentMode() const;
0176 
0177     void setPreferredModes(const QStringList &modes);
0178     QStringList preferredModes() const;
0179     /**
0180      * Returns the preferred mode with higher resolution and refresh
0181      */
0182     Q_INVOKABLE QString preferredModeId() const;
0183     /**
0184      * Returns KScreen::Mode associated with preferredModeId()
0185      */
0186     Q_INVOKABLE ModePtr preferredMode() const;
0187 
0188     QPoint pos() const;
0189     void setPos(const QPoint &pos);
0190 
0191     /***
0192      * Returns actual size being rendered in the output
0193      *
0194      * The returned valued is after transformations have been applied to
0195      * the resolution of the current mode.
0196      *
0197      * For example if currentMode is 1280x800 but it is a vertical screen
0198      * the returned size will be 800x1280.
0199      *
0200      * If that same resolution (1280x800) is transformed and scale x2, the
0201      * value returned will be 2560x1600.
0202      *
0203      * This property reflects the currently active output configuration and
0204      * is not affected by current mode or orientation change made by user
0205      * until the config is applied.
0206      *
0207      * @since 5.4
0208      */
0209     QSize size() const;
0210     void setSize(const QSize &size);
0211 
0212     /**
0213      * Returns either current mode size or if not available preferred one or if also not
0214      * available the first one in the ModeList.
0215      *
0216      * @return mode size
0217      */
0218     QSize enforcedModeSize() const;
0219 
0220     Rotation rotation() const;
0221     void setRotation(Rotation rotation);
0222     /**
0223      * A comfortable function that returns true when output is not rotated
0224      * or is rotated upside down.
0225      */
0226     Q_INVOKABLE inline bool isHorizontal() const
0227     {
0228         return rotation() == Output::None || rotation() == Output::Inverted || rotation() == Output::Flipped || rotation() == Output::Flipped180;
0229     }
0230 
0231     bool isConnected() const;
0232     void setConnected(bool connected);
0233 
0234     bool isEnabled() const;
0235     void setEnabled(bool enabled);
0236 
0237     bool isPrimary() const;
0238     void setPrimary(bool primary);
0239 
0240     uint32_t priority() const;
0241     void setPriority(uint32_t priority);
0242 
0243     /**
0244      * @brief Immutable clones because of hardware restrictions
0245      *
0246      * Clones are set symmetrically on all outputs. The list contains ids
0247      * for all other outputs being clones of this output.
0248      *
0249      * @return List of output ids being clones of each other.
0250      */
0251     QList<int> clones() const;
0252     /**
0253      * @brief Set the clones list.
0254      *
0255      * When this output is part of a configuration this call is followed by
0256      * similar calls on other outputs making the lists in all outputs
0257      * symmetric.
0258      * @param outputlist
0259      */
0260     void setClones(const QList<int> &outputlist);
0261 
0262     /**
0263      * @brief Provides the source for an ongoing replication
0264      *
0265      * If the returned output id is non-null this output is a replica of the
0266      * returned output. If null is returned the output is no replica of any
0267      * other output.
0268      *
0269      * @return Replication source output id of this output
0270      */
0271     int replicationSource() const;
0272     /**
0273      * @brief Set the replication source.
0274      * @param source
0275      */
0276     void setReplicationSource(int source);
0277 
0278     void setEdid(const QByteArray &rawData);
0279 
0280     /**
0281      * edid returns the output's EDID information if available.
0282      *
0283      * The output maintains ownership of the returned Edid, so the caller should not delete it.
0284      * Note that the edid is only valid as long as the output is alive.
0285      */
0286     Edid *edid() const;
0287 
0288     /**
0289      * Returns the physical size of the screen in milimeters.
0290      *
0291      * @note Some broken GPUs or monitors return the size in centimeters instead
0292      * of millimeters. KScreen at the moment is not sanitizing the values.
0293      */
0294     QSize sizeMm() const;
0295     void setSizeMm(const QSize &size);
0296 
0297     /**
0298      * Returns if the output needs to be taken account for in the overall compositor/screen
0299      * space and if it should be depicted on its own in a graphical view for repositioning.
0300      *
0301      * @return true if the output is positionable in compositor/screen space.
0302      *
0303      * @since 5.17
0304      */
0305     bool isPositionable() const;
0306 
0307     /**
0308      * Returns a rectangle containing the currently set output position and
0309      * size.
0310      *
0311      * The geometry also reflects current orientation (i.e. if current mode
0312      * is 1920x1080 and orientation is @p KScreen::Output::Left, then the
0313      * size of the returned rectangle will be 1080x1920.
0314      *
0315      * This property contains the current settings stored in the particular
0316      * Output object, so it is updated even when user changes current mode
0317      * or orientation without applying the whole config/
0318      */
0319     QRect geometry() const;
0320 
0321     /**
0322      * returns the scaling factor to use for this output
0323      *
0324      * @since 5.9
0325      */
0326     qreal scale() const;
0327 
0328     /**
0329      * Set the scaling factor for this output.
0330      *
0331      * @arg factor Scale factor to use for this output, the backend may or may not
0332      * be able to deal with non-integer values, in that case, the factor gets rounded.
0333      *
0334      * @since 5.9
0335      */
0336     void setScale(qreal factor);
0337 
0338     /**
0339      * The logical size is the output's representation internal to the display server and its
0340      * overall screen geometry.
0341      *
0342      * returns the explicitly set logical size of this output, is an invalid size if not set
0343      *
0344      * @since 5.18
0345      */
0346     QSizeF explicitLogicalSize() const;
0347 
0348     /**
0349      * The logical size is the output's representation internal to the display
0350      * server and its overall screen geometry.
0351      *
0352      * returns the logical size of this output, rounded up to the next integer;
0353      * is an invalid size if not set
0354      *
0355      * @since 6.0
0356      */
0357     QSize explicitLogicalSizeInt() const;
0358 
0359     /**
0360      * Specifies explicitly the logical size of this output and by that overrides any other
0361      * logical size calculation through mode and scale. To enable this instead again call this
0362      * function with an invalid size as argument.
0363      *
0364      * @param size of this output in logical space
0365      *
0366      * @since 5.24
0367      */
0368     void setExplicitLogicalSize(const QSizeF &size);
0369 
0370     /**
0371      * @returns whether the mode should be changed to the new preferred mode
0372      * once it changes
0373      *
0374      * @since 5.15
0375      */
0376     bool followPreferredMode() const;
0377 
0378     /**
0379      * Set whether the preferred mode should be followed through @arg follow
0380      *
0381      * @since 5.15
0382      */
0383     void setFollowPreferredMode(bool follow);
0384 
0385     /**
0386      * @returns the capabilities of this output
0387      * @since 5.22
0388      */
0389     Capabilities capabilities() const;
0390 
0391     /**
0392      * sets the capabilities of this output
0393      * @since 5.22
0394      */
0395     void setCapabilities(Capabilities capabilities);
0396 
0397     /**
0398      * @returns the overscan value of this output in %
0399      * @since 5.22
0400      */
0401     uint32_t overscan() const;
0402 
0403     /**
0404      * Set the overscan for this output
0405      * @param overscan the overscan value in %
0406      * @since 5.22
0407      */
0408     void setOverscan(uint32_t overscan);
0409 
0410     /**
0411      * @returns when variable refresh rate should be used on this output
0412      *
0413      * @since 5.22
0414      */
0415     VrrPolicy vrrPolicy() const;
0416 
0417     /**
0418      * Set when variable refresh rate should be used on this output
0419      *
0420      * @since 5.22
0421      */
0422     void setVrrPolicy(VrrPolicy policy);
0423 
0424     /**
0425      * @returns which rgb range the output is using
0426      * @since 5.23
0427      */
0428     RgbRange rgbRange() const;
0429 
0430     /**
0431      * Set which rgb range the output should use
0432      * @since 5.23
0433      */
0434     void setRgbRange(RgbRange rgbRange);
0435 
0436     /**
0437      * @returns if high dynamic range is enabled
0438      * @since 6.0
0439      */
0440     bool isHdrEnabled() const;
0441 
0442     /**
0443      * Set if high dynamic range should be enabled
0444      * @since 6.0
0445      */
0446     void setHdrEnabled(bool enable);
0447 
0448     /**
0449      * @returns the brightness for SDR content while the output is in HDR mode
0450      * @since 6.0
0451      */
0452     uint32_t sdrBrightness() const;
0453 
0454     /**
0455      * Set the brightness for SDR content while the output is in HDR mode
0456      * @since 6.0
0457      */
0458     void setSdrBrightness(uint32_t brightness);
0459 
0460     /**
0461      * @returns if the use of wide color gamut is enabled
0462      * @since 6.0
0463      */
0464     bool isWcgEnabled() const;
0465 
0466     /**
0467      * Set if a wide color gamut should be used
0468      * @since 6.0
0469      */
0470     void setWcgEnabled(bool enable);
0471 
0472     /**
0473      * @returns the policy for auto rotation
0474      * @since 6.0
0475      */
0476     AutoRotatePolicy autoRotatePolicy() const;
0477 
0478     /**
0479      * Set the policy for auto rotation
0480      * @since 6.0
0481      */
0482     void setAutoRotatePolicy(AutoRotatePolicy policy);
0483 
0484     /**
0485      * @since 6.0
0486      */
0487     QString iccProfilePath() const;
0488     /**
0489      * @since 6.0
0490      */
0491     void setIccProfilePath(const QString &path);
0492 
0493     double sdrGamutWideness() const;
0494     void setSdrGamutWideness(double value);
0495 
0496     double maxPeakBrightness() const;
0497     void setMaxPeakBrightness(double value);
0498 
0499     double maxAverageBrightness() const;
0500     void setMaxAverageBrightness(double value);
0501 
0502     double minBrightness() const;
0503     void setMinBrightness(double value);
0504 
0505     std::optional<double> maxPeakBrightnessOverride() const;
0506     void setMaxPeakBrightnessOverride(std::optional<double> value);
0507 
0508     std::optional<double> maxAverageBrightnessOverride() const;
0509     void setMaxAverageBrightnessOverride(std::optional<double> value);
0510 
0511     std::optional<double> minBrightnessOverride() const;
0512     void setMinBrightnessOverride(std::optional<double> value);
0513 
0514     void apply(const OutputPtr &other);
0515 
0516 Q_SIGNALS:
0517     void outputChanged();
0518     void posChanged();
0519     void sizeChanged();
0520     void currentModeIdChanged();
0521     void rotationChanged();
0522     void isConnectedChanged();
0523     void isEnabledChanged();
0524     void priorityChanged();
0525     void clonesChanged();
0526     void replicationSourceChanged();
0527     void scaleChanged();
0528     void explicitLogicalSizeChanged();
0529     void followPreferredModeChanged(bool followPreferredMode);
0530     void capabilitiesChanged();
0531     void overscanChanged();
0532     void vrrPolicyChanged();
0533     void rgbRangeChanged();
0534     void hdrEnabledChanged();
0535     void sdrBrightnessChanged();
0536     void wcgEnabledChanged();
0537     void autoRotatePolicyChanged();
0538     void iccProfilePathChanged();
0539     void sdrGamutWidenessChanged();
0540     void maxPeakBrightnessChanged();
0541     void maxAverageBrightnessChanged();
0542     void minBrightnessChanged();
0543     void maxPeakBrightnessOverrideChanged();
0544     void maxAverageBrightnessOverrideChanged();
0545     void minBrightnessOverrideChanged();
0546 
0547     /** The mode list changed.
0548      *
0549      * This may happen when a mode is added or changed.
0550      *
0551      * @since 5.8.3
0552      */
0553     void modesChanged();
0554 
0555 private:
0556     Q_DISABLE_COPY(Output)
0557 
0558     class Private;
0559     Private *const d;
0560 
0561     explicit Output(Private *dd);
0562 };
0563 
0564 } // KScreen namespace
0565 
0566 KSCREEN_EXPORT QDebug operator<<(QDebug dbg, const KScreen::OutputPtr &output);