Merge AbstractWaylandOutput with AbstractOutput

This commit is contained in:
Vlad Zahorodnii 2022-04-14 11:32:51 +03:00
parent ca7927e3b6
commit d43dac8f8d
52 changed files with 735 additions and 942 deletions

View file

@ -85,7 +85,7 @@ void OutputChangesTest::testWindowSticksToOutputAfterOutputIsDisabled()
// Disable the output where the window is on. // Disable the output where the window is on.
WaylandOutputConfig config; WaylandOutputConfig config;
{ {
auto changeSet = config.changeSet(static_cast<AbstractWaylandOutput *>(outputs[0])); auto changeSet = config.changeSet(outputs[0]);
changeSet->enabled = false; changeSet->enabled = false;
} }
kwinApp()->platform()->applyOutputChanges(config); kwinApp()->platform()->applyOutputChanges(config);
@ -111,11 +111,11 @@ void OutputChangesTest::testWindowSticksToOutputAfterAnotherOutputIsDisabled()
// Disable the first output. // Disable the first output.
WaylandOutputConfig config; WaylandOutputConfig config;
{ {
auto changeSet = config.changeSet(static_cast<AbstractWaylandOutput *>(outputs[0])); auto changeSet = config.changeSet(outputs[0]);
changeSet->enabled = false; changeSet->enabled = false;
} }
{ {
auto changeSet = config.changeSet(static_cast<AbstractWaylandOutput *>(outputs[1])); auto changeSet = config.changeSet(outputs[1]);
changeSet->pos = QPoint(0, 0); changeSet->pos = QPoint(0, 0);
} }
kwinApp()->platform()->applyOutputChanges(config); kwinApp()->platform()->applyOutputChanges(config);
@ -141,7 +141,7 @@ void OutputChangesTest::testWindowSticksToOutputAfterOutputIsMoved()
// Disable the first output. // Disable the first output.
WaylandOutputConfig config; WaylandOutputConfig config;
{ {
auto changeSet = config.changeSet(static_cast<AbstractWaylandOutput *>(outputs[0])); auto changeSet = config.changeSet(outputs[0]);
changeSet->pos = QPoint(-10, 20); changeSet->pos = QPoint(-10, 20);
} }
kwinApp()->platform()->applyOutputChanges(config); kwinApp()->platform()->applyOutputChanges(config);

View file

@ -2909,7 +2909,7 @@ void TestXdgShellClientRules::testScreenForce()
// Disable the output where the window is on, so the client is moved the other screen // Disable the output where the window is on, so the client is moved the other screen
WaylandOutputConfig config; WaylandOutputConfig config;
auto changeSet = config.changeSet(static_cast<AbstractWaylandOutput *>(outputs.at(1))); auto changeSet = config.changeSet(outputs.at(1));
changeSet->enabled = false; changeSet->enabled = false;
kwinApp()->platform()->applyOutputChanges(config); kwinApp()->platform()->applyOutputChanges(config);

View file

@ -10,7 +10,7 @@
#include "kwin_wayland_test.h" #include "kwin_wayland_test.h"
#include "abstract_client.h" #include "abstract_client.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "cursor.h" #include "cursor.h"
#include "decorations/decorationbridge.h" #include "decorations/decorationbridge.h"
#include "decorations/settings.h" #include "decorations/settings.h"

View file

@ -29,7 +29,6 @@ target_sources(kwin PRIVATE
3rdparty/xcursor.c 3rdparty/xcursor.c
abstract_client.cpp abstract_client.cpp
abstract_output.cpp abstract_output.cpp
abstract_wayland_output.cpp
activation.cpp activation.cpp
appmenu.cpp appmenu.cpp
atoms.cpp atoms.cpp

View file

@ -10,7 +10,6 @@
#include "abstract_client.h" #include "abstract_client.h"
#include "abstract_output.h" #include "abstract_output.h"
#include "abstract_wayland_output.h"
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
#endif #endif

View file

@ -8,8 +8,10 @@
*/ */
#include "abstract_output.h" #include "abstract_output.h"
#include "outputlayer.h" #include "waylandoutputconfig.h"
#include <KConfigGroup> #include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig> #include <KSharedConfig>
namespace KWin namespace KWin
@ -86,34 +88,44 @@ AbstractOutput::~AbstractOutput()
{ {
} }
QString AbstractOutput::name() const
{
return m_name;
}
QUuid AbstractOutput::uuid() const QUuid AbstractOutput::uuid() const
{ {
return QUuid(); return m_uuid;
} }
bool AbstractOutput::isEnabled() const AbstractOutput::Transform AbstractOutput::transform() const
{ {
return true; return m_transform;
} }
void AbstractOutput::setEnabled(bool enable) QString AbstractOutput::eisaId() const
{ {
Q_UNUSED(enable) return m_eisaId;
}
QString AbstractOutput::manufacturer() const
{
return m_manufacturer;
}
QString AbstractOutput::model() const
{
return m_model;
}
QString AbstractOutput::serialNumber() const
{
return m_serialNumber;
} }
bool AbstractOutput::isInternal() const bool AbstractOutput::isInternal() const
{ {
return false; return m_internal;
}
qreal AbstractOutput::scale() const
{
return 1;
}
QSize AbstractOutput::physicalSize() const
{
return QSize();
} }
int AbstractOutput::gammaRampSize() const int AbstractOutput::gammaRampSize() const
@ -127,25 +139,11 @@ bool AbstractOutput::setGammaRamp(const GammaRamp &gamma)
return false; return false;
} }
QString AbstractOutput::manufacturer() const
{
return QString();
}
QString AbstractOutput::model() const
{
return QString();
}
QString AbstractOutput::serialNumber() const
{
return QString();
}
void AbstractOutput::inhibitDirectScanout() void AbstractOutput::inhibitDirectScanout()
{ {
m_directScanoutCount++; m_directScanoutCount++;
} }
void AbstractOutput::uninhibitDirectScanout() void AbstractOutput::uninhibitDirectScanout()
{ {
m_directScanoutCount--; m_directScanoutCount--;
@ -172,4 +170,311 @@ QRect AbstractOutput::mapFromGlobal(const QRect &rect) const
return rect.translated(-geometry().topLeft()); return rect.translated(-geometry().topLeft());
} }
AbstractOutput::Capabilities AbstractOutput::capabilities() const
{
return m_capabilities;
}
void AbstractOutput::setCapabilityInternal(Capability capability, bool on)
{
if (static_cast<bool>(m_capabilities & capability) != on) {
m_capabilities.setFlag(capability, on);
Q_EMIT capabilitiesChanged();
}
}
qreal AbstractOutput::scale() const
{
return m_scale;
}
void AbstractOutput::setScale(qreal scale)
{
if (m_scale != scale) {
m_scale = scale;
Q_EMIT scaleChanged();
Q_EMIT geometryChanged();
}
}
QRect AbstractOutput::geometry() const
{
return QRect(m_position, pixelSize() / scale());
}
QSize AbstractOutput::physicalSize() const
{
return orientateSize(m_physicalSize);
}
int AbstractOutput::refreshRate() const
{
return m_refreshRate;
}
void AbstractOutput::moveTo(const QPoint &pos)
{
if (m_position != pos) {
m_position = pos;
Q_EMIT geometryChanged();
}
}
QSize AbstractOutput::modeSize() const
{
return m_modeSize;
}
QSize AbstractOutput::pixelSize() const
{
return orientateSize(m_modeSize);
}
QByteArray AbstractOutput::edid() const
{
return m_edid;
}
bool AbstractOutput::Mode::operator==(const Mode &other) const
{
return id == other.id && other.flags == flags && size == other.size && refreshRate == other.refreshRate;
}
QVector<AbstractOutput::Mode> AbstractOutput::modes() const
{
return m_modes;
}
void AbstractOutput::setModes(const QVector<Mode> &modes)
{
if (m_modes != modes) {
m_modes = modes;
Q_EMIT modesChanged();
}
}
AbstractOutput::SubPixel AbstractOutput::subPixel() const
{
return m_subPixel;
}
void AbstractOutput::setSubPixelInternal(SubPixel subPixel)
{
m_subPixel = subPixel;
}
void AbstractOutput::applyChanges(const WaylandOutputConfig &config)
{
auto props = config.constChangeSet(this);
Q_EMIT aboutToChange();
setEnabled(props->enabled);
updateTransform(props->transform);
moveTo(props->pos);
setScale(props->scale);
setVrrPolicy(props->vrrPolicy);
setRgbRangeInternal(props->rgbRange);
Q_EMIT changed();
}
bool AbstractOutput::isEnabled() const
{
return m_isEnabled;
}
void AbstractOutput::setEnabled(bool enable)
{
if (m_isEnabled != enable) {
m_isEnabled = enable;
updateEnablement(enable);
Q_EMIT enabledChanged();
}
}
QString AbstractOutput::description() const
{
return m_manufacturer + ' ' + m_model;
}
void AbstractOutput::setCurrentModeInternal(const QSize &size, int refreshRate)
{
const bool sizeChanged = m_modeSize != size;
if (sizeChanged || m_refreshRate != refreshRate) {
m_modeSize = size;
m_refreshRate = refreshRate;
Q_EMIT currentModeChanged();
if (sizeChanged) {
Q_EMIT geometryChanged();
}
}
}
static QUuid generateOutputId(const QString &eisaId, const QString &model,
const QString &serialNumber, const QString &name)
{
static const QUuid urlNs = QUuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); // NameSpace_URL
static const QUuid kwinNs = QUuid::createUuidV5(urlNs, QStringLiteral("https://kwin.kde.org/o/"));
const QString payload = QStringList{name, eisaId, model, serialNumber}.join(':');
return QUuid::createUuidV5(kwinNs, payload);
}
void AbstractOutput::initialize(const QString &model, const QString &manufacturer,
const QString &eisaId, const QString &serialNumber,
const QSize &physicalSize,
const QVector<Mode> &modes, const QByteArray &edid)
{
m_serialNumber = serialNumber;
m_eisaId = eisaId;
m_manufacturer = manufacturer.isEmpty() ? i18n("unknown") : manufacturer;
m_model = model;
m_physicalSize = physicalSize;
m_edid = edid;
m_modes = modes;
m_uuid = generateOutputId(m_eisaId, m_model, m_serialNumber, m_name);
for (const Mode &mode : modes) {
if (mode.flags & ModeFlag::Current) {
m_modeSize = mode.size;
m_refreshRate = mode.refreshRate;
break;
}
}
}
QSize AbstractOutput::orientateSize(const QSize &size) const
{
if (m_transform == Transform::Rotated90 || m_transform == Transform::Rotated270 || m_transform == Transform::Flipped90 || m_transform == Transform::Flipped270) {
return size.transposed();
}
return size;
}
void AbstractOutput::setTransformInternal(Transform transform)
{
if (m_transform != transform) {
m_transform = transform;
Q_EMIT transformChanged();
Q_EMIT currentModeChanged();
Q_EMIT geometryChanged();
}
}
void AbstractOutput::setDpmsModeInternal(DpmsMode dpmsMode)
{
if (m_dpmsMode != dpmsMode) {
m_dpmsMode = dpmsMode;
Q_EMIT dpmsModeChanged();
}
}
void AbstractOutput::setDpmsMode(DpmsMode mode)
{
Q_UNUSED(mode)
}
AbstractOutput::DpmsMode AbstractOutput::dpmsMode() const
{
return m_dpmsMode;
}
QMatrix4x4 AbstractOutput::logicalToNativeMatrix(const QRect &rect, qreal scale, Transform transform)
{
QMatrix4x4 matrix;
matrix.scale(scale);
switch (transform) {
case Transform::Normal:
case Transform::Flipped:
break;
case Transform::Rotated90:
case Transform::Flipped90:
matrix.translate(0, rect.width());
matrix.rotate(-90, 0, 0, 1);
break;
case Transform::Rotated180:
case Transform::Flipped180:
matrix.translate(rect.width(), rect.height());
matrix.rotate(-180, 0, 0, 1);
break;
case Transform::Rotated270:
case Transform::Flipped270:
matrix.translate(rect.height(), 0);
matrix.rotate(-270, 0, 0, 1);
break;
}
switch (transform) {
case Transform::Flipped:
case Transform::Flipped90:
case Transform::Flipped180:
case Transform::Flipped270:
matrix.translate(rect.width(), 0);
matrix.scale(-1, 1);
break;
default:
break;
}
matrix.translate(-rect.x(), -rect.y());
return matrix;
}
void AbstractOutput::setOverscanInternal(uint32_t overscan)
{
if (m_overscan != overscan) {
m_overscan = overscan;
Q_EMIT overscanChanged();
}
}
uint32_t AbstractOutput::overscan() const
{
return m_overscan;
}
void AbstractOutput::setVrrPolicy(RenderLoop::VrrPolicy policy)
{
if (renderLoop()->vrrPolicy() != policy && (m_capabilities & Capability::Vrr)) {
renderLoop()->setVrrPolicy(policy);
Q_EMIT vrrPolicyChanged();
}
}
RenderLoop::VrrPolicy AbstractOutput::vrrPolicy() const
{
return renderLoop()->vrrPolicy();
}
bool AbstractOutput::isPlaceholder() const
{
return m_isPlaceholder;
}
void AbstractOutput::setPlaceholder(bool isPlaceholder)
{
m_isPlaceholder = isPlaceholder;
}
AbstractOutput::RgbRange AbstractOutput::rgbRange() const
{
return m_rgbRange;
}
void AbstractOutput::setRgbRangeInternal(RgbRange range)
{
if (m_rgbRange != range) {
m_rgbRange = range;
Q_EMIT rgbRangeChanged();
}
}
void AbstractOutput::setPhysicalSizeInternal(const QSize &size)
{
m_physicalSize = size;
}
} // namespace KWin } // namespace KWin

View file

@ -11,22 +11,22 @@
#include <kwin_export.h> #include <kwin_export.h>
#include "renderloop.h"
#include <QDebug> #include <QDebug>
#include <QMatrix4x4>
#include <QObject> #include <QObject>
#include <QRect> #include <QRect>
#include <QSize> #include <QSize>
#include <QUuid> #include <QUuid>
#include <QVector> #include <QVector>
namespace KWaylandServer
{
class OutputChangeSetV2;
}
namespace KWin namespace KWin
{ {
class EffectScreenImpl; class EffectScreenImpl;
class RenderLoop; class RenderLoop;
class WaylandOutputConfig;
class KWIN_EXPORT GammaRamp class KWIN_EXPORT GammaRamp
{ {
@ -90,6 +90,56 @@ class KWIN_EXPORT AbstractOutput : public QObject
Q_OBJECT Q_OBJECT
public: public:
enum class ModeFlag : uint {
Current = 0x1,
Preferred = 0x2,
};
Q_DECLARE_FLAGS(ModeFlags, ModeFlag)
Q_ENUM(ModeFlag)
struct Mode
{
QSize size;
int refreshRate;
ModeFlags flags;
int id;
inline bool operator==(const Mode &other) const;
};
enum class DpmsMode {
On,
Standby,
Suspend,
Off,
};
Q_ENUM(DpmsMode)
enum class Capability : uint {
Dpms = 0x1,
Overscan = 0x2,
Vrr = 0x4,
RgbRange = 0x8,
};
Q_DECLARE_FLAGS(Capabilities, Capability)
enum class SubPixel {
Unknown,
None,
Horizontal_RGB,
Horizontal_BGR,
Vertical_RGB,
Vertical_BGR,
};
Q_ENUM(SubPixel)
enum class RgbRange {
Automatic = 0,
Full = 1,
Limited = 2,
};
Q_ENUM(RgbRange)
explicit AbstractOutput(QObject *parent = nullptr); explicit AbstractOutput(QObject *parent = nullptr);
~AbstractOutput() override; ~AbstractOutput() override;
@ -101,31 +151,31 @@ public:
/** /**
* Returns a short identifiable name of this output. * Returns a short identifiable name of this output.
*/ */
virtual QString name() const = 0; QString name() const;
/** /**
* Returns the identifying uuid of this output. * Returns the identifying uuid of this output.
* *
* Default implementation returns an empty byte array. * Default implementation returns an empty byte array.
*/ */
virtual QUuid uuid() const; QUuid uuid() const;
/** /**
* Returns @c true if the output is enabled; otherwise returns @c false. * Returns @c true if the output is enabled; otherwise returns @c false.
*/ */
virtual bool isEnabled() const; bool isEnabled() const;
/** /**
* Enable or disable the output. * Enable or disable the output.
* *
* Default implementation does nothing * Default implementation does nothing
*/ */
virtual void setEnabled(bool enable); void setEnabled(bool enable);
/** /**
* Returns geometry of this output in device independent pixels. * Returns geometry of this output in device independent pixels.
*/ */
virtual QRect geometry() const = 0; QRect geometry() const;
/** /**
* Equivalent to `QRect(QPoint(0, 0), geometry().size())` * Equivalent to `QRect(QPoint(0, 0), geometry().size())`
@ -135,29 +185,27 @@ public:
/** /**
* Returns the approximate vertical refresh rate of this output, in mHz. * Returns the approximate vertical refresh rate of this output, in mHz.
*/ */
virtual int refreshRate() const = 0; int refreshRate() const;
/** /**
* Returns whether this output is connected through an internal connector, * Returns whether this output is connected through an internal connector,
* e.g. LVDS, or eDP. * e.g. LVDS, or eDP.
*
* Default implementation returns @c false.
*/ */
virtual bool isInternal() const; bool isInternal() const;
/** /**
* Returns the ratio between physical pixels and logical pixels. * Returns the ratio between physical pixels and logical pixels.
* *
* Default implementation returns 1. * Default implementation returns 1.
*/ */
virtual qreal scale() const; qreal scale() const;
/** /**
* Returns the physical size of this output, in millimeters. * Returns the physical size of this output, in millimeters.
* *
* Default implementation returns an invalid QSize. * Default implementation returns an invalid QSize.
*/ */
virtual QSize physicalSize() const; QSize physicalSize() const;
/** /**
* Returns the size of the gamma lookup table. * Returns the size of the gamma lookup table.
@ -174,20 +222,23 @@ public:
virtual bool setGammaRamp(const GammaRamp &gamma); virtual bool setGammaRamp(const GammaRamp &gamma);
/** Returns the resolution of the output. */ /** Returns the resolution of the output. */
virtual QSize pixelSize() const = 0; QSize pixelSize() const;
QSize modeSize() const;
QString eisaId() const;
/** /**
* Returns the manufacturer of the screen. * Returns the manufacturer of the screen.
*/ */
virtual QString manufacturer() const; QString manufacturer() const;
/** /**
* Returns the model of the screen. * Returns the model of the screen.
*/ */
virtual QString model() const; QString model() const;
/** /**
* Returns the serial number of the screen. * Returns the serial number of the screen.
*/ */
virtual QString serialNumber() const; QString serialNumber() const;
/** /**
* Returns the RenderLoop for this output. If the platform does not support per screen * Returns the RenderLoop for this output. If the platform does not support per screen
@ -221,13 +272,37 @@ public:
Flipped270 Flipped270
}; };
Q_ENUM(Transform) Q_ENUM(Transform)
virtual Transform transform() const Transform transform() const;
{
return Transform::Normal;
}
virtual bool usesSoftwareCursor() const; virtual bool usesSoftwareCursor() const;
void moveTo(const QPoint &pos);
void setScale(qreal scale);
void applyChanges(const WaylandOutputConfig &config);
SubPixel subPixel() const;
QString description() const;
Capabilities capabilities() const;
QByteArray edid() const;
QVector<Mode> modes() const;
void setModes(const QVector<Mode> &modes);
DpmsMode dpmsMode() const;
virtual void setDpmsMode(DpmsMode mode);
uint32_t overscan() const;
/**
* Returns a matrix that can translate into the display's coordinates system
*/
static QMatrix4x4 logicalToNativeMatrix(const QRect &rect, qreal scale, Transform transform);
void setVrrPolicy(RenderLoop::VrrPolicy policy);
RenderLoop::VrrPolicy vrrPolicy() const;
RgbRange rgbRange() const;
bool isPlaceholder() const;
Q_SIGNALS: Q_SIGNALS:
/** /**
* This signal is emitted when the geometry of this output has changed. * This signal is emitted when the geometry of this output has changed.
@ -272,10 +347,78 @@ Q_SIGNALS:
*/ */
void changed(); void changed();
void currentModeChanged();
void modesChanged();
void outputChange(const QRegion &damagedRegion);
void transformChanged();
void dpmsModeChanged();
void capabilitiesChanged();
void overscanChanged();
void vrrPolicyChanged();
void rgbRangeChanged();
protected:
void initialize(const QString &model, const QString &manufacturer,
const QString &eisaId, const QString &serialNumber,
const QSize &physicalSize,
const QVector<Mode> &modes, const QByteArray &edid);
void setName(const QString &name)
{
m_name = name;
}
void setInternal(bool set)
{
m_internal = set;
}
virtual void updateEnablement(bool enable)
{
Q_UNUSED(enable);
}
virtual void updateTransform(Transform transform)
{
Q_UNUSED(transform);
}
void setCurrentModeInternal(const QSize &size, int refreshRate);
void setTransformInternal(Transform transform);
void setDpmsModeInternal(DpmsMode dpmsMode);
void setCapabilityInternal(Capability capability, bool on = true);
void setSubPixelInternal(SubPixel subPixel);
void setOverscanInternal(uint32_t overscan);
void setPlaceholder(bool isPlaceholder);
void setRgbRangeInternal(RgbRange range);
void setPhysicalSizeInternal(const QSize &size);
QSize orientateSize(const QSize &size) const;
private: private:
Q_DISABLE_COPY(AbstractOutput) Q_DISABLE_COPY(AbstractOutput)
EffectScreenImpl *m_effectScreen = nullptr; EffectScreenImpl *m_effectScreen = nullptr;
int m_directScanoutCount = 0; int m_directScanoutCount = 0;
QString m_name;
QString m_eisaId;
QString m_manufacturer;
QString m_model;
QString m_serialNumber;
QUuid m_uuid;
QSize m_modeSize;
QSize m_physicalSize;
QPoint m_position;
qreal m_scale = 1;
Capabilities m_capabilities;
Transform m_transform = Transform::Normal;
QByteArray m_edid;
QVector<Mode> m_modes;
DpmsMode m_dpmsMode = DpmsMode::On;
SubPixel m_subPixel = SubPixel::Unknown;
int m_refreshRate = -1;
bool m_isEnabled = true;
bool m_internal = false;
bool m_isPlaceholder = false;
uint32_t m_overscan = 0;
RgbRange m_rgbRange = RgbRange::Automatic;
friend class EffectScreenImpl; // to access m_effectScreen friend class EffectScreenImpl; // to access m_effectScreen
}; };
@ -288,4 +431,6 @@ KWIN_EXPORT QDebug operator<<(QDebug debug, const AbstractOutput *output);
} // namespace KWin } // namespace KWin
Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::AbstractOutput::Capabilities)
#endif #endif

View file

@ -1,366 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "abstract_wayland_output.h"
#include "screens.h"
#include "waylandoutputconfig.h"
// KWayland
#include <KWaylandServer/outputchangeset_v2.h>
// KF5
#include <KLocalizedString>
#include <QMatrix4x4>
namespace KWin
{
AbstractWaylandOutput::AbstractWaylandOutput(QObject *parent)
: AbstractOutput(parent)
{
}
AbstractWaylandOutput::Capabilities AbstractWaylandOutput::capabilities() const
{
return m_capabilities;
}
void AbstractWaylandOutput::setCapabilityInternal(Capability capability, bool on)
{
if (static_cast<bool>(m_capabilities & capability) != on) {
m_capabilities.setFlag(capability, on);
Q_EMIT capabilitiesChanged();
}
}
QString AbstractWaylandOutput::name() const
{
return m_name;
}
QUuid AbstractWaylandOutput::uuid() const
{
return m_uuid;
}
QRect AbstractWaylandOutput::geometry() const
{
return QRect(m_position, pixelSize() / scale());
}
QSize AbstractWaylandOutput::physicalSize() const
{
return orientateSize(m_physicalSize);
}
int AbstractWaylandOutput::refreshRate() const
{
return m_refreshRate;
}
void AbstractWaylandOutput::moveTo(const QPoint &pos)
{
if (m_position != pos) {
m_position = pos;
Q_EMIT geometryChanged();
}
}
QString AbstractWaylandOutput::eisaId() const
{
return m_eisaId;
}
QString AbstractWaylandOutput::manufacturer() const
{
return m_manufacturer;
}
QString AbstractWaylandOutput::model() const
{
return m_model;
}
QString AbstractWaylandOutput::serialNumber() const
{
return m_serialNumber;
}
QSize AbstractWaylandOutput::modeSize() const
{
return m_modeSize;
}
QSize AbstractWaylandOutput::pixelSize() const
{
return orientateSize(m_modeSize);
}
QByteArray AbstractWaylandOutput::edid() const
{
return m_edid;
}
bool AbstractWaylandOutput::Mode::operator==(const Mode &other) const
{
return id == other.id && other.flags == flags && size == other.size && refreshRate == other.refreshRate;
}
QVector<AbstractWaylandOutput::Mode> AbstractWaylandOutput::modes() const
{
return m_modes;
}
void AbstractWaylandOutput::setModes(const QVector<Mode> &modes)
{
if (m_modes != modes) {
m_modes = modes;
Q_EMIT modesChanged();
}
}
qreal AbstractWaylandOutput::scale() const
{
return m_scale;
}
void AbstractWaylandOutput::setScale(qreal scale)
{
if (m_scale != scale) {
m_scale = scale;
Q_EMIT scaleChanged();
Q_EMIT geometryChanged();
}
}
AbstractWaylandOutput::SubPixel AbstractWaylandOutput::subPixel() const
{
return m_subPixel;
}
void AbstractWaylandOutput::setSubPixelInternal(SubPixel subPixel)
{
m_subPixel = subPixel;
}
void AbstractWaylandOutput::applyChanges(const WaylandOutputConfig &config)
{
auto props = config.constChangeSet(this);
Q_EMIT aboutToChange();
setEnabled(props->enabled);
updateTransform(props->transform);
moveTo(props->pos);
setScale(props->scale);
setVrrPolicy(props->vrrPolicy);
setRgbRangeInternal(props->rgbRange);
Q_EMIT changed();
}
bool AbstractWaylandOutput::isEnabled() const
{
return m_isEnabled;
}
void AbstractWaylandOutput::setEnabled(bool enable)
{
if (m_isEnabled != enable) {
m_isEnabled = enable;
updateEnablement(enable);
Q_EMIT enabledChanged();
}
}
QString AbstractWaylandOutput::description() const
{
return m_manufacturer + ' ' + m_model;
}
void AbstractWaylandOutput::setCurrentModeInternal(const QSize &size, int refreshRate)
{
const bool sizeChanged = m_modeSize != size;
if (sizeChanged || m_refreshRate != refreshRate) {
m_modeSize = size;
m_refreshRate = refreshRate;
Q_EMIT currentModeChanged();
if (sizeChanged) {
Q_EMIT geometryChanged();
}
}
}
static QUuid generateOutputId(const QString &eisaId, const QString &model,
const QString &serialNumber, const QString &name)
{
static const QUuid urlNs = QUuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); // NameSpace_URL
static const QUuid kwinNs = QUuid::createUuidV5(urlNs, QStringLiteral("https://kwin.kde.org/o/"));
const QString payload = QStringList{name, eisaId, model, serialNumber}.join(':');
return QUuid::createUuidV5(kwinNs, payload);
}
void AbstractWaylandOutput::initialize(const QString &model, const QString &manufacturer,
const QString &eisaId, const QString &serialNumber,
const QSize &physicalSize,
const QVector<Mode> &modes, const QByteArray &edid)
{
m_serialNumber = serialNumber;
m_eisaId = eisaId;
m_manufacturer = manufacturer.isEmpty() ? i18n("unknown") : manufacturer;
m_model = model;
m_physicalSize = physicalSize;
m_edid = edid;
m_modes = modes;
m_uuid = generateOutputId(m_eisaId, m_model, m_serialNumber, m_name);
for (const Mode &mode : modes) {
if (mode.flags & ModeFlag::Current) {
m_modeSize = mode.size;
m_refreshRate = mode.refreshRate;
break;
}
}
}
QSize AbstractWaylandOutput::orientateSize(const QSize &size) const
{
if (m_transform == Transform::Rotated90 || m_transform == Transform::Rotated270 || m_transform == Transform::Flipped90 || m_transform == Transform::Flipped270) {
return size.transposed();
}
return size;
}
void AbstractWaylandOutput::setTransformInternal(Transform transform)
{
if (m_transform != transform) {
m_transform = transform;
Q_EMIT transformChanged();
Q_EMIT currentModeChanged();
Q_EMIT geometryChanged();
}
}
AbstractWaylandOutput::Transform AbstractWaylandOutput::transform() const
{
return m_transform;
}
void AbstractWaylandOutput::setDpmsModeInternal(DpmsMode dpmsMode)
{
if (m_dpmsMode != dpmsMode) {
m_dpmsMode = dpmsMode;
Q_EMIT dpmsModeChanged();
}
}
void AbstractWaylandOutput::setDpmsMode(DpmsMode mode)
{
Q_UNUSED(mode)
}
AbstractWaylandOutput::DpmsMode AbstractWaylandOutput::dpmsMode() const
{
return m_dpmsMode;
}
QMatrix4x4 AbstractWaylandOutput::logicalToNativeMatrix(const QRect &rect, qreal scale, Transform transform)
{
QMatrix4x4 matrix;
matrix.scale(scale);
switch (transform) {
case Transform::Normal:
case Transform::Flipped:
break;
case Transform::Rotated90:
case Transform::Flipped90:
matrix.translate(0, rect.width());
matrix.rotate(-90, 0, 0, 1);
break;
case Transform::Rotated180:
case Transform::Flipped180:
matrix.translate(rect.width(), rect.height());
matrix.rotate(-180, 0, 0, 1);
break;
case Transform::Rotated270:
case Transform::Flipped270:
matrix.translate(rect.height(), 0);
matrix.rotate(-270, 0, 0, 1);
break;
}
switch (transform) {
case Transform::Flipped:
case Transform::Flipped90:
case Transform::Flipped180:
case Transform::Flipped270:
matrix.translate(rect.width(), 0);
matrix.scale(-1, 1);
break;
default:
break;
}
matrix.translate(-rect.x(), -rect.y());
return matrix;
}
void AbstractWaylandOutput::setOverscanInternal(uint32_t overscan)
{
if (m_overscan != overscan) {
m_overscan = overscan;
Q_EMIT overscanChanged();
}
}
uint32_t AbstractWaylandOutput::overscan() const
{
return m_overscan;
}
void AbstractWaylandOutput::setVrrPolicy(RenderLoop::VrrPolicy policy)
{
if (renderLoop()->vrrPolicy() != policy && (m_capabilities & Capability::Vrr)) {
renderLoop()->setVrrPolicy(policy);
Q_EMIT vrrPolicyChanged();
}
}
RenderLoop::VrrPolicy AbstractWaylandOutput::vrrPolicy() const
{
return renderLoop()->vrrPolicy();
}
bool AbstractWaylandOutput::isPlaceholder() const
{
return m_isPlaceholder;
}
void AbstractWaylandOutput::setPlaceholder(bool isPlaceholder)
{
m_isPlaceholder = isPlaceholder;
}
AbstractWaylandOutput::RgbRange AbstractWaylandOutput::rgbRange() const
{
return m_rgbRange;
}
void AbstractWaylandOutput::setRgbRangeInternal(RgbRange range)
{
if (m_rgbRange != range) {
m_rgbRange = range;
Q_EMIT rgbRangeChanged();
}
}
}

View file

@ -1,224 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KWIN_ABSTRACT_WAYLAND_OUTPUT_H
#define KWIN_ABSTRACT_WAYLAND_OUTPUT_H
#include "abstract_output.h"
#include "renderloop.h"
#include "utils/common.h"
#include <kwin_export.h>
#include <QObject>
#include <QSize>
#include <QTimer>
namespace KWin
{
class WaylandOutputConfig;
/**
* Generic output representation in a Wayland session
*/
class KWIN_EXPORT AbstractWaylandOutput : public AbstractOutput
{
Q_OBJECT
public:
enum class ModeFlag : uint {
Current = 0x1,
Preferred = 0x2,
};
Q_DECLARE_FLAGS(ModeFlags, ModeFlag)
Q_ENUM(ModeFlag)
struct Mode
{
QSize size;
int refreshRate;
ModeFlags flags;
int id;
inline bool operator==(const Mode &other) const;
};
enum class DpmsMode {
On,
Standby,
Suspend,
Off,
};
Q_ENUM(DpmsMode)
enum class Capability : uint {
Dpms = 0x1,
Overscan = 0x2,
Vrr = 0x4,
RgbRange = 0x8,
};
Q_DECLARE_FLAGS(Capabilities, Capability)
enum class SubPixel {
Unknown,
None,
Horizontal_RGB,
Horizontal_BGR,
Vertical_RGB,
Vertical_BGR,
};
Q_ENUM(SubPixel)
enum class RgbRange {
Automatic = 0,
Full = 1,
Limited = 2,
};
Q_ENUM(RgbRange)
explicit AbstractWaylandOutput(QObject *parent = nullptr);
QString name() const override;
QUuid uuid() const override;
QSize modeSize() const;
// TODO: The name is ambiguous. Rename this function.
QSize pixelSize() const override;
qreal scale() const override;
QRect geometry() const override;
QSize physicalSize() const override;
/**
* Returns the orientation of this output.
*
* - Flipped along the vertical axis is landscape + inv. portrait.
* - Rotated 90° and flipped along the horizontal axis is portrait + inv. landscape
* - Rotated 180° and flipped along the vertical axis is inv. landscape + inv. portrait
* - Rotated 270° and flipped along the horizontal axis is inv. portrait + inv. landscape +
* portrait
*/
Transform transform() const override;
int refreshRate() const override;
bool isInternal() const override
{
return m_internal;
}
QString eisaId() const;
QString manufacturer() const override;
QString model() const override;
QString serialNumber() const override;
void moveTo(const QPoint &pos);
void setScale(qreal scale);
void applyChanges(const WaylandOutputConfig &config);
bool isEnabled() const override;
void setEnabled(bool enable) override;
SubPixel subPixel() const;
QString description() const;
Capabilities capabilities() const;
QByteArray edid() const;
QVector<Mode> modes() const;
void setModes(const QVector<Mode> &modes);
DpmsMode dpmsMode() const;
virtual void setDpmsMode(DpmsMode mode);
uint32_t overscan() const;
/**
* Returns a matrix that can translate into the display's coordinates system
*/
static QMatrix4x4 logicalToNativeMatrix(const QRect &rect, qreal scale, Transform transform);
void setVrrPolicy(RenderLoop::VrrPolicy policy);
RenderLoop::VrrPolicy vrrPolicy() const;
RgbRange rgbRange() const;
bool isPlaceholder() const;
Q_SIGNALS:
void currentModeChanged();
void modesChanged();
void outputChange(const QRegion &damagedRegion);
void transformChanged();
void dpmsModeChanged();
void capabilitiesChanged();
void overscanChanged();
void vrrPolicyChanged();
void rgbRangeChanged();
protected:
void initialize(const QString &model, const QString &manufacturer,
const QString &eisaId, const QString &serialNumber,
const QSize &physicalSize,
const QVector<Mode> &modes, const QByteArray &edid);
void setName(const QString &name)
{
m_name = name;
}
void setInternal(bool set)
{
m_internal = set;
}
virtual void updateEnablement(bool enable)
{
Q_UNUSED(enable);
}
virtual void updateTransform(Transform transform)
{
Q_UNUSED(transform);
}
void setCurrentModeInternal(const QSize &size, int refreshRate);
void setTransformInternal(Transform transform);
void setDpmsModeInternal(DpmsMode dpmsMode);
void setCapabilityInternal(Capability capability, bool on = true);
void setSubPixelInternal(SubPixel subPixel);
void setOverscanInternal(uint32_t overscan);
void setPlaceholder(bool isPlaceholder);
void setRgbRangeInternal(RgbRange range);
QSize orientateSize(const QSize &size) const;
private:
QString m_name;
QString m_eisaId;
QString m_manufacturer;
QString m_model;
QString m_serialNumber;
QUuid m_uuid;
QSize m_modeSize;
QSize m_physicalSize;
QPoint m_position;
qreal m_scale = 1;
Capabilities m_capabilities;
Transform m_transform = Transform::Normal;
QByteArray m_edid;
QVector<Mode> m_modes;
DpmsMode m_dpmsMode = DpmsMode::On;
SubPixel m_subPixel = SubPixel::Unknown;
int m_refreshRate = -1;
bool m_isEnabled = true;
bool m_internal = false;
bool m_isPlaceholder = false;
uint32_t m_overscan = 0;
RgbRange m_rgbRange = RgbRange::Automatic;
};
}
Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::AbstractWaylandOutput::Capabilities)
#endif // KWIN_OUTPUT_H

View file

@ -15,7 +15,7 @@ namespace KWin
{ {
DrmAbstractOutput::DrmAbstractOutput(DrmGpu *gpu) DrmAbstractOutput::DrmAbstractOutput(DrmGpu *gpu)
: AbstractWaylandOutput(gpu->platform()) : AbstractOutput(gpu->platform())
, m_renderLoop(new RenderLoop(this)) , m_renderLoop(new RenderLoop(this))
, m_gpu(gpu) , m_gpu(gpu)
{ {
@ -39,7 +39,7 @@ void DrmAbstractOutput::pageFlipped(std::chrono::nanoseconds timestamp) const
QVector<int32_t> DrmAbstractOutput::regionToRects(const QRegion &region) const QVector<int32_t> DrmAbstractOutput::regionToRects(const QRegion &region) const
{ {
const int height = pixelSize().height(); const int height = pixelSize().height();
const QMatrix4x4 matrix = AbstractWaylandOutput::logicalToNativeMatrix(rect(), scale(), transform()); const QMatrix4x4 matrix = AbstractOutput::logicalToNativeMatrix(rect(), scale(), transform());
QVector<EGLint> rects; QVector<EGLint> rects;
rects.reserve(region.rectCount() * 4); rects.reserve(region.rectCount() * 4);
for (const QRect &_rect : region) { for (const QRect &_rect : region) {

View file

@ -8,7 +8,7 @@
*/ */
#pragma once #pragma once
#include "abstract_wayland_output.h" #include "abstract_output.h"
namespace KWin namespace KWin
{ {
@ -17,7 +17,7 @@ class DrmBackend;
class DrmGpu; class DrmGpu;
class DrmOutputLayer; class DrmOutputLayer;
class DrmAbstractOutput : public AbstractWaylandOutput class DrmAbstractOutput : public AbstractOutput
{ {
Q_OBJECT Q_OBJECT
public: public:

View file

@ -107,7 +107,7 @@ void DrmBackend::turnOutputsOn()
{ {
m_dpmsFilter.reset(); m_dpmsFilter.reset();
for (auto it = m_enabledOutputs.constBegin(), end = m_enabledOutputs.constEnd(); it != end; it++) { for (auto it = m_enabledOutputs.constBegin(), end = m_enabledOutputs.constEnd(); it != end; it++) {
(*it)->setDpmsMode(AbstractWaylandOutput::DpmsMode::On); (*it)->setDpmsMode(AbstractOutput::DpmsMode::On);
} }
} }
@ -118,7 +118,7 @@ void DrmBackend::checkOutputsAreOn()
return; return;
} }
for (auto it = m_enabledOutputs.constBegin(), end = m_enabledOutputs.constEnd(); it != end; it++) { for (auto it = m_enabledOutputs.constBegin(), end = m_enabledOutputs.constEnd(); it != end; it++) {
if ((*it)->dpmsMode() != AbstractWaylandOutput::DpmsMode::On) { if ((*it)->dpmsMode() != AbstractOutput::DpmsMode::On) {
// dpms still disabled, need to keep the filter // dpms still disabled, need to keep the filter
return; return;
} }
@ -435,7 +435,7 @@ bool DrmBackend::readOutputsConfiguration(const QVector<DrmAbstractOutput *> &ou
Q_ASSERT(!outputs.isEmpty()); Q_ASSERT(!outputs.isEmpty());
const auto outputsInfo = KWinKScreenIntegration::outputsConfig(outputs); const auto outputsInfo = KWinKScreenIntegration::outputsConfig(outputs);
AbstractWaylandOutput *primaryOutput = outputs.constFirst(); AbstractOutput *primaryOutput = outputs.constFirst();
WaylandOutputConfig cfg; WaylandOutputConfig cfg;
// default position goes from left to right // default position goes from left to right
QPoint pos(0, 0); QPoint pos(0, 0);
@ -460,7 +460,7 @@ bool DrmBackend::readOutputsConfiguration(const QVector<DrmAbstractOutput *> &ou
props->overscan = static_cast<uint32_t>(outputInfo["overscan"].toInt(props->overscan)); props->overscan = static_cast<uint32_t>(outputInfo["overscan"].toInt(props->overscan));
props->vrrPolicy = static_cast<RenderLoop::VrrPolicy>(outputInfo["vrrpolicy"].toInt(static_cast<uint32_t>(props->vrrPolicy))); props->vrrPolicy = static_cast<RenderLoop::VrrPolicy>(outputInfo["vrrpolicy"].toInt(static_cast<uint32_t>(props->vrrPolicy)));
props->rgbRange = static_cast<AbstractWaylandOutput::RgbRange>(outputInfo["rgbrange"].toInt(static_cast<uint32_t>(props->rgbRange))); props->rgbRange = static_cast<AbstractOutput::RgbRange>(outputInfo["rgbrange"].toInt(static_cast<uint32_t>(props->rgbRange)));
if (const QJsonObject mode = outputInfo["mode"].toObject(); !mode.isEmpty()) { if (const QJsonObject mode = outputInfo["mode"].toObject(); !mode.isEmpty()) {
const QJsonObject size = mode["size"].toObject(); const QJsonObject size = mode["size"].toObject();

View file

@ -207,21 +207,21 @@ QSharedPointer<DrmConnectorMode> DrmConnector::findMode(const drmModeModeInfo &m
return it == m_modes.constEnd() ? nullptr : *it; return it == m_modes.constEnd() ? nullptr : *it;
} }
AbstractWaylandOutput::SubPixel DrmConnector::subpixel() const AbstractOutput::SubPixel DrmConnector::subpixel() const
{ {
switch (m_conn->subpixel) { switch (m_conn->subpixel) {
case DRM_MODE_SUBPIXEL_UNKNOWN: case DRM_MODE_SUBPIXEL_UNKNOWN:
return AbstractWaylandOutput::SubPixel::Unknown; return AbstractOutput::SubPixel::Unknown;
case DRM_MODE_SUBPIXEL_NONE: case DRM_MODE_SUBPIXEL_NONE:
return AbstractWaylandOutput::SubPixel::None; return AbstractOutput::SubPixel::None;
case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB: case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
return AbstractWaylandOutput::SubPixel::Horizontal_RGB; return AbstractOutput::SubPixel::Horizontal_RGB;
case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR: case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
return AbstractWaylandOutput::SubPixel::Horizontal_BGR; return AbstractOutput::SubPixel::Horizontal_BGR;
case DRM_MODE_SUBPIXEL_VERTICAL_RGB: case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
return AbstractWaylandOutput::SubPixel::Vertical_RGB; return AbstractOutput::SubPixel::Vertical_RGB;
case DRM_MODE_SUBPIXEL_VERTICAL_BGR: case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
return AbstractWaylandOutput::SubPixel::Vertical_BGR; return AbstractOutput::SubPixel::Vertical_BGR;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
@ -271,10 +271,10 @@ bool DrmConnector::hasRgbRange() const
return rgb && rgb->hasAllEnums(); return rgb && rgb->hasAllEnums();
} }
AbstractWaylandOutput::RgbRange DrmConnector::rgbRange() const AbstractOutput::RgbRange DrmConnector::rgbRange() const
{ {
const auto &rgb = getProp(PropertyIndex::Broadcast_RGB); const auto &rgb = getProp(PropertyIndex::Broadcast_RGB);
return rgb->enumForValue<AbstractWaylandOutput::RgbRange>(rgb->pending()); return rgb->enumForValue<AbstractOutput::RgbRange>(rgb->pending());
} }
bool DrmConnector::updateProperties() bool DrmConnector::updateProperties()

View file

@ -14,7 +14,7 @@
#include <QSize> #include <QSize>
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "drm_object.h" #include "drm_object.h"
#include "drm_pointer.h" #include "drm_pointer.h"
#include "edid.h" #include "edid.h"
@ -101,12 +101,12 @@ public:
QVector<QSharedPointer<DrmConnectorMode>> modes() const; QVector<QSharedPointer<DrmConnectorMode>> modes() const;
QSharedPointer<DrmConnectorMode> findMode(const drmModeModeInfo &modeInfo) const; QSharedPointer<DrmConnectorMode> findMode(const drmModeModeInfo &modeInfo) const;
AbstractWaylandOutput::SubPixel subpixel() const; AbstractOutput::SubPixel subpixel() const;
bool hasOverscan() const; bool hasOverscan() const;
uint32_t overscan() const; uint32_t overscan() const;
bool vrrCapable() const; bool vrrCapable() const;
bool hasRgbRange() const; bool hasRgbRange() const;
AbstractWaylandOutput::RgbRange rgbRange() const; AbstractOutput::RgbRange rgbRange() const;
LinkStatus linkStatus() const; LinkStatus linkStatus() const;
private: private:

View file

@ -165,7 +165,7 @@ void DrmOutput::moveCursor()
} }
} }
QVector<AbstractWaylandOutput::Mode> DrmOutput::getModes() const QVector<AbstractOutput::Mode> DrmOutput::getModes() const
{ {
bool modeFound = false; bool modeFound = false;
QVector<Mode> modes; QVector<Mode> modes;

View file

@ -18,6 +18,7 @@
#include <QPoint> #include <QPoint>
#include <QSharedPointer> #include <QSharedPointer>
#include <QSize> #include <QSize>
#include <QTimer>
#include <QVector> #include <QVector>
#include <chrono> #include <chrono>
#include <xf86drmMode.h> #include <xf86drmMode.h>
@ -63,7 +64,7 @@ private:
bool setDrmDpmsMode(DpmsMode mode); bool setDrmDpmsMode(DpmsMode mode);
void setDpmsMode(DpmsMode mode) override; void setDpmsMode(DpmsMode mode) override;
QVector<AbstractWaylandOutput::Mode> getModes() const; QVector<AbstractOutput::Mode> getModes() const;
int gammaRampSize() const override; int gammaRampSize() const override;
bool setGammaRamp(const GammaRamp &gamma) override; bool setGammaRamp(const GammaRamp &gamma) override;

View file

@ -17,7 +17,7 @@
#include <chrono> #include <chrono>
#include <xf86drmMode.h> #include <xf86drmMode.h>
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "drm_object_plane.h" #include "drm_object_plane.h"
#include "renderloop_p.h" #include "renderloop_p.h"
@ -104,7 +104,7 @@ public:
bool enabled = true; // whether or not the pipeline needs a crtc bool enabled = true; // whether or not the pipeline needs a crtc
QSharedPointer<DrmConnectorMode> mode; QSharedPointer<DrmConnectorMode> mode;
uint32_t overscan = 0; uint32_t overscan = 0;
AbstractWaylandOutput::RgbRange rgbRange = AbstractWaylandOutput::RgbRange::Automatic; AbstractOutput::RgbRange rgbRange = AbstractOutput::RgbRange::Automatic;
RenderLoopPrivate::SyncMode syncMode = RenderLoopPrivate::SyncMode::Fixed; RenderLoopPrivate::SyncMode syncMode = RenderLoopPrivate::SyncMode::Fixed;
QSharedPointer<DrmGammaRamp> gamma; QSharedPointer<DrmGammaRamp> gamma;

View file

@ -34,7 +34,7 @@ DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize
setName("Virtual-" + name); setName("Virtual-" + name);
m_modeIndex = 0; m_modeIndex = 0;
QVector<Mode> modes = {{size, 60000, AbstractWaylandOutput::ModeFlags(AbstractWaylandOutput::ModeFlag::Current) | AbstractWaylandOutput::ModeFlag::Preferred, 0}}; QVector<Mode> modes = {{size, 60000, AbstractOutput::ModeFlags(AbstractOutput::ModeFlag::Current) | AbstractOutput::ModeFlag::Preferred, 0}};
initialize(QLatin1String("model_") + name, initialize(QLatin1String("model_") + name,
QLatin1String("manufacturer_") + name, QLatin1String("manufacturer_") + name,
QLatin1String("eisa_") + name, QLatin1String("eisa_") + name,

View file

@ -14,7 +14,7 @@
// TODO: Make it compile also in testing environment // TODO: Make it compile also in testing environment
#ifndef KWIN_BUILD_TESTING #ifndef KWIN_BUILD_TESTING
#include "abstract_client.h" #include "abstract_client.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "main.h" #include "main.h"
#include "platform.h" #include "platform.h"
#include "workspace.h" #include "workspace.h"
@ -194,9 +194,9 @@ void Connection::handleEvent()
} }
#ifndef KWIN_BUILD_TESTING #ifndef KWIN_BUILD_TESTING
QPointF devicePointToGlobalPosition(const QPointF &devicePos, const AbstractWaylandOutput *output) QPointF devicePointToGlobalPosition(const QPointF &devicePos, const AbstractOutput *output)
{ {
using Transform = AbstractWaylandOutput::Transform; using Transform = AbstractOutput::Transform;
QPointF pos = devicePos; QPointF pos = devicePos;
// TODO: Do we need to handle the flipped cases differently? // TODO: Do we need to handle the flipped cases differently?
@ -358,10 +358,8 @@ void Connection::processEvents()
case LIBINPUT_EVENT_TOUCH_DOWN: { case LIBINPUT_EVENT_TOUCH_DOWN: {
#ifndef KWIN_BUILD_TESTING #ifndef KWIN_BUILD_TESTING
TouchEvent *te = static_cast<TouchEvent *>(event.data()); TouchEvent *te = static_cast<TouchEvent *>(event.data());
const auto *output = static_cast<AbstractWaylandOutput *>(te->device()->output()); const auto *output = te->device()->output();
const QPointF globalPos = const QPointF globalPos = devicePointToGlobalPosition(te->absolutePos(output->modeSize()), output);
devicePointToGlobalPosition(te->absolutePos(output->modeSize()),
output);
Q_EMIT te->device()->touchDown(te->id(), globalPos, te->time(), te->device()); Q_EMIT te->device()->touchDown(te->id(), globalPos, te->time(), te->device());
break; break;
#endif #endif
@ -374,10 +372,8 @@ void Connection::processEvents()
case LIBINPUT_EVENT_TOUCH_MOTION: { case LIBINPUT_EVENT_TOUCH_MOTION: {
#ifndef KWIN_BUILD_TESTING #ifndef KWIN_BUILD_TESTING
TouchEvent *te = static_cast<TouchEvent *>(event.data()); TouchEvent *te = static_cast<TouchEvent *>(event.data());
const auto *output = static_cast<AbstractWaylandOutput *>(te->device()->output()); const auto *output = te->device()->output();
const QPointF globalPos = const QPointF globalPos = devicePointToGlobalPosition(te->absolutePos(output->modeSize()), output);
devicePointToGlobalPosition(te->absolutePos(output->modeSize()),
output);
Q_EMIT te->device()->touchMotion(te->id(), globalPos, te->time(), te->device()); Q_EMIT te->device()->touchMotion(te->id(), globalPos, te->time(), te->device());
break; break;
#endif #endif
@ -477,12 +473,12 @@ void Connection::processEvents()
if (workspace()) { if (workspace()) {
#ifndef KWIN_BUILD_TESTING #ifndef KWIN_BUILD_TESTING
AbstractWaylandOutput *output = static_cast<AbstractWaylandOutput *>(tte->device()->output()); AbstractOutput *output = tte->device()->output();
if (!output && workspace()->activeClient()) { if (!output && workspace()->activeClient()) {
output = static_cast<AbstractWaylandOutput *>(workspace()->activeClient()->output()); output = workspace()->activeClient()->output();
} }
if (!output) { if (!output) {
output = static_cast<AbstractWaylandOutput *>(workspace()->activeOutput()); output = workspace()->activeOutput();
} }
const QPointF globalPos = const QPointF globalPos =
devicePointToGlobalPosition(tte->transformedPosition(output->modeSize()), devicePointToGlobalPosition(tte->transformedPosition(output->modeSize()),

View file

@ -672,6 +672,7 @@ AbstractOutput *Device::output() const
void Device::setOutput(AbstractOutput *output) void Device::setOutput(AbstractOutput *output)
{ {
#ifndef KWIN_BUILD_TESTING
m_output = output; m_output = output;
if (m_output) { if (m_output) {
writeEntry(ConfigKey::OutputName, output->name()); writeEntry(ConfigKey::OutputName, output->name());
@ -679,6 +680,9 @@ void Device::setOutput(AbstractOutput *output)
writeEntry(ConfigKey::OutputName, QString()); writeEntry(ConfigKey::OutputName, QString());
} }
Q_EMIT outputNameChanged(); Q_EMIT outputNameChanged();
#else
Q_UNUSED(output)
#endif
} }
static libinput_led toLibinputLEDS(LEDs leds) static libinput_led toLibinputLEDS(LEDs leds)

View file

@ -16,7 +16,7 @@ namespace KWin
{ {
VirtualOutput::VirtualOutput(VirtualBackend *parent) VirtualOutput::VirtualOutput(VirtualBackend *parent)
: AbstractWaylandOutput(parent) : AbstractOutput(parent)
, m_backend(parent) , m_backend(parent)
, m_renderLoop(new RenderLoop(this)) , m_renderLoop(new RenderLoop(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create(this)) , m_vsyncMonitor(SoftwareVsyncMonitor::create(this))

View file

@ -9,7 +9,7 @@
#ifndef KWIN_VIRTUAL_OUTPUT_H #ifndef KWIN_VIRTUAL_OUTPUT_H
#define KWIN_VIRTUAL_OUTPUT_H #define KWIN_VIRTUAL_OUTPUT_H
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include <QObject> #include <QObject>
#include <QRect> #include <QRect>
@ -20,7 +20,7 @@ namespace KWin
class SoftwareVsyncMonitor; class SoftwareVsyncMonitor;
class VirtualBackend; class VirtualBackend;
class VirtualOutput : public AbstractWaylandOutput class VirtualOutput : public AbstractOutput
{ {
Q_OBJECT Q_OBJECT

View file

@ -44,7 +44,7 @@ namespace KWin
namespace Wayland namespace Wayland
{ {
static QVector<EGLint> regionToRects(const QRegion &region, AbstractWaylandOutput *output) static QVector<EGLint> regionToRects(const QRegion &region, AbstractOutput *output)
{ {
const int height = output->modeSize().height(); const int height = output->modeSize().height();
const QMatrix4x4 matrix = WaylandOutput::logicalToNativeMatrix(output->rect(), const QMatrix4x4 matrix = WaylandOutput::logicalToNativeMatrix(output->rect(),

View file

@ -25,7 +25,7 @@ using namespace KWayland::Client;
static const int s_refreshRate = 60000; // TODO: can we get refresh rate data from Wayland host? static const int s_refreshRate = 60000; // TODO: can we get refresh rate data from Wayland host?
WaylandOutput::WaylandOutput(Surface *surface, WaylandBackend *backend) WaylandOutput::WaylandOutput(Surface *surface, WaylandBackend *backend)
: AbstractWaylandOutput(backend) : AbstractOutput(backend)
, m_renderLoop(new RenderLoop(this)) , m_renderLoop(new RenderLoop(this))
, m_surface(surface) , m_surface(surface)
, m_backend(backend) , m_backend(backend)
@ -102,7 +102,7 @@ void WaylandOutput::updateEnablement(bool enable)
setDpmsMode(enable ? DpmsMode::On : DpmsMode::Off); setDpmsMode(enable ? DpmsMode::On : DpmsMode::Off);
} }
void WaylandOutput::setDpmsMode(KWin::AbstractWaylandOutput::DpmsMode mode) void WaylandOutput::setDpmsMode(DpmsMode mode)
{ {
if (mode == DpmsMode::Off) { if (mode == DpmsMode::Off) {
if (!m_turnOffTimer.isActive()) { if (!m_turnOffTimer.isActive()) {

View file

@ -9,11 +9,12 @@
#ifndef KWIN_WAYLAND_OUTPUT_H #ifndef KWIN_WAYLAND_OUTPUT_H
#define KWIN_WAYLAND_OUTPUT_H #define KWIN_WAYLAND_OUTPUT_H
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include <KWayland/Client/xdgshell.h> #include <KWayland/Client/xdgshell.h>
#include <QObject> #include <QObject>
#include <QTimer>
namespace KWayland namespace KWayland
{ {
@ -35,7 +36,7 @@ namespace Wayland
{ {
class WaylandBackend; class WaylandBackend;
class WaylandOutput : public AbstractWaylandOutput class WaylandOutput : public AbstractOutput
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -80,7 +81,7 @@ public:
void updateEnablement(bool enable) override; void updateEnablement(bool enable) override;
void updateTransform(Transform transform) override; void updateTransform(Transform transform) override;
void setDpmsMode(KWin::AbstractWaylandOutput::DpmsMode mode) override; void setDpmsMode(DpmsMode mode) override;
Q_SIGNALS: Q_SIGNALS:
void sizeChanged(const QSize &size); void sizeChanged(const QSize &size);

View file

@ -14,13 +14,8 @@ namespace KWin
X11Output::X11Output(const QString &name, QObject *parent) X11Output::X11Output(const QString &name, QObject *parent)
: AbstractOutput(parent) : AbstractOutput(parent)
, m_name(name)
{ {
} setName(name);
QString X11Output::name() const
{
return m_name;
} }
RenderLoop *X11Output::renderLoop() const RenderLoop *X11Output::renderLoop() const
@ -43,29 +38,6 @@ void X11Output::setXineramaNumber(int number)
m_xineramaNumber = number; m_xineramaNumber = number;
} }
QRect X11Output::geometry() const
{
return m_geometry;
}
void X11Output::setGeometry(QRect set)
{
if (m_geometry != set) {
m_geometry = set;
Q_EMIT geometryChanged();
}
}
int X11Output::refreshRate() const
{
return m_refreshRate;
}
void X11Output::setRefreshRate(int set)
{
m_refreshRate = set;
}
int X11Output::gammaRampSize() const int X11Output::gammaRampSize() const
{ {
return m_gammaRampSize; return m_gammaRampSize;
@ -93,24 +65,19 @@ void X11Output::setGammaRampSize(int size)
m_gammaRampSize = size; m_gammaRampSize = size;
} }
QSize X11Output::physicalSize() const
{
return m_physicalSize;
}
void X11Output::setPhysicalSize(const QSize &size)
{
m_physicalSize = size;
}
QSize X11Output::pixelSize() const
{
return geometry().size();
}
bool X11Output::usesSoftwareCursor() const bool X11Output::usesSoftwareCursor() const
{ {
return false; return false;
} }
void X11Output::setMode(const QSize &size, int refreshRate)
{
setCurrentModeInternal(size, refreshRate);
}
void X11Output::setPhysicalSize(const QSize &size)
{
setPhysicalSizeInternal(size);
}
} }

View file

@ -30,7 +30,7 @@ class KWIN_EXPORT X11Output : public AbstractOutput
public: public:
explicit X11Output(const QString &name, QObject *parent = nullptr); explicit X11Output(const QString &name, QObject *parent = nullptr);
QString name() const override; bool usesSoftwareCursor() const override;
RenderLoop *renderLoop() const override; RenderLoop *renderLoop() const override;
void setRenderLoop(RenderLoop *loop); void setRenderLoop(RenderLoop *loop);
@ -38,20 +38,11 @@ public:
int xineramaNumber() const; int xineramaNumber() const;
void setXineramaNumber(int number); void setXineramaNumber(int number);
QRect geometry() const override;
void setGeometry(QRect set);
int refreshRate() const override;
void setRefreshRate(int set);
int gammaRampSize() const override; int gammaRampSize() const override;
bool setGammaRamp(const GammaRamp &gamma) override; bool setGammaRamp(const GammaRamp &gamma) override;
QSize physicalSize() const override;
void setPhysicalSize(const QSize &size); void setPhysicalSize(const QSize &size);
void setMode(const QSize &size, int refreshRate);
QSize pixelSize() const override;
bool usesSoftwareCursor() const override;
private: private:
void setCrtc(xcb_randr_crtc_t crtc); void setCrtc(xcb_randr_crtc_t crtc);
@ -59,11 +50,7 @@ private:
RenderLoop *m_loop = nullptr; RenderLoop *m_loop = nullptr;
xcb_randr_crtc_t m_crtc = XCB_NONE; xcb_randr_crtc_t m_crtc = XCB_NONE;
QString m_name;
QRect m_geometry;
QSize m_physicalSize;
int m_gammaRampSize; int m_gammaRampSize;
int m_refreshRate;
int m_xineramaNumber = 0; int m_xineramaNumber = 0;
friend class X11StandalonePlatform; friend class X11StandalonePlatform;

View file

@ -543,8 +543,8 @@ void X11StandalonePlatform::doUpdateOutputs()
output->setRenderLoop(m_renderLoop); output->setRenderLoop(m_renderLoop);
output->setCrtc(crtcs[i]); output->setCrtc(crtcs[i]);
output->setGammaRampSize(gamma.isNull() ? 0 : gamma->size); output->setGammaRampSize(gamma.isNull() ? 0 : gamma->size);
output->setGeometry(geometry); output->setMode(geometry.size(), refreshRate * 1000);
output->setRefreshRate(refreshRate * 1000); output->moveTo(geometry.topLeft());
output->setXineramaNumber(i); output->setXineramaNumber(i);
QSize physicalSize(outputInfo->mm_width, outputInfo->mm_height); QSize physicalSize(outputInfo->mm_width, outputInfo->mm_height);

View file

@ -14,6 +14,26 @@ X11PlaceholderOutput::X11PlaceholderOutput(RenderLoop *loop, QObject *parent)
: AbstractOutput(parent) : AbstractOutput(parent)
, m_loop(loop) , m_loop(loop)
{ {
QSize pixelSize;
xcb_screen_t *screen = kwinApp()->x11DefaultScreen();
if (screen) {
pixelSize = QSize(screen->width_in_pixels, screen->height_in_pixels);
}
const Mode mode{
.size = pixelSize,
.refreshRate = 60000,
.flags = ModeFlag::Current,
.id = 0,
};
const QByteArray model = QByteArrayLiteral("kwin");
const QByteArray manufacturer = QByteArrayLiteral("xorg");
const QByteArray eisaId;
const QByteArray serial;
initialize(model, manufacturer, eisaId, serial, pixelSize, {mode}, QByteArray());
setName(QStringLiteral("Placeholder-0"));
} }
RenderLoop *X11PlaceholderOutput::renderLoop() const RenderLoop *X11PlaceholderOutput::renderLoop() const
@ -21,28 +41,4 @@ RenderLoop *X11PlaceholderOutput::renderLoop() const
return m_loop; return m_loop;
} }
QString X11PlaceholderOutput::name() const
{
return QStringLiteral("Placeholder-0");
}
QRect X11PlaceholderOutput::geometry() const
{
xcb_screen_t *screen = kwinApp()->x11DefaultScreen();
if (screen) {
return QRect(0, 0, screen->width_in_pixels, screen->height_in_pixels);
}
return QRect();
}
int X11PlaceholderOutput::refreshRate() const
{
return 60000;
}
QSize X11PlaceholderOutput::pixelSize() const
{
return geometry().size();
}
} // namespace KWin } // namespace KWin

View file

@ -19,10 +19,6 @@ public:
explicit X11PlaceholderOutput(RenderLoop *loop, QObject *parent = nullptr); explicit X11PlaceholderOutput(RenderLoop *loop, QObject *parent = nullptr);
RenderLoop *renderLoop() const override; RenderLoop *renderLoop() const override;
QString name() const override;
QRect geometry() const override;
int refreshRate() const override;
QSize pixelSize() const override;
private: private:
RenderLoop *m_loop; RenderLoop *m_loop;

View file

@ -26,7 +26,7 @@ namespace KWin
{ {
X11WindowedOutput::X11WindowedOutput(X11WindowedBackend *backend) X11WindowedOutput::X11WindowedOutput(X11WindowedBackend *backend)
: AbstractWaylandOutput(backend) : AbstractOutput(backend)
, m_renderLoop(new RenderLoop(this)) , m_renderLoop(new RenderLoop(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create(this)) , m_vsyncMonitor(SoftwareVsyncMonitor::create(this))
, m_backend(backend) , m_backend(backend)

View file

@ -9,7 +9,7 @@
#ifndef KWIN_X11WINDOWED_OUTPUT_H #ifndef KWIN_X11WINDOWED_OUTPUT_H
#define KWIN_X11WINDOWED_OUTPUT_H #define KWIN_X11WINDOWED_OUTPUT_H
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include <kwin_export.h> #include <kwin_export.h>
#include <QObject> #include <QObject>
@ -29,7 +29,7 @@ class X11WindowedBackend;
/** /**
* Wayland outputs in a nested X11 setup * Wayland outputs in a nested X11 setup
*/ */
class KWIN_EXPORT X11WindowedOutput : public AbstractWaylandOutput class KWIN_EXPORT X11WindowedOutput : public AbstractOutput
{ {
Q_OBJECT Q_OBJECT
public: public:

View file

@ -7,7 +7,7 @@
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
*/ */
#include "dpmsinputeventfilter.h" #include "dpmsinputeventfilter.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "main.h" #include "main.h"
#include "platform.h" #include "platform.h"
#include "wayland_server.h" #include "wayland_server.h"
@ -107,9 +107,8 @@ bool DpmsInputEventFilter::touchMotion(qint32 id, const QPointF &pos, quint32 ti
void DpmsInputEventFilter::notify() void DpmsInputEventFilter::notify()
{ {
const QVector<AbstractOutput *> enabledOutputs = kwinApp()->platform()->enabledOutputs(); const QVector<AbstractOutput *> enabledOutputs = kwinApp()->platform()->enabledOutputs();
for (auto it = enabledOutputs.constBegin(), end = enabledOutputs.constEnd(); it != end; it++) { for (AbstractOutput *output : enabledOutputs) {
auto waylandOutput = static_cast<AbstractWaylandOutput *>(*it); output->setDpmsMode(AbstractOutput::DpmsMode::On);
waylandOutput->setDpmsMode(AbstractWaylandOutput::DpmsMode::On);
} }
} }

View file

@ -8,7 +8,7 @@
*/ */
#include "inputpanelv1client.h" #include "inputpanelv1client.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "deleted.h" #include "deleted.h"
#include "inputmethod.h" #include "inputmethod.h"
#include "platform.h" #include "platform.h"
@ -166,13 +166,13 @@ QRect InputPanelV1Client::inputGeometry() const
void InputPanelV1Client::setOutput(OutputInterface *outputIface) void InputPanelV1Client::setOutput(OutputInterface *outputIface)
{ {
if (m_output) { if (m_output) {
disconnect(m_output, &AbstractWaylandOutput::geometryChanged, this, &InputPanelV1Client::reposition); disconnect(m_output, &AbstractOutput::geometryChanged, this, &InputPanelV1Client::reposition);
} }
m_output = waylandServer()->findOutput(outputIface); m_output = waylandServer()->findOutput(outputIface);
if (m_output) { if (m_output) {
connect(m_output, &AbstractWaylandOutput::geometryChanged, this, &InputPanelV1Client::reposition); connect(m_output, &AbstractOutput::geometryChanged, this, &InputPanelV1Client::reposition);
} }
} }

View file

@ -15,7 +15,7 @@
namespace KWin namespace KWin
{ {
class AbstractWaylandOutput; class AbstractOutput;
class InputPanelV1Client : public WaylandClient class InputPanelV1Client : public WaylandClient
{ {
@ -87,7 +87,7 @@ private:
void reposition(); void reposition();
void setOutput(KWaylandServer::OutputInterface *output); void setOutput(KWaylandServer::OutputInterface *output);
QPointer<AbstractWaylandOutput> m_output; QPointer<AbstractOutput> m_output;
Mode m_mode = Toplevel; Mode m_mode = Toplevel;
const QPointer<KWaylandServer::InputPanelSurfaceV1Interface> m_panelSurface; const QPointer<KWaylandServer::InputPanelSurfaceV1Interface> m_panelSurface;
}; };

View file

@ -5,7 +5,7 @@
*/ */
#include "layershellv1integration.h" #include "layershellv1integration.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "layershellv1client.h" #include "layershellv1client.h"
#include "platform.h" #include "platform.h"
#include "screens.h" #include "screens.h"

View file

@ -102,7 +102,7 @@ void Platform::requestOutputsChange(KWaylandServer::OutputConfigurationV2Interfa
const auto changes = config->changes(); const auto changes = config->changes();
for (auto it = changes.begin(); it != changes.end(); it++) { for (auto it = changes.begin(); it != changes.end(); it++) {
const KWaylandServer::OutputChangeSetV2 *changeset = it.value(); const KWaylandServer::OutputChangeSetV2 *changeset = it.value();
auto output = qobject_cast<AbstractWaylandOutput *>(findOutput(it.key()->uuid())); auto output = findOutput(it.key()->uuid());
if (!output) { if (!output) {
qCWarning(KWIN_CORE) << "Could NOT find output matching " << it.key()->uuid(); qCWarning(KWIN_CORE) << "Could NOT find output matching " << it.key()->uuid();
continue; continue;
@ -113,20 +113,15 @@ void Platform::requestOutputsChange(KWaylandServer::OutputConfigurationV2Interfa
props->scale = changeset->scale(); props->scale = changeset->scale();
props->modeSize = changeset->size(); props->modeSize = changeset->size();
props->refreshRate = changeset->refreshRate(); props->refreshRate = changeset->refreshRate();
props->transform = static_cast<AbstractWaylandOutput::Transform>(changeset->transform()); props->transform = static_cast<AbstractOutput::Transform>(changeset->transform());
props->overscan = changeset->overscan(); props->overscan = changeset->overscan();
props->rgbRange = static_cast<AbstractWaylandOutput::RgbRange>(changeset->rgbRange()); props->rgbRange = static_cast<AbstractOutput::RgbRange>(changeset->rgbRange());
props->vrrPolicy = static_cast<RenderLoop::VrrPolicy>(changeset->vrrPolicy()); props->vrrPolicy = static_cast<RenderLoop::VrrPolicy>(changeset->vrrPolicy());
} }
const auto allOutputs = outputs(); const auto allOutputs = outputs();
bool allDisabled = !std::any_of(allOutputs.begin(), allOutputs.end(), [&cfg](const auto &output) { bool allDisabled = !std::any_of(allOutputs.begin(), allOutputs.end(), [&cfg](const auto &output) {
auto o = qobject_cast<AbstractWaylandOutput *>(output); return cfg.changeSet(output)->enabled;
if (!o) {
qCWarning(KWIN_CORE) << "Platform::requestOutputsChange should only be called for Wayland platforms!";
return false;
}
return cfg.changeSet(o)->enabled;
}); });
if (allDisabled) { if (allDisabled) {
qCWarning(KWIN_CORE) << "Disabling all outputs through configuration changes is not allowed"; qCWarning(KWIN_CORE) << "Disabling all outputs through configuration changes is not allowed";
@ -159,17 +154,17 @@ bool Platform::applyOutputChanges(const WaylandOutputConfig &config)
QVector<AbstractOutput *> toBeEnabledOutputs; QVector<AbstractOutput *> toBeEnabledOutputs;
QVector<AbstractOutput *> toBeDisabledOutputs; QVector<AbstractOutput *> toBeDisabledOutputs;
for (const auto &output : availableOutputs) { for (const auto &output : availableOutputs) {
if (config.constChangeSet(qobject_cast<AbstractWaylandOutput *>(output))->enabled) { if (config.constChangeSet(output)->enabled) {
toBeEnabledOutputs << output; toBeEnabledOutputs << output;
} else { } else {
toBeDisabledOutputs << output; toBeDisabledOutputs << output;
} }
} }
for (const auto &output : toBeEnabledOutputs) { for (const auto &output : toBeEnabledOutputs) {
static_cast<AbstractWaylandOutput *>(output)->applyChanges(config); output->applyChanges(config);
} }
for (const auto &output : toBeDisabledOutputs) { for (const auto &output : toBeDisabledOutputs) {
static_cast<AbstractWaylandOutput *>(output)->applyChanges(config); output->applyChanges(config);
} }
return true; return true;
} }

View file

@ -7,11 +7,12 @@
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
*/ */
#include "abstract_egl_backend.h" #include "abstract_egl_backend.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "composite.h" #include "composite.h"
#include "egl_dmabuf.h" #include "egl_dmabuf.h"
#include "options.h" #include "options.h"
#include "platform.h" #include "platform.h"
#include "utils/common.h"
#include "utils/egl_context_attribute_builder.h" #include "utils/egl_context_attribute_builder.h"
#include "wayland_server.h" #include "wayland_server.h"
#include <KWaylandServer/display.h> #include <KWaylandServer/display.h>

View file

@ -7,7 +7,7 @@
#include "regionscreencastsource.h" #include "regionscreencastsource.h"
#include "screencastutils.h" #include "screencastutils.h"
#include <abstract_wayland_output.h> #include <abstract_output.h>
#include <composite.h> #include <composite.h>
#include <kwingltexture.h> #include <kwingltexture.h>
#include <kwinglutils.h> #include <kwinglutils.h>
@ -38,7 +38,7 @@ bool RegionScreenCastSource::hasAlphaChannel() const
return true; return true;
} }
void RegionScreenCastSource::updateOutput(AbstractWaylandOutput *output) void RegionScreenCastSource::updateOutput(AbstractOutput *output)
{ {
m_last = output->renderLoop()->lastPresentationTimestamp(); m_last = output->renderLoop()->lastPresentationTimestamp();
@ -80,9 +80,8 @@ void RegionScreenCastSource::render(GLFramebuffer *target)
m_target.reset(new GLFramebuffer(m_renderedTexture.data())); m_target.reset(new GLFramebuffer(m_renderedTexture.data()));
const auto allOutputs = kwinApp()->platform()->enabledOutputs(); const auto allOutputs = kwinApp()->platform()->enabledOutputs();
for (auto output : allOutputs) { for (auto output : allOutputs) {
AbstractWaylandOutput *streamOutput = qobject_cast<AbstractWaylandOutput *>(output); if (output->geometry().intersects(m_region)) {
if (streamOutput->geometry().intersects(m_region)) { updateOutput(output);
updateOutput(streamOutput);
} }
} }
} }

View file

@ -14,7 +14,7 @@
namespace KWin namespace KWin
{ {
class AbstractWaylandOutput; class AbstractOutput;
class RegionScreenCastSource : public ScreenCastSource class RegionScreenCastSource : public ScreenCastSource
{ {
@ -34,7 +34,7 @@ public:
{ {
return m_region; return m_region;
} }
void updateOutput(AbstractWaylandOutput *output); void updateOutput(AbstractOutput *output);
private: private:
const QRect m_region; const QRect m_region;

View file

@ -8,7 +8,7 @@
#include "screencastmanager.h" #include "screencastmanager.h"
#include "abstract_client.h" #include "abstract_client.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "composite.h" #include "composite.h"
#include "deleted.h" #include "deleted.h"
#include "effects.h" #include "effects.h"
@ -107,7 +107,7 @@ void ScreencastManager::streamVirtualOutput(KWaylandServer::ScreencastStreamV1In
double scale, double scale,
KWaylandServer::ScreencastV1Interface::CursorMode mode) KWaylandServer::ScreencastV1Interface::CursorMode mode)
{ {
auto output = qobject_cast<AbstractWaylandOutput *>(kwinApp()->platform()->createVirtualOutput(name, size, scale)); auto output = kwinApp()->platform()->createVirtualOutput(name, size, scale);
streamOutput(stream, output, mode); streamOutput(stream, output, mode);
connect(stream, &KWaylandServer::ScreencastStreamV1Interface::finished, output, [output] { connect(stream, &KWaylandServer::ScreencastStreamV1Interface::finished, output, [output] {
kwinApp()->platform()->removeVirtualOutput(output); kwinApp()->platform()->removeVirtualOutput(output);
@ -122,7 +122,7 @@ void ScreencastManager::streamWaylandOutput(KWaylandServer::ScreencastStreamV1In
} }
void ScreencastManager::streamOutput(KWaylandServer::ScreencastStreamV1Interface *waylandStream, void ScreencastManager::streamOutput(KWaylandServer::ScreencastStreamV1Interface *waylandStream,
AbstractWaylandOutput *streamOutput, AbstractOutput *streamOutput,
KWaylandServer::ScreencastV1Interface::CursorMode mode) KWaylandServer::ScreencastV1Interface::CursorMode mode)
{ {
if (!streamOutput) { if (!streamOutput) {
@ -144,7 +144,7 @@ void ScreencastManager::streamOutput(KWaylandServer::ScreencastStreamV1Interface
}; };
connect(stream, &ScreenCastStream::startStreaming, waylandStream, [streamOutput, stream, bufferToStream] { connect(stream, &ScreenCastStream::startStreaming, waylandStream, [streamOutput, stream, bufferToStream] {
Compositor::self()->scene()->addRepaint(streamOutput->geometry()); Compositor::self()->scene()->addRepaint(streamOutput->geometry());
connect(streamOutput, &AbstractWaylandOutput::outputChange, stream, bufferToStream); connect(streamOutput, &AbstractOutput::outputChange, stream, bufferToStream);
}); });
integrateStreams(waylandStream, stream); integrateStreams(waylandStream, stream);
} }
@ -171,19 +171,18 @@ void ScreencastManager::streamRegion(KWaylandServer::ScreencastStreamV1Interface
const auto allOutputs = kwinApp()->platform()->enabledOutputs(); const auto allOutputs = kwinApp()->platform()->enabledOutputs();
for (auto output : allOutputs) { for (auto output : allOutputs) {
AbstractWaylandOutput *streamOutput = qobject_cast<AbstractWaylandOutput *>(output); if (output->geometry().intersects(geometry)) {
if (streamOutput->geometry().intersects(geometry)) { auto bufferToStream = [output, stream, source](const QRegion &damagedRegion) {
auto bufferToStream = [streamOutput, stream, source](const QRegion &damagedRegion) {
if (damagedRegion.isEmpty()) { if (damagedRegion.isEmpty()) {
return; return;
} }
const QRect streamRegion = source->region(); const QRect streamRegion = source->region();
const QRegion region = streamOutput->pixelSize() != streamOutput->modeSize() ? streamOutput->geometry() : damagedRegion; const QRegion region = output->pixelSize() != output->modeSize() ? output->geometry() : damagedRegion;
source->updateOutput(streamOutput); source->updateOutput(output);
stream->recordFrame(region.translated(-streamRegion.topLeft()).intersected(streamRegion)); stream->recordFrame(region.translated(-streamRegion.topLeft()).intersected(streamRegion));
}; };
connect(streamOutput, &AbstractWaylandOutput::outputChange, stream, bufferToStream); connect(output, &AbstractOutput::outputChange, stream, bufferToStream);
} }
} }
}); });

View file

@ -14,7 +14,7 @@
namespace KWin namespace KWin
{ {
class AbstractWaylandOutput; class AbstractOutput;
class ScreenCastStream; class ScreenCastStream;
class ScreencastManager : public Plugin class ScreencastManager : public Plugin
@ -30,7 +30,7 @@ private:
KWaylandServer::OutputInterface *output, KWaylandServer::OutputInterface *output,
KWaylandServer::ScreencastV1Interface::CursorMode mode); KWaylandServer::ScreencastV1Interface::CursorMode mode);
void void
streamOutput(KWaylandServer::ScreencastStreamV1Interface *stream, AbstractWaylandOutput *output, KWaylandServer::ScreencastV1Interface::CursorMode mode); streamOutput(KWaylandServer::ScreencastStreamV1Interface *stream, AbstractOutput *output, KWaylandServer::ScreencastV1Interface::CursorMode mode);
void streamVirtualOutput(KWaylandServer::ScreencastStreamV1Interface *stream, void streamVirtualOutput(KWaylandServer::ScreencastStreamV1Interface *stream,
const QString &name, const QString &name,
const QSize &size, const QSize &size,

View file

@ -10,7 +10,7 @@
#include <config-kwin.h> #include <config-kwin.h>
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "composite.h" #include "composite.h"
#include "idle_inhibition.h" #include "idle_inhibition.h"
#include "inputpanelv1integration.h" #include "inputpanelv1integration.h"
@ -306,37 +306,33 @@ void WaylandServer::initPlatform()
void WaylandServer::handleOutputAdded(AbstractOutput *output) void WaylandServer::handleOutputAdded(AbstractOutput *output)
{ {
auto o = static_cast<AbstractWaylandOutput *>(output); if (!output->isPlaceholder()) {
if (!o->isPlaceholder()) { m_waylandOutputDevices.insert(output, new WaylandOutputDevice(output));
m_waylandOutputDevices.insert(o, new WaylandOutputDevice(o));
} }
} }
void WaylandServer::handleOutputRemoved(AbstractOutput *output) void WaylandServer::handleOutputRemoved(AbstractOutput *output)
{ {
auto o = static_cast<AbstractWaylandOutput *>(output); if (!output->isPlaceholder()) {
if (!o->isPlaceholder()) { delete m_waylandOutputDevices.take(output);
delete m_waylandOutputDevices.take(o);
} }
} }
void WaylandServer::handleOutputEnabled(AbstractOutput *output) void WaylandServer::handleOutputEnabled(AbstractOutput *output)
{ {
auto o = static_cast<AbstractWaylandOutput *>(output); if (!output->isPlaceholder()) {
if (!o->isPlaceholder()) { m_waylandOutputs.insert(output, new WaylandOutput(output));
m_waylandOutputs.insert(o, new WaylandOutput(o));
} }
} }
void WaylandServer::handleOutputDisabled(AbstractOutput *output) void WaylandServer::handleOutputDisabled(AbstractOutput *output)
{ {
auto o = static_cast<AbstractWaylandOutput *>(output); if (!output->isPlaceholder()) {
if (!o->isPlaceholder()) { delete m_waylandOutputs.take(output);
delete m_waylandOutputs.take(o);
} }
} }
AbstractWaylandOutput *WaylandServer::findOutput(KWaylandServer::OutputInterface *outputIface) const AbstractOutput *WaylandServer::findOutput(KWaylandServer::OutputInterface *outputIface) const
{ {
for (auto it = m_waylandOutputs.constBegin(); it != m_waylandOutputs.constEnd(); ++it) { for (auto it = m_waylandOutputs.constBegin(); it != m_waylandOutputs.constEnd(); ++it) {
if ((*it)->waylandOutput() == outputIface) { if ((*it)->waylandOutput() == outputIface) {

View file

@ -59,7 +59,6 @@ class Toplevel;
class XdgPopupClient; class XdgPopupClient;
class XdgSurfaceClient; class XdgSurfaceClient;
class XdgToplevelClient; class XdgToplevelClient;
class AbstractWaylandOutput;
class WaylandOutput; class WaylandOutput;
class WaylandOutputDevice; class WaylandOutputDevice;
@ -226,7 +225,7 @@ public:
m_linuxDmabufBuffers.remove(buffer); m_linuxDmabufBuffers.remove(buffer);
} }
AbstractWaylandOutput *findOutput(KWaylandServer::OutputInterface *output) const; AbstractOutput *findOutput(KWaylandServer::OutputInterface *output) const;
/** /**
* Returns the first socket name that can be used to connect to this server. * Returns the first socket name that can be used to connect to this server.
@ -291,8 +290,8 @@ private:
KWaylandServer::PrimaryOutputV1Interface *m_primary = nullptr; KWaylandServer::PrimaryOutputV1Interface *m_primary = nullptr;
QList<AbstractClient *> m_clients; QList<AbstractClient *> m_clients;
InitializationFlags m_initFlags; InitializationFlags m_initFlags;
QHash<AbstractWaylandOutput *, WaylandOutput *> m_waylandOutputs; QHash<AbstractOutput *, WaylandOutput *> m_waylandOutputs;
QHash<AbstractWaylandOutput *, WaylandOutputDevice *> m_waylandOutputDevices; QHash<AbstractOutput *, WaylandOutputDevice *> m_waylandOutputDevices;
KWIN_SINGLETON(WaylandServer) KWIN_SINGLETON(WaylandServer)
}; };

View file

@ -12,83 +12,83 @@
namespace KWin namespace KWin
{ {
static KWaylandServer::OutputInterface::Transform kwinTransformToOutputTransform(AbstractWaylandOutput::Transform transform) static KWaylandServer::OutputInterface::Transform kwinTransformToOutputTransform(AbstractOutput::Transform transform)
{ {
switch (transform) { switch (transform) {
case AbstractWaylandOutput::Transform::Normal: case AbstractOutput::Transform::Normal:
return KWaylandServer::OutputInterface::Transform::Normal; return KWaylandServer::OutputInterface::Transform::Normal;
case AbstractWaylandOutput::Transform::Rotated90: case AbstractOutput::Transform::Rotated90:
return KWaylandServer::OutputInterface::Transform::Rotated90; return KWaylandServer::OutputInterface::Transform::Rotated90;
case AbstractWaylandOutput::Transform::Rotated180: case AbstractOutput::Transform::Rotated180:
return KWaylandServer::OutputInterface::Transform::Rotated180; return KWaylandServer::OutputInterface::Transform::Rotated180;
case AbstractWaylandOutput::Transform::Rotated270: case AbstractOutput::Transform::Rotated270:
return KWaylandServer::OutputInterface::Transform::Rotated270; return KWaylandServer::OutputInterface::Transform::Rotated270;
case AbstractWaylandOutput::Transform::Flipped: case AbstractOutput::Transform::Flipped:
return KWaylandServer::OutputInterface::Transform::Flipped; return KWaylandServer::OutputInterface::Transform::Flipped;
case AbstractWaylandOutput::Transform::Flipped90: case AbstractOutput::Transform::Flipped90:
return KWaylandServer::OutputInterface::Transform::Flipped90; return KWaylandServer::OutputInterface::Transform::Flipped90;
case AbstractWaylandOutput::Transform::Flipped180: case AbstractOutput::Transform::Flipped180:
return KWaylandServer::OutputInterface::Transform::Flipped180; return KWaylandServer::OutputInterface::Transform::Flipped180;
case AbstractWaylandOutput::Transform::Flipped270: case AbstractOutput::Transform::Flipped270:
return KWaylandServer::OutputInterface::Transform::Flipped270; return KWaylandServer::OutputInterface::Transform::Flipped270;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
static KWaylandServer::OutputInterface::SubPixel kwinSubPixelToOutputSubPixel(AbstractWaylandOutput::SubPixel subPixel) static KWaylandServer::OutputInterface::SubPixel kwinSubPixelToOutputSubPixel(AbstractOutput::SubPixel subPixel)
{ {
switch (subPixel) { switch (subPixel) {
case AbstractWaylandOutput::SubPixel::Unknown: case AbstractOutput::SubPixel::Unknown:
return KWaylandServer::OutputInterface::SubPixel::Unknown; return KWaylandServer::OutputInterface::SubPixel::Unknown;
case AbstractWaylandOutput::SubPixel::None: case AbstractOutput::SubPixel::None:
return KWaylandServer::OutputInterface::SubPixel::None; return KWaylandServer::OutputInterface::SubPixel::None;
case AbstractWaylandOutput::SubPixel::Horizontal_RGB: case AbstractOutput::SubPixel::Horizontal_RGB:
return KWaylandServer::OutputInterface::SubPixel::HorizontalRGB; return KWaylandServer::OutputInterface::SubPixel::HorizontalRGB;
case AbstractWaylandOutput::SubPixel::Horizontal_BGR: case AbstractOutput::SubPixel::Horizontal_BGR:
return KWaylandServer::OutputInterface::SubPixel::HorizontalBGR; return KWaylandServer::OutputInterface::SubPixel::HorizontalBGR;
case AbstractWaylandOutput::SubPixel::Vertical_RGB: case AbstractOutput::SubPixel::Vertical_RGB:
return KWaylandServer::OutputInterface::SubPixel::VerticalRGB; return KWaylandServer::OutputInterface::SubPixel::VerticalRGB;
case AbstractWaylandOutput::SubPixel::Vertical_BGR: case AbstractOutput::SubPixel::Vertical_BGR:
return KWaylandServer::OutputInterface::SubPixel::VerticalBGR; return KWaylandServer::OutputInterface::SubPixel::VerticalBGR;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
static KWaylandServer::OutputInterface::DpmsMode kwinDpmsModeToOutputDpmsMode(AbstractWaylandOutput::DpmsMode dpmsMode) static KWaylandServer::OutputInterface::DpmsMode kwinDpmsModeToOutputDpmsMode(AbstractOutput::DpmsMode dpmsMode)
{ {
switch (dpmsMode) { switch (dpmsMode) {
case AbstractWaylandOutput::DpmsMode::Off: case AbstractOutput::DpmsMode::Off:
return KWaylandServer::OutputInterface::DpmsMode::Off; return KWaylandServer::OutputInterface::DpmsMode::Off;
case AbstractWaylandOutput::DpmsMode::On: case AbstractOutput::DpmsMode::On:
return KWaylandServer::OutputInterface::DpmsMode::On; return KWaylandServer::OutputInterface::DpmsMode::On;
case AbstractWaylandOutput::DpmsMode::Standby: case AbstractOutput::DpmsMode::Standby:
return KWaylandServer::OutputInterface::DpmsMode::Standby; return KWaylandServer::OutputInterface::DpmsMode::Standby;
case AbstractWaylandOutput::DpmsMode::Suspend: case AbstractOutput::DpmsMode::Suspend:
return KWaylandServer::OutputInterface::DpmsMode::Suspend; return KWaylandServer::OutputInterface::DpmsMode::Suspend;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
static AbstractWaylandOutput::DpmsMode outputDpmsModeToKWinDpmsMode(KWaylandServer::OutputInterface::DpmsMode dpmsMode) static AbstractOutput::DpmsMode outputDpmsModeToKWinDpmsMode(KWaylandServer::OutputInterface::DpmsMode dpmsMode)
{ {
switch (dpmsMode) { switch (dpmsMode) {
case KWaylandServer::OutputInterface::DpmsMode::Off: case KWaylandServer::OutputInterface::DpmsMode::Off:
return AbstractWaylandOutput::DpmsMode::Off; return AbstractOutput::DpmsMode::Off;
case KWaylandServer::OutputInterface::DpmsMode::On: case KWaylandServer::OutputInterface::DpmsMode::On:
return AbstractWaylandOutput::DpmsMode::On; return AbstractOutput::DpmsMode::On;
case KWaylandServer::OutputInterface::DpmsMode::Standby: case KWaylandServer::OutputInterface::DpmsMode::Standby:
return AbstractWaylandOutput::DpmsMode::Standby; return AbstractOutput::DpmsMode::Standby;
case KWaylandServer::OutputInterface::DpmsMode::Suspend: case KWaylandServer::OutputInterface::DpmsMode::Suspend:
return AbstractWaylandOutput::DpmsMode::Suspend; return AbstractOutput::DpmsMode::Suspend;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
} }
} }
WaylandOutput::WaylandOutput(AbstractWaylandOutput *output, QObject *parent) WaylandOutput::WaylandOutput(AbstractOutput *output, QObject *parent)
: QObject(parent) : QObject(parent)
, m_platformOutput(output) , m_platformOutput(output)
, m_waylandOutput(new KWaylandServer::OutputInterface(waylandServer()->display())) , m_waylandOutput(new KWaylandServer::OutputInterface(waylandServer()->display()))
@ -101,7 +101,7 @@ WaylandOutput::WaylandOutput(AbstractWaylandOutput *output, QObject *parent)
m_waylandOutput->setModel(output->model()); m_waylandOutput->setModel(output->model());
m_waylandOutput->setPhysicalSize(output->physicalSize()); m_waylandOutput->setPhysicalSize(output->physicalSize());
m_waylandOutput->setDpmsMode(kwinDpmsModeToOutputDpmsMode(output->dpmsMode())); m_waylandOutput->setDpmsMode(kwinDpmsModeToOutputDpmsMode(output->dpmsMode()));
m_waylandOutput->setDpmsSupported(output->capabilities() & AbstractWaylandOutput::Capability::Dpms); m_waylandOutput->setDpmsSupported(output->capabilities() & AbstractOutput::Capability::Dpms);
m_waylandOutput->setGlobalPosition(geometry.topLeft()); m_waylandOutput->setGlobalPosition(geometry.topLeft());
m_waylandOutput->setScale(std::ceil(output->scale())); m_waylandOutput->setScale(std::ceil(output->scale()));
m_waylandOutput->setMode(output->modeSize(), output->refreshRate()); m_waylandOutput->setMode(output->modeSize(), output->refreshRate());
@ -116,7 +116,7 @@ WaylandOutput::WaylandOutput(AbstractWaylandOutput *output, QObject *parent)
m_xdgOutputV1->done(); m_xdgOutputV1->done();
// The dpms functionality is not part of the wl_output interface, but org_kde_kwin_dpms. // The dpms functionality is not part of the wl_output interface, but org_kde_kwin_dpms.
connect(output, &AbstractWaylandOutput::dpmsModeChanged, connect(output, &AbstractOutput::dpmsModeChanged,
this, &WaylandOutput::handleDpmsModeChanged); this, &WaylandOutput::handleDpmsModeChanged);
connect(m_waylandOutput.data(), &KWaylandServer::OutputInterface::dpmsModeRequested, connect(m_waylandOutput.data(), &KWaylandServer::OutputInterface::dpmsModeRequested,
this, &WaylandOutput::handleDpmsModeRequested); this, &WaylandOutput::handleDpmsModeRequested);
@ -125,10 +125,10 @@ WaylandOutput::WaylandOutput(AbstractWaylandOutput *output, QObject *parent)
m_updateTimer.setSingleShot(true); m_updateTimer.setSingleShot(true);
connect(&m_updateTimer, &QTimer::timeout, this, &WaylandOutput::update); connect(&m_updateTimer, &QTimer::timeout, this, &WaylandOutput::update);
connect(output, &AbstractWaylandOutput::currentModeChanged, this, &WaylandOutput::scheduleUpdate); connect(output, &AbstractOutput::currentModeChanged, this, &WaylandOutput::scheduleUpdate);
connect(output, &AbstractWaylandOutput::geometryChanged, this, &WaylandOutput::scheduleUpdate); connect(output, &AbstractOutput::geometryChanged, this, &WaylandOutput::scheduleUpdate);
connect(output, &AbstractWaylandOutput::transformChanged, this, &WaylandOutput::scheduleUpdate); connect(output, &AbstractOutput::transformChanged, this, &WaylandOutput::scheduleUpdate);
connect(output, &AbstractWaylandOutput::scaleChanged, this, &WaylandOutput::scheduleUpdate); connect(output, &AbstractOutput::scaleChanged, this, &WaylandOutput::scheduleUpdate);
} }
KWaylandServer::OutputInterface *WaylandOutput::waylandOutput() const KWaylandServer::OutputInterface *WaylandOutput::waylandOutput() const

View file

@ -6,12 +6,14 @@
#pragma once #pragma once
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include <KWaylandServer/output_interface.h> #include <KWaylandServer/output_interface.h>
#include <KWaylandServer/utils.h> #include <KWaylandServer/utils.h>
#include <KWaylandServer/xdgoutput_v1_interface.h> #include <KWaylandServer/xdgoutput_v1_interface.h>
#include <QTimer>
namespace KWin namespace KWin
{ {
@ -20,7 +22,7 @@ class WaylandOutput : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit WaylandOutput(AbstractWaylandOutput *output, QObject *parent = nullptr); explicit WaylandOutput(AbstractOutput *output, QObject *parent = nullptr);
KWaylandServer::OutputInterface *waylandOutput() const; KWaylandServer::OutputInterface *waylandOutput() const;
@ -32,7 +34,7 @@ private Q_SLOTS:
void scheduleUpdate(); void scheduleUpdate();
private: private:
AbstractWaylandOutput *m_platformOutput; AbstractOutput *m_platformOutput;
QTimer m_updateTimer; QTimer m_updateTimer;
KWaylandServer::ScopedGlobalPointer<KWaylandServer::OutputInterface> m_waylandOutput; KWaylandServer::ScopedGlobalPointer<KWaylandServer::OutputInterface> m_waylandOutput;
KWaylandServer::XdgOutputV1Interface *m_xdgOutputV1; KWaylandServer::XdgOutputV1Interface *m_xdgOutputV1;

View file

@ -11,14 +11,14 @@
namespace KWin namespace KWin
{ {
QSharedPointer<OutputChangeSet> WaylandOutputConfig::changeSet(AbstractWaylandOutput *output) QSharedPointer<OutputChangeSet> WaylandOutputConfig::changeSet(AbstractOutput *output)
{ {
const auto ptr = constChangeSet(output); const auto ptr = constChangeSet(output);
m_properties[output] = ptr; m_properties[output] = ptr;
return ptr; return ptr;
} }
QSharedPointer<OutputChangeSet> WaylandOutputConfig::constChangeSet(AbstractWaylandOutput *output) const QSharedPointer<OutputChangeSet> WaylandOutputConfig::constChangeSet(AbstractOutput *output) const
{ {
if (!m_properties.contains(output)) { if (!m_properties.contains(output)) {
auto props = QSharedPointer<OutputChangeSet>::create(); auto props = QSharedPointer<OutputChangeSet>::create();

View file

@ -11,7 +11,7 @@
#include <QPoint> #include <QPoint>
#include <QSize> #include <QSize>
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include "kwin_export.h" #include "kwin_export.h"
namespace KWin namespace KWin
@ -25,20 +25,20 @@ public:
float scale; float scale;
QSize modeSize; QSize modeSize;
uint32_t refreshRate; uint32_t refreshRate;
AbstractWaylandOutput::Transform transform; AbstractOutput::Transform transform;
uint32_t overscan; uint32_t overscan;
AbstractWaylandOutput::RgbRange rgbRange; AbstractOutput::RgbRange rgbRange;
RenderLoop::VrrPolicy vrrPolicy; RenderLoop::VrrPolicy vrrPolicy;
}; };
class KWIN_EXPORT WaylandOutputConfig class KWIN_EXPORT WaylandOutputConfig
{ {
public: public:
QSharedPointer<OutputChangeSet> changeSet(AbstractWaylandOutput *output); QSharedPointer<OutputChangeSet> changeSet(AbstractOutput *output);
QSharedPointer<OutputChangeSet> constChangeSet(AbstractWaylandOutput *output) const; QSharedPointer<OutputChangeSet> constChangeSet(AbstractOutput *output) const;
private: private:
QMap<AbstractWaylandOutput *, QSharedPointer<OutputChangeSet>> m_properties; QMap<AbstractOutput *, QSharedPointer<OutputChangeSet>> m_properties;
}; };
} }

View file

@ -13,26 +13,26 @@ using namespace KWaylandServer;
namespace KWin namespace KWin
{ {
static KWaylandServer::OutputDeviceV2Interface::Transform kwinTransformToOutputDeviceTransform(AbstractWaylandOutput::Transform transform) static KWaylandServer::OutputDeviceV2Interface::Transform kwinTransformToOutputDeviceTransform(AbstractOutput::Transform transform)
{ {
return static_cast<KWaylandServer::OutputDeviceV2Interface::Transform>(transform); return static_cast<KWaylandServer::OutputDeviceV2Interface::Transform>(transform);
} }
static KWaylandServer::OutputDeviceV2Interface::SubPixel kwinSubPixelToOutputDeviceSubPixel(AbstractWaylandOutput::SubPixel subPixel) static KWaylandServer::OutputDeviceV2Interface::SubPixel kwinSubPixelToOutputDeviceSubPixel(AbstractOutput::SubPixel subPixel)
{ {
return static_cast<KWaylandServer::OutputDeviceV2Interface::SubPixel>(subPixel); return static_cast<KWaylandServer::OutputDeviceV2Interface::SubPixel>(subPixel);
} }
static KWaylandServer::OutputDeviceV2Interface::Capabilities kwinCapabilitiesToOutputDeviceCapabilities(AbstractWaylandOutput::Capabilities caps) static KWaylandServer::OutputDeviceV2Interface::Capabilities kwinCapabilitiesToOutputDeviceCapabilities(AbstractOutput::Capabilities caps)
{ {
KWaylandServer::OutputDeviceV2Interface::Capabilities ret; KWaylandServer::OutputDeviceV2Interface::Capabilities ret;
if (caps & AbstractWaylandOutput::Capability::Overscan) { if (caps & AbstractOutput::Capability::Overscan) {
ret |= KWaylandServer::OutputDeviceV2Interface::Capability::Overscan; ret |= KWaylandServer::OutputDeviceV2Interface::Capability::Overscan;
} }
if (caps & AbstractWaylandOutput::Capability::Vrr) { if (caps & AbstractOutput::Capability::Vrr) {
ret |= KWaylandServer::OutputDeviceV2Interface::Capability::Vrr; ret |= KWaylandServer::OutputDeviceV2Interface::Capability::Vrr;
} }
if (caps & AbstractWaylandOutput::Capability::RgbRange) { if (caps & AbstractOutput::Capability::RgbRange) {
ret |= KWaylandServer::OutputDeviceV2Interface::Capability::RgbRange; ret |= KWaylandServer::OutputDeviceV2Interface::Capability::RgbRange;
} }
return ret; return ret;
@ -43,12 +43,12 @@ static KWaylandServer::OutputDeviceV2Interface::VrrPolicy kwinVrrPolicyToOutputD
return static_cast<KWaylandServer::OutputDeviceV2Interface::VrrPolicy>(policy); return static_cast<KWaylandServer::OutputDeviceV2Interface::VrrPolicy>(policy);
} }
static KWaylandServer::OutputDeviceV2Interface::RgbRange kwinRgbRangeToOutputDeviceRgbRange(AbstractWaylandOutput::RgbRange range) static KWaylandServer::OutputDeviceV2Interface::RgbRange kwinRgbRangeToOutputDeviceRgbRange(AbstractOutput::RgbRange range)
{ {
return static_cast<KWaylandServer::OutputDeviceV2Interface::RgbRange>(range); return static_cast<KWaylandServer::OutputDeviceV2Interface::RgbRange>(range);
} }
WaylandOutputDevice::WaylandOutputDevice(AbstractWaylandOutput *output, QObject *parent) WaylandOutputDevice::WaylandOutputDevice(AbstractOutput *output, QObject *parent)
: QObject(parent) : QObject(parent)
, m_platformOutput(output) , m_platformOutput(output)
, m_outputDeviceV2(new KWaylandServer::OutputDeviceV2Interface(waylandServer()->display())) , m_outputDeviceV2(new KWaylandServer::OutputDeviceV2Interface(waylandServer()->display()))
@ -72,41 +72,41 @@ WaylandOutputDevice::WaylandOutputDevice(AbstractWaylandOutput *output, QObject
updateModes(output); updateModes(output);
connect(output, &AbstractWaylandOutput::geometryChanged, connect(output, &AbstractOutput::geometryChanged,
this, &WaylandOutputDevice::handleGeometryChanged); this, &WaylandOutputDevice::handleGeometryChanged);
connect(output, &AbstractWaylandOutput::scaleChanged, connect(output, &AbstractOutput::scaleChanged,
this, &WaylandOutputDevice::handleScaleChanged); this, &WaylandOutputDevice::handleScaleChanged);
connect(output, &AbstractWaylandOutput::enabledChanged, connect(output, &AbstractOutput::enabledChanged,
this, &WaylandOutputDevice::handleEnabledChanged); this, &WaylandOutputDevice::handleEnabledChanged);
connect(output, &AbstractWaylandOutput::transformChanged, connect(output, &AbstractOutput::transformChanged,
this, &WaylandOutputDevice::handleTransformChanged); this, &WaylandOutputDevice::handleTransformChanged);
connect(output, &AbstractWaylandOutput::currentModeChanged, connect(output, &AbstractOutput::currentModeChanged,
this, &WaylandOutputDevice::handleCurrentModeChanged); this, &WaylandOutputDevice::handleCurrentModeChanged);
connect(output, &AbstractWaylandOutput::capabilitiesChanged, connect(output, &AbstractOutput::capabilitiesChanged,
this, &WaylandOutputDevice::handleCapabilitiesChanged); this, &WaylandOutputDevice::handleCapabilitiesChanged);
connect(output, &AbstractWaylandOutput::overscanChanged, connect(output, &AbstractOutput::overscanChanged,
this, &WaylandOutputDevice::handleOverscanChanged); this, &WaylandOutputDevice::handleOverscanChanged);
connect(output, &AbstractWaylandOutput::vrrPolicyChanged, connect(output, &AbstractOutput::vrrPolicyChanged,
this, &WaylandOutputDevice::handleVrrPolicyChanged); this, &WaylandOutputDevice::handleVrrPolicyChanged);
connect(output, &AbstractWaylandOutput::modesChanged, connect(output, &AbstractOutput::modesChanged,
this, &WaylandOutputDevice::handleModesChanged); this, &WaylandOutputDevice::handleModesChanged);
connect(output, &AbstractWaylandOutput::rgbRangeChanged, connect(output, &AbstractOutput::rgbRangeChanged,
this, &WaylandOutputDevice::handleRgbRangeChanged); this, &WaylandOutputDevice::handleRgbRangeChanged);
} }
void WaylandOutputDevice::updateModes(AbstractWaylandOutput *output) void WaylandOutputDevice::updateModes(AbstractOutput *output)
{ {
QList<OutputDeviceModeV2Interface *> deviceModes; QList<OutputDeviceModeV2Interface *> deviceModes;
const auto modes = output->modes(); const auto modes = output->modes();
deviceModes.reserve(modes.size()); deviceModes.reserve(modes.size());
for (const AbstractWaylandOutput::Mode &mode : modes) { for (const AbstractOutput::Mode &mode : modes) {
OutputDeviceModeV2Interface::ModeFlags flags; OutputDeviceModeV2Interface::ModeFlags flags;
if (mode.flags & AbstractWaylandOutput::ModeFlag::Current) { if (mode.flags & AbstractOutput::ModeFlag::Current) {
flags |= OutputDeviceModeV2Interface::ModeFlag::Current; flags |= OutputDeviceModeV2Interface::ModeFlag::Current;
} }
if (mode.flags & AbstractWaylandOutput::ModeFlag::Preferred) { if (mode.flags & AbstractOutput::ModeFlag::Preferred) {
flags |= OutputDeviceModeV2Interface::ModeFlag::Preferred; flags |= OutputDeviceModeV2Interface::ModeFlag::Preferred;
} }

View file

@ -7,7 +7,7 @@
#pragma once #pragma once
#include "abstract_wayland_output.h" #include "abstract_output.h"
#include <KWaylandServer/outputdevice_v2_interface.h> #include <KWaylandServer/outputdevice_v2_interface.h>
#include <KWaylandServer/utils.h> #include <KWaylandServer/utils.h>
@ -20,7 +20,7 @@ class WaylandOutputDevice : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit WaylandOutputDevice(AbstractWaylandOutput *output, QObject *parent = nullptr); explicit WaylandOutputDevice(AbstractOutput *output, QObject *parent = nullptr);
private Q_SLOTS: private Q_SLOTS:
void handleGeometryChanged(); void handleGeometryChanged();
@ -35,9 +35,9 @@ private Q_SLOTS:
void handleRgbRangeChanged(); void handleRgbRangeChanged();
private: private:
void updateModes(AbstractWaylandOutput *output); void updateModes(AbstractOutput *output);
AbstractWaylandOutput *m_platformOutput; AbstractOutput *m_platformOutput;
KWaylandServer::ScopedGlobalPointer<KWaylandServer::OutputDeviceV2Interface> m_outputDeviceV2; KWaylandServer::ScopedGlobalPointer<KWaylandServer::OutputDeviceV2Interface> m_outputDeviceV2;
}; };

View file

@ -13,7 +13,7 @@
// kwin libs // kwin libs
#include <kwinglplatform.h> #include <kwinglplatform.h>
// kwin // kwin
#include "abstract_wayland_output.h" #include "abstract_output.h"
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
#endif #endif
@ -1622,24 +1622,21 @@ QString Workspace::supportInformation() const
.arg(geo.height())); .arg(geo.height()));
support.append(QStringLiteral("Scale: %1\n").arg(output->scale())); support.append(QStringLiteral("Scale: %1\n").arg(output->scale()));
support.append(QStringLiteral("Refresh Rate: %1\n").arg(output->refreshRate())); support.append(QStringLiteral("Refresh Rate: %1\n").arg(output->refreshRate()));
const auto waylandOutput = qobject_cast<AbstractWaylandOutput *>(output); QString vrr = QStringLiteral("incapable");
if (waylandOutput) { if (output->capabilities() & AbstractOutput::Capability::Vrr) {
QString vrr = QStringLiteral("incapable"); switch (output->vrrPolicy()) {
if (waylandOutput->capabilities() & AbstractWaylandOutput::Capability::Vrr) { case RenderLoop::VrrPolicy::Never:
switch (waylandOutput->vrrPolicy()) { vrr = QStringLiteral("never");
case RenderLoop::VrrPolicy::Never: break;
vrr = QStringLiteral("never"); case RenderLoop::VrrPolicy::Always:
break; vrr = QStringLiteral("always");
case RenderLoop::VrrPolicy::Always: break;
vrr = QStringLiteral("always"); case RenderLoop::VrrPolicy::Automatic:
break; vrr = QStringLiteral("automatic");
case RenderLoop::VrrPolicy::Automatic: break;
vrr = QStringLiteral("automatic");
break;
}
} }
support.append(QStringLiteral("Adaptive Sync: %1\n").arg(vrr));
} }
support.append(QStringLiteral("Adaptive Sync: %1\n").arg(vrr));
} }
support.append(QStringLiteral("\nCompositing\n")); support.append(QStringLiteral("\nCompositing\n"));
support.append(QStringLiteral("===========\n")); support.append(QStringLiteral("===========\n"));

View file

@ -9,7 +9,7 @@
SPDX-License-Identifier: GPL-2.0-or-later SPDX-License-Identifier: GPL-2.0-or-later
*/ */
#include "xdgshellclient.h" #include "xdgshellclient.h"
#include "abstract_wayland_output.h" #include "abstract_output.h"
#if KWIN_BUILD_ACTIVITIES #if KWIN_BUILD_ACTIVITIES
#include "activities.h" #include "activities.h"
#endif #endif