diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -453,6 +453,7 @@ decorations/decorationrenderer.cpp decorations/decorations_logging.cpp platform.cpp + output.cpp shell_client.cpp wayland_server.cpp wayland_cursor_theme.cpp diff --git a/autotests/integration/screen_changes_test.cpp b/autotests/integration/screen_changes_test.cpp --- a/autotests/integration/screen_changes_test.cpp +++ b/autotests/integration/screen_changes_test.cpp @@ -125,15 +125,15 @@ QCOMPARE(outputRemovedSpy.count(), 1); // let's create the output objects to ensure they are correct - QScopedPointer o1(registry.createOutput(outputAnnouncedSpy.first().first().value(), outputAnnouncedSpy.first().last().value())); + QScopedPointer o1(registry.createOutput(outputAnnouncedSpy.first().first().value(), outputAnnouncedSpy.first().last().value())); QVERIFY(o1->isValid()); - QSignalSpy o1ChangedSpy(o1.data(), &Output::changed); + QSignalSpy o1ChangedSpy(o1.data(), &KWayland::Client::Output::changed); QVERIFY(o1ChangedSpy.isValid()); QVERIFY(o1ChangedSpy.wait()); QCOMPARE(o1->geometry(), geometries.at(0)); - QScopedPointer o2(registry.createOutput(outputAnnouncedSpy.last().first().value(), outputAnnouncedSpy.last().last().value())); + QScopedPointer o2(registry.createOutput(outputAnnouncedSpy.last().first().value(), outputAnnouncedSpy.last().last().value())); QVERIFY(o2->isValid()); - QSignalSpy o2ChangedSpy(o2.data(), &Output::changed); + QSignalSpy o2ChangedSpy(o2.data(), &KWayland::Client::Output::changed); QVERIFY(o2ChangedSpy.isValid()); QVERIFY(o2ChangedSpy.wait()); QCOMPARE(o2->geometry(), geometries.at(1)); @@ -143,9 +143,9 @@ outputRemovedSpy.clear(); screensChangedSpy.clear(); - QSignalSpy o1RemovedSpy(o1.data(), &Output::removed); + QSignalSpy o1RemovedSpy(o1.data(), &KWayland::Client::Output::removed); QVERIFY(o1RemovedSpy.isValid()); - QSignalSpy o2RemovedSpy(o2.data(), &Output::removed); + QSignalSpy o2RemovedSpy(o2.data(), &KWayland::Client::Output::removed); QVERIFY(o2RemovedSpy.isValid()); const QVector geometries2{QRect(0, 0, 1280, 1024)}; diff --git a/output.h b/output.h new file mode 100644 --- /dev/null +++ b/output.h @@ -0,0 +1,105 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright 2018 Roman Gilg + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef KWIN_OUTPUT_H +#define KWIN_OUTPUT_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace KWayland +{ +namespace Server +{ +class OutputInterface; +class OutputDeviceInterface; +class OutputChangeSet; +class OutputManagementInterface; +} +} + +namespace KWin +{ + +/** + * Generic output representation in a Wayland session + **/ +class KWIN_EXPORT Output : public QObject +{ + Q_OBJECT +public: + virtual ~Output() {} + + QString name() const; + bool isEnabled() const { + return !m_waylandOutput.isNull(); + } + + virtual QSize pixelSize() const = 0; + qreal scale() const { + return m_scale; + } + /* + * The geometry of this output in global compositor co-ordinates (i.e scaled) + */ + QRect geometry() const; + QSize physicalSize() const; + Qt::ScreenOrientation orientation() const { + return m_orientation; + } + + bool isInternal() const { + return m_internal; + } + + void setGlobalPos(const QPoint &pos); + void setScale(qreal scale); + + /** + * This sets the changes and tests them against the specific output + */ + void setChanges(KWayland::Server::OutputChangeSet *changeset); + virtual bool commitChanges() { return false; } + + const QPointer getWaylandInterface() const { + return m_waylandOutput; + } + +protected: + QPointer m_changeset; + QPointer m_waylandOutput; + QPointer m_waylandOutputDevice; + + QPoint m_globalPos; + qreal m_scale = 1; + QSize m_physicalSize; + Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; + bool m_internal = false; +}; + +} + +#endif // KWIN_OUTPUT_H diff --git a/output.cpp b/output.cpp new file mode 100644 --- /dev/null +++ b/output.cpp @@ -0,0 +1,82 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright 2018 Roman Gilg + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "output.h" + +// KWayland +#include +#include +#include +// KF5 +#include + +namespace KWin +{ + +QString Output::name() const +{ + if (!m_waylandOutput) { + return i18n("unknown"); + } + return QStringLiteral("%1 %2").arg(m_waylandOutput->manufacturer()).arg(m_waylandOutput->model()); +} + +QRect Output::geometry() const +{ + return QRect(m_globalPos, pixelSize() / scale()); +} + +QSize Output::physicalSize() const +{ + if (m_orientation == Qt::PortraitOrientation || m_orientation == Qt::InvertedPortraitOrientation) { + return QSize(m_physicalSize.height(), m_physicalSize.width()); + } + return m_physicalSize; +} + +void Output::setGlobalPos(const QPoint &pos) +{ + m_globalPos = pos; + if (m_waylandOutput) { + m_waylandOutput->setGlobalPosition(pos); + } + if (m_waylandOutputDevice) { + m_waylandOutputDevice->setGlobalPosition(pos); + } +} + +void Output::setScale(qreal scale) +{ + m_scale = scale; + if (m_waylandOutput) { + m_waylandOutput->setScale(scale); + } + if (m_waylandOutputDevice) { + m_waylandOutputDevice->setScale(scale); + } +} + +void Output::setChanges(KWayland::Server::OutputChangeSet *changes) +{ + m_changeset = changes; + qCDebug(KWIN_CORE) << "set changes in Output"; + commitChanges(); +} + +} diff --git a/platform.h b/platform.h --- a/platform.h +++ b/platform.h @@ -45,6 +45,7 @@ struct GammaRamp; } +class Output; class Edge; class Compositor; class OverlayWindow; @@ -411,6 +412,15 @@ return false; } + // outputs with connections (org_kde_kwin_outputdevice) + QVector outputs() const { + return m_outputs; + } + // actively compositing outputs (wl_output) + QVector enabledOutputs() const { + return m_enabledOutputs; + } + /* * A string of information to include in kwin debug output * It should not be translated. @@ -450,6 +460,7 @@ void initFailed(); void cursorChanged(); void readyChanged(bool); + /** * Emitted by backends using a one screen (nested window) approach and when the size of that changes. **/ @@ -500,6 +511,9 @@ **/ virtual void doShowCursor(); + QVector m_outputs; + QVector m_enabledOutputs; + private: void triggerCursorRepaint(); bool m_softWareCursor = false; diff --git a/platform.cpp b/platform.cpp --- a/platform.cpp +++ b/platform.cpp @@ -46,6 +46,7 @@ Platform::~Platform() { + qDeleteAll(m_outputs); if (m_eglDisplay != EGL_NO_DISPLAY) { eglTerminate(m_eglDisplay); } diff --git a/plugins/platforms/drm/drm_backend.h b/plugins/platforms/drm/drm_backend.h --- a/plugins/platforms/drm/drm_backend.h +++ b/plugins/platforms/drm/drm_backend.h @@ -93,12 +93,6 @@ int fd() const { return m_fd; } - QVector outputs() const { - return m_outputs; - } - QVector enabledOutputs() const { - return m_enabledOutputs; - } QVector planes() const { return m_planes; } @@ -173,10 +167,6 @@ QVector m_crtcs; // all connectors QVector m_connectors; - // active output pipelines (planes + crtc + encoder + connector) - QVector m_outputs; - // active and enabled pipelines (above + wl_output) - QVector m_enabledOutputs; bool m_deleteBufferAfterPageFlip; bool m_atomicModeSetting = false; diff --git a/plugins/platforms/drm/drm_backend.cpp b/plugins/platforms/drm/drm_backend.cpp --- a/plugins/platforms/drm/drm_backend.cpp +++ b/plugins/platforms/drm/drm_backend.cpp @@ -90,7 +90,10 @@ while (m_pageFlipsPending != 0) { QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); } + // we need to first remove all outputs qDeleteAll(m_outputs); + m_outputs.clear(); + qDeleteAll(m_planes); qDeleteAll(m_crtcs); qDeleteAll(m_connectors); @@ -130,7 +133,8 @@ { m_dpmsFilter.reset(); for (auto it = m_enabledOutputs.constBegin(), end = m_enabledOutputs.constEnd(); it != end; it++) { - (*it)->setDpms(DrmOutput::DpmsMode::On); + auto o = qobject_cast(*it); + o->setDpms(DrmOutput::DpmsMode::On); } } @@ -141,7 +145,8 @@ return; } for (auto it = m_enabledOutputs.constBegin(), end = m_enabledOutputs.constEnd(); it != end; it++) { - if (!(*it)->isDpmsEnabled()) { + auto o = qobject_cast(*it); + if (!o->isDpmsEnabled()) { // dpms still disabled, need to keep the filter return; } @@ -170,7 +175,7 @@ if (!usesSoftwareCursor()) { const QPoint cp = Cursor::pos() - softwareCursorHotspot(); for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { - DrmOutput *o = *it; + DrmOutput *o = qobject_cast(*it); // only relevant in atomic mode o->m_modesetRequested = true; o->pageFlipped(); // TODO: Do we really need this? @@ -198,7 +203,7 @@ } // hide cursor and disable for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { - DrmOutput *o = *it; + DrmOutput *o = qobject_cast(*it); o->hideCursor(); } m_active = false; @@ -373,7 +378,7 @@ return; } - QVector connectedOutputs; + QVector connectedOutputs; QVector pendingConnectors; // split up connected connectors in already or not yet assigned ones @@ -392,15 +397,15 @@ // check for outputs which got removed auto it = m_outputs.begin(); while (it != m_outputs.end()) { - if (connectedOutputs.contains(*it)) { + Output *o = *it; + if (connectedOutputs.contains(o)) { it++; continue; } - DrmOutput *removed = *it; it = m_outputs.erase(it); - m_enabledOutputs.removeOne(removed); - emit outputRemoved(removed); - delete removed; + m_enabledOutputs.removeOne(o); + emit outputRemoved(qobject_cast(o)); + delete o; } // now check new connections @@ -427,8 +432,8 @@ // check if crtc isn't used yet -- currently we don't allow multiple outputs on one crtc (cloned mode) auto it = std::find_if(connectedOutputs.constBegin(), connectedOutputs.constEnd(), - [crtc] (DrmOutput *o) { - return o->m_crtc == crtc; + [crtc] (Output *o) { + return qobject_cast(o)->m_crtc == crtc; } ); if (it != connectedOutputs.constEnd()) { @@ -476,7 +481,9 @@ } } } - std::sort(connectedOutputs.begin(), connectedOutputs.end(), [] (DrmOutput *a, DrmOutput *b) { return a->m_conn->id() < b->m_conn->id(); }); + std::sort(connectedOutputs.begin(), connectedOutputs.end(), [] (Output *a, Output *b) { + return qobject_cast(a)->m_conn->id() < qobject_cast(b)->m_conn->id(); + }); m_outputs = connectedOutputs; m_enabledOutputs = connectedOutputs; readOutputsConfiguration(); @@ -496,25 +503,27 @@ // default position goes from left to right QPoint pos(0, 0); for (auto it = m_outputs.begin(); it != m_outputs.end(); ++it) { - qCDebug(KWIN_DRM) << "Reading output configuration for [" << uuid << "] ["<< (*it)->uuid() << "]"; - const auto outputConfig = configGroup.group((*it)->uuid()); - (*it)->setGlobalPos(outputConfig.readEntry("Position", pos)); + auto o = qobject_cast(*it); + qCDebug(KWIN_DRM) << "Reading output configuration for [" << uuid << "] ["<< o->uuid() << "]"; + const auto outputConfig = configGroup.group(o->uuid()); + o->setGlobalPos(outputConfig.readEntry("Position", pos)); // TODO: add mode - (*it)->setScale(outputConfig.readEntry("Scale", 1.0)); - pos.setX(pos.x() + (*it)->geometry().width()); + o->setScale(outputConfig.readEntry("Scale", 1.0)); + pos.setX(pos.x() + o->geometry().width()); } } QByteArray DrmBackend::generateOutputConfigurationUuid() const { auto it = m_outputs.constBegin(); if (m_outputs.size() == 1) { // special case: one output - return (*it)->uuid(); + return qobject_cast(*it)->uuid(); } QCryptographicHash hash(QCryptographicHash::Md5); for (; it != m_outputs.constEnd(); ++it) { - hash.addData((*it)->uuid()); + auto o = qobject_cast(*it); + hash.addData(o->uuid()); } return hash.result().toHex().left(10); } @@ -574,22 +583,22 @@ DrmOutput *DrmBackend::findOutput(quint32 connector) { - auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [connector] (DrmOutput *o) { - return o->m_conn->id() == connector; + auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [connector] (Output *o) { + return qobject_cast(o)->m_conn->id() == connector; }); if (it != m_outputs.constEnd()) { - return *it; + return qobject_cast(*it); } return nullptr; } DrmOutput *DrmBackend::findOutput(const QByteArray &uuid) { - auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [uuid] (DrmOutput *o) { - return o->m_uuid == uuid; + auto it = std::find_if(m_outputs.constBegin(), m_outputs.constEnd(), [uuid] (Output *o) { + return qobject_cast(o)->m_uuid == uuid; }); if (it != m_outputs.constEnd()) { - return *it; + return qobject_cast(*it); } return nullptr; } @@ -623,10 +632,11 @@ return; } for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { + auto o = qobject_cast(*it); if (m_cursorEnabled) { - (*it)->showCursor(); + o->showCursor(); } else { - (*it)->hideCursor(); + o->hideCursor(); } } } @@ -653,7 +663,8 @@ { if (m_cursorEnabled) { for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { - (*it)->showCursor(); + auto o = qobject_cast(*it); + o->showCursor(); } } markCursorAsRendered(); @@ -673,7 +684,8 @@ return; } for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { - (*it)->updateCursor(); + auto o = qobject_cast(*it); + o->updateCursor(); } setCursor(); @@ -691,7 +703,8 @@ return; } for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { - (*it)->hideCursor(); + auto o = qobject_cast(*it); + o->hideCursor(); } } @@ -701,7 +714,8 @@ return; } for (auto it = m_outputs.constBegin(); it != m_outputs.constEnd(); ++it) { - (*it)->moveCursor(Cursor::pos()); + auto o = qobject_cast(*it); + o->moveCursor(Cursor::pos()); } } @@ -747,7 +761,8 @@ } bool enabled = false; for (auto it = m_enabledOutputs.constBegin(); it != m_enabledOutputs.constEnd(); ++it) { - enabled = enabled || (*it)->isDpmsEnabled(); + auto o = qobject_cast(*it); + enabled = enabled || o->isDpmsEnabled(); } setOutputsEnabled(enabled); } @@ -766,15 +781,17 @@ if (m_outputs.size() <= screen) { return 0; } - return m_outputs.at(screen)->m_crtc->getGammaRampSize(); + auto o = qobject_cast(m_outputs.at(screen)); + return o->m_crtc->getGammaRampSize(); } bool DrmBackend::setGammaRamp(int screen, ColorCorrect::GammaRamp &gamma) { if (m_outputs.size() <= screen) { return false; } - return m_outputs.at(screen)->m_crtc->setGammaRamp(gamma); + auto o = qobject_cast(m_outputs.at(screen)); + return o->m_crtc->setGammaRamp(gamma); } QString DrmBackend::supportInformation() const diff --git a/plugins/platforms/drm/drm_output.h b/plugins/platforms/drm/drm_output.h --- a/plugins/platforms/drm/drm_output.h +++ b/plugins/platforms/drm/drm_output.h @@ -20,30 +20,19 @@ #ifndef KWIN_DRM_OUTPUT_H #define KWIN_DRM_OUTPUT_H +#include "output.h" #include "drm_pointer.h" #include "drm_object.h" #include "drm_object_plane.h" #include #include -#include #include #include #include #include -namespace KWayland -{ -namespace Server -{ -class OutputInterface; -class OutputDeviceInterface; -class OutputChangeSet; -class OutputManagementInterface; -} -} - namespace KWin { @@ -54,7 +43,7 @@ class DrmConnector; class DrmCrtc; -class DrmOutput : public QObject +class KWIN_EXPORT DrmOutput : public Output { Q_OBJECT public: @@ -82,23 +71,11 @@ * The default is on */ void setEnabled(bool enabled); - bool isEnabled() const; - - /** - * This sets the changes and tests them against the DRM output - */ - void setChanges(KWayland::Server::OutputChangeSet *changeset); - bool commitChanges(); - QSize pixelSize() const; - qreal scale() const; + virtual bool commitChanges() override; - /* - * The geometry of this output in global compositor co-ordinates (i.e scaled) - */ - QRect geometry() const; + QSize pixelSize() const override; - QString name() const; int currentRefreshRate() const; // These values are defined by the kernel enum class DpmsMode { @@ -117,24 +94,10 @@ return m_uuid; } - QSize physicalSize() const; - bool initCursor(const QSize &cursorSize); bool supportsTransformations() const; - bool isInternal() const { - return m_internal; - } - - Qt::ScreenOrientation orientation() const { - return m_orientation; - } - - const QPointer getWaylandInterface() const { - return m_waylandOutput; - } - Q_SIGNALS: void dpmsChanged(); void modeChanged(); @@ -160,8 +123,6 @@ bool isCurrentMode(const drmModeModeInfo *mode) const; void initUuid(); - void setGlobalPos(const QPoint &pos); - void setScale(qreal scale); void initOutput(); bool initPrimaryPlane(); bool initCursorPlane(); @@ -178,14 +139,9 @@ DrmBackend *m_backend; DrmConnector *m_conn = nullptr; DrmCrtc *m_crtc = nullptr; - QPoint m_globalPos; - qreal m_scale = 1; bool m_lastGbm = false; drmModeModeInfo m_mode; Edid m_edid; - QPointer m_waylandOutput; - QPointer m_waylandOutputDevice; - QPointer m_changeset; KWin::ScopedDrmPointer<_drmModeProperty, &drmModeFreeProperty> m_dpms; DpmsMode m_dpmsMode = DpmsMode::On; DpmsMode m_dpmsModePending = DpmsMode::On; @@ -198,8 +154,6 @@ bool m_pageFlipPending = false; bool m_dpmsAtomicOffPending = false; bool m_modesetRequested = true; - QSize m_physicalSize; - Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; struct { Qt::ScreenOrientation orientation; @@ -211,7 +165,6 @@ DrmDumbBuffer *m_cursor[2] = {nullptr, nullptr}; int m_cursorIndex = 0; bool m_hasNewCursor = false; - bool m_internal = false; }; } diff --git a/plugins/platforms/drm/drm_output.cpp b/plugins/platforms/drm/drm_output.cpp --- a/plugins/platforms/drm/drm_output.cpp +++ b/plugins/platforms/drm/drm_output.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include // KF5 @@ -57,7 +56,7 @@ { DrmOutput::DrmOutput(DrmBackend *backend) - : QObject() + : Output() , m_backend(backend) { } @@ -165,24 +164,6 @@ return QSize(m_mode.hdisplay, m_mode.vdisplay); } -QSize DrmOutput::physicalSize() const -{ - if (m_orientation == Qt::PortraitOrientation || m_orientation == Qt::InvertedPortraitOrientation) { - return QSize(m_physicalSize.height(), m_physicalSize.width()); - } - return m_physicalSize; -} - -QRect DrmOutput::geometry() const -{ - return QRect(m_globalPos, pixelSize() / scale()); -} - -qreal DrmOutput::scale() const -{ - return m_scale; -} - void DrmOutput::setEnabled(bool enabled) { if (enabled == isEnabled()) { @@ -199,11 +180,6 @@ KWayland::Server::OutputDeviceInterface::Enablement::Enabled : KWayland::Server::OutputDeviceInterface::Enablement::Disabled); } -bool DrmOutput::isEnabled() const -{ - return !m_waylandOutput.isNull(); -} - static KWayland::Server::OutputInterface::DpmsMode toWaylandDpmsMode(DrmOutput::DpmsMode mode) { using namespace KWayland::Server; @@ -754,51 +730,14 @@ m_backend->outputWentOff(); } -QString DrmOutput::name() const -{ - if (!m_waylandOutput) { - return i18n("unknown"); - } - return QStringLiteral("%1 %2").arg(m_waylandOutput->manufacturer()).arg(m_waylandOutput->model()); -} - int DrmOutput::currentRefreshRate() const { if (!m_waylandOutput) { return 60000; } return m_waylandOutput->refreshRate(); } -void DrmOutput::setGlobalPos(const QPoint &pos) -{ - m_globalPos = pos; - if (m_waylandOutput) { - m_waylandOutput->setGlobalPosition(pos); - } - if (m_waylandOutputDevice) { - m_waylandOutputDevice->setGlobalPosition(pos); - } -} - -void DrmOutput::setScale(qreal scale) -{ - m_scale = scale; - if (m_waylandOutput) { - m_waylandOutput->setScale(scale); - } - if (m_waylandOutputDevice) { - m_waylandOutputDevice->setScale(scale); - } -} - -void DrmOutput::setChanges(KWayland::Server::OutputChangeSet *changes) -{ - m_changeset = changes; - qCDebug(KWIN_DRM) << "set changes in DrmOutput"; - commitChanges(); -} - bool DrmOutput::commitChanges() { Q_ASSERT(!m_waylandOutputDevice.isNull()); diff --git a/plugins/platforms/drm/egl_gbm_backend.h b/plugins/platforms/drm/egl_gbm_backend.h --- a/plugins/platforms/drm/egl_gbm_backend.h +++ b/plugins/platforms/drm/egl_gbm_backend.h @@ -61,7 +61,7 @@ bool initBufferConfigs(); bool initRenderingContext(); void initRemotePresent(); - struct Output { + struct EglGbmOutput { DrmOutput *output = nullptr; DrmBuffer *buffer = nullptr; std::shared_ptr gbmSurface; @@ -72,13 +72,13 @@ */ QList damageHistory; }; - bool resetOutput(Output &output, DrmOutput *drmOutput); - bool makeContextCurrent(const Output &output); - void presentOnOutput(Output &output); - void cleanupOutput(const Output &output); + bool resetOutput(EglGbmOutput &output, DrmOutput *drmOutput); + bool makeContextCurrent(const EglGbmOutput &output); + void presentOnOutput(EglGbmOutput &output); + void cleanupOutput(const EglGbmOutput &output); void createOutput(DrmOutput *output); DrmBackend *m_backend; - QVector m_outputs; + QVector m_outputs; QScopedPointer m_remoteaccessManager; friend class EglGbmTexture; }; diff --git a/plugins/platforms/drm/egl_gbm_backend.cpp b/plugins/platforms/drm/egl_gbm_backend.cpp --- a/plugins/platforms/drm/egl_gbm_backend.cpp +++ b/plugins/platforms/drm/egl_gbm_backend.cpp @@ -47,7 +47,7 @@ connect(m_backend, &DrmBackend::outputRemoved, this, [this] (DrmOutput *output) { auto it = std::find_if(m_outputs.begin(), m_outputs.end(), - [output] (const Output &o) { + [output] (const EglGbmOutput &o) { return o.output == output; } ); @@ -73,7 +73,7 @@ m_outputs.clear(); } -void EglGbmBackend::cleanupOutput(const Output &o) +void EglGbmBackend::cleanupOutput(const EglGbmOutput &o) { o.output->releaseGbm(); @@ -142,8 +142,8 @@ } const auto outputs = m_backend->outputs(); - for (DrmOutput *drmOutput: outputs) { - createOutput(drmOutput); + for (Output *drmOutput: outputs) { + createOutput(qobject_cast(drmOutput)); } if (m_outputs.isEmpty()) { qCCritical(KWIN_DRM) << "Create Window Surfaces failed"; @@ -165,7 +165,7 @@ m_remoteaccessManager.reset(new RemoteAccessManager); } -bool EglGbmBackend::resetOutput(Output &o, DrmOutput *drmOutput) +bool EglGbmBackend::resetOutput(EglGbmOutput &o, DrmOutput *drmOutput) { o.output = drmOutput; auto size = drmOutput->pixelSize(); @@ -196,7 +196,7 @@ void EglGbmBackend::createOutput(DrmOutput *drmOutput) { - Output o; + EglGbmOutput o; if (resetOutput(o, drmOutput)) { connect(drmOutput, &DrmOutput::modeChanged, this, [drmOutput, this] { @@ -215,7 +215,7 @@ } } -bool EglGbmBackend::makeContextCurrent(const Output &output) +bool EglGbmBackend::makeContextCurrent(const EglGbmOutput &output) { const EGLSurface surface = output.eglSurface; if (surface == EGL_NO_SURFACE) { @@ -279,7 +279,7 @@ } } -void EglGbmBackend::presentOnOutput(EglGbmBackend::Output &o) +void EglGbmBackend::presentOnOutput(EglGbmBackend::EglGbmOutput &o) { eglSwapBuffers(eglDisplay(), o.eglSurface); o.buffer = m_backend->createBuffer(o.gbmSurface); @@ -315,7 +315,7 @@ QRegion EglGbmBackend::prepareRenderingForScreen(int screenId) { - const Output &o = m_outputs.at(screenId); + const EglGbmOutput &o = m_outputs.at(screenId); makeContextCurrent(o); if (supportsBufferAge()) { QRegion region; @@ -341,7 +341,7 @@ void EglGbmBackend::endRenderingFrameForScreen(int screenId, const QRegion &renderedRegion, const QRegion &damagedRegion) { - Output &o = m_outputs[screenId]; + EglGbmOutput &o = m_outputs[screenId]; if (damagedRegion.intersected(o.output->geometry()).isEmpty() && screenId == 0) { // If the damaged region of a window is fully occluded, the only diff --git a/plugins/platforms/drm/scene_qpainter_drm_backend.h b/plugins/platforms/drm/scene_qpainter_drm_backend.h --- a/plugins/platforms/drm/scene_qpainter_drm_backend.h +++ b/plugins/platforms/drm/scene_qpainter_drm_backend.h @@ -47,12 +47,12 @@ private: void initOutput(DrmOutput *output); - struct Output { + struct QPainterOutput { DrmDumbBuffer *buffer[2]; DrmOutput *output; int index = 0; }; - QVector m_outputs; + QVector m_outputs; DrmBackend *m_backend; }; } diff --git a/plugins/platforms/drm/scene_qpainter_drm_backend.cpp b/plugins/platforms/drm/scene_qpainter_drm_backend.cpp --- a/plugins/platforms/drm/scene_qpainter_drm_backend.cpp +++ b/plugins/platforms/drm/scene_qpainter_drm_backend.cpp @@ -32,13 +32,13 @@ { const auto outputs = m_backend->outputs(); for (auto output: outputs) { - initOutput(output); + initOutput(qobject_cast(output)); } connect(m_backend, &DrmBackend::outputAdded, this, &DrmQPainterBackend::initOutput); connect(m_backend, &DrmBackend::outputRemoved, this, [this] (DrmOutput *o) { auto it = std::find_if(m_outputs.begin(), m_outputs.end(), - [o] (const Output &output) { + [o] (const QPainterOutput &output) { return output.output == o; } ); @@ -62,7 +62,7 @@ void DrmQPainterBackend::initOutput(DrmOutput *output) { - Output o; + QPainterOutput o; auto initBuffer = [&o, output, this] (int index) { o.buffer[index] = m_backend->createBuffer(output->pixelSize()); o.buffer[index]->map(); @@ -102,7 +102,7 @@ QImage *DrmQPainterBackend::bufferForScreen(int screenId) { - const Output &o = m_outputs.at(screenId); + const QPainterOutput &o = m_outputs.at(screenId); return o.buffer[o.index]->image(); } @@ -126,7 +126,7 @@ return; } for (auto it = m_outputs.begin(); it != m_outputs.end(); ++it) { - const Output &o = *it; + const QPainterOutput &o = *it; m_backend->present(o.buffer[o.index], o.output); } } diff --git a/plugins/platforms/drm/screens_drm.cpp b/plugins/platforms/drm/screens_drm.cpp --- a/plugins/platforms/drm/screens_drm.cpp +++ b/plugins/platforms/drm/screens_drm.cpp @@ -79,7 +79,8 @@ int minDistance = INT_MAX; const auto outputs = m_backend->enabledOutputs(); for (int i = 0; i < outputs.size(); ++i) { - const QRect &geo = outputs.at(i)->geometry(); + auto o = qobject_cast(outputs.at(i)); + const QRect &geo = o->geometry(); if (geo.contains(pos)) { return i; } @@ -110,16 +111,18 @@ if (screen >= outputs.size()) { return Screens::refreshRate(screen); } - return outputs.at(screen)->currentRefreshRate() / 1000.0f; + auto o = qobject_cast(outputs.at(screen)); + return o->currentRefreshRate() / 1000.0f; } QSizeF DrmScreens::physicalSize(int screen) const { const auto outputs = m_backend->enabledOutputs(); if (screen >= outputs.size()) { return Screens::physicalSize(screen); } - return outputs.at(screen)->physicalSize(); + auto o = qobject_cast(outputs.at(screen)); + return o->physicalSize(); } bool DrmScreens::isInternal(int screen) const @@ -137,16 +140,18 @@ if (screen >= outputs.size()) { return false; } - return outputs.at(screen)->supportsTransformations(); + auto o = qobject_cast(outputs.at(screen)); + return o->supportsTransformations(); } Qt::ScreenOrientation DrmScreens::orientation(int screen) const { const auto outputs = m_backend->outputs(); if (screen >= outputs.size()) { return Qt::PrimaryOrientation; } - return outputs.at(screen)->orientation(); + auto o = qobject_cast(outputs.at(screen)); + return o->orientation(); } }