diff --git a/abstract_wayland_output.h b/abstract_wayland_output.h --- a/abstract_wayland_output.h +++ b/abstract_wayland_output.h @@ -56,6 +56,17 @@ { Q_OBJECT public: + enum class Transform { + Normal, + Rotated90, + Rotated180, + Rotated270, + Flipped, + Flipped90, + Flipped180, + Flipped270 + }; + explicit AbstractWaylandOutput(QObject *parent = nullptr); ~AbstractWaylandOutput() override; @@ -135,13 +146,13 @@ virtual void updateMode(int modeIndex) { Q_UNUSED(modeIndex); } - virtual void transform(KWayland::Server::OutputDeviceInterface::Transform transform) { + virtual void updateTransform(Transform transform) { Q_UNUSED(transform); } void setWaylandMode(const QSize &size, int refreshRate); + void setTransform(Transform transform); - void setOrientation(Qt::ScreenOrientations orientation); QSize orientateSize(const QSize &size) const; /** @@ -153,7 +164,7 @@ * - Rotated 270° and flipped along the horizontal axis is inv. portrait + inv. landscape + * portrait */ - Qt::ScreenOrientations orientation() const; + Transform transform() const; private: void createWaylandOutput(); diff --git a/abstract_wayland_output.cpp b/abstract_wayland_output.cpp --- a/abstract_wayland_output.cpp +++ b/abstract_wayland_output.cpp @@ -151,6 +151,18 @@ } } +inline +AbstractWaylandOutput::Transform toTransform(DeviceInterface::Transform deviceTransform) +{ + return static_cast(deviceTransform); +} + +inline +DeviceInterface::Transform toDeviceTransform(AbstractWaylandOutput::Transform transform) +{ + return static_cast(transform); +} + void AbstractWaylandOutput::applyChanges(const KWayland::Server::OutputChangeSet *changeSet) { qCDebug(KWIN_CORE) << "Apply changes to the Wayland output."; @@ -165,7 +177,7 @@ } if (changeSet->transformChanged()) { qCDebug(KWIN_CORE) << "Server setting transform: " << (int)(changeSet->transform()); - transform(changeSet->transform()); + updateTransform(toTransform(changeSet->transform())); setTransform(changeSet->transform()); emitModeChanged = true; } @@ -308,70 +320,19 @@ return size; } -DeviceInterface::Transform toTransform(Qt::ScreenOrientations orientation) +void AbstractWaylandOutput::setTransform(Transform transform) { - if (orientation | Qt::LandscapeOrientation) { - if (orientation | Qt::InvertedPortraitOrientation) { - return DeviceInterface::Transform::Flipped; - } - return DeviceInterface::Transform::Normal; - } - - if (orientation | Qt::PortraitOrientation) { - if (orientation | Qt::InvertedLandscapeOrientation) { - if (orientation | Qt::InvertedPortraitOrientation) { - return DeviceInterface::Transform::Flipped270; - } - return DeviceInterface::Transform::Flipped90; - } - return DeviceInterface::Transform::Rotated90; - } - - if (orientation | Qt::InvertedLandscapeOrientation) { - return DeviceInterface::Transform::Rotated180; - } - - if (orientation | Qt::InvertedPortraitOrientation) { - return DeviceInterface::Transform::Rotated270; - } - - Q_ASSERT(orientation == Qt::PrimaryOrientation); - return DeviceInterface::Transform::Normal; -} - -void AbstractWaylandOutput::setOrientation(Qt::ScreenOrientations orientation) -{ - const auto transform = toTransform(orientation); - if (transform == m_waylandOutputDevice->transform()) { + const auto deviceTransform = toDeviceTransform(transform); + if (deviceTransform == m_waylandOutputDevice->transform()) { return; } - setTransform(transform); + setTransform(deviceTransform); emit modeChanged(); } -Qt::ScreenOrientations AbstractWaylandOutput::orientation() const +AbstractWaylandOutput::Transform AbstractWaylandOutput::transform() const { - const DeviceInterface::Transform transform = m_waylandOutputDevice->transform(); - - switch (transform) { - case DeviceInterface::Transform::Rotated90: - return Qt::PortraitOrientation; - case DeviceInterface::Transform::Rotated180: - return Qt::InvertedLandscapeOrientation; - case DeviceInterface::Transform::Rotated270: - return Qt::InvertedPortraitOrientation; - case DeviceInterface::Transform::Flipped: - return Qt::LandscapeOrientation | Qt::InvertedPortraitOrientation; - case DeviceInterface::Transform::Flipped90: - return Qt::PortraitOrientation | Qt::InvertedLandscapeOrientation; - case DeviceInterface::Transform::Flipped180: - return Qt::InvertedLandscapeOrientation | Qt::InvertedPortraitOrientation; - case DeviceInterface::Transform::Flipped270: - return Qt::PortraitOrientation | Qt::InvertedLandscapeOrientation | - Qt::InvertedPortraitOrientation; - default: - return Qt::LandscapeOrientation; - } + return static_cast(m_waylandOutputDevice->transform()); } } 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 @@ -123,7 +123,7 @@ void updateMode(int modeIndex) override; void setWaylandMode(); - void transform(KWayland::Server::OutputDeviceInterface::Transform transform) override; + void updateTransform(Transform transform) override; void automaticRotation(); int gammaRampSize() const override; @@ -150,7 +150,7 @@ bool m_modesetRequested = true; struct { - Qt::ScreenOrientations orientation; + Transform transform; drmModeModeInfo mode; DrmPlane::Transformations planeTransformations; QPoint globalPos; 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 @@ -128,18 +128,21 @@ return ret; } -// TODO: Respect OR combinations of values -int orientationToRotation(Qt::ScreenOrientations orientation) +// TODO: Do we need to handle the flipped cases differently? +int transformToRotation(DrmOutput::Transform transform) { - switch (orientation) { - case Qt::PrimaryOrientation: - case Qt::LandscapeOrientation: + switch (transform) { + case DrmOutput::Transform::Normal: + case DrmOutput::Transform::Flipped: return 0; - case Qt::InvertedPortraitOrientation: + case DrmOutput::Transform::Rotated90: + case DrmOutput::Transform::Flipped90: return 90; - case Qt::InvertedLandscapeOrientation: + case DrmOutput::Transform::Rotated180: + case DrmOutput::Transform::Flipped180: return 180; - case Qt::PortraitOrientation: + case DrmOutput::Transform::Rotated270: + case DrmOutput::Transform::Flipped270: return 270; } Q_UNREACHABLE(); @@ -149,7 +152,7 @@ QMatrix4x4 DrmOutput::matrixDisplay(const QSize &s) const { QMatrix4x4 matrix; - const int angle = orientationToRotation(orientation()); + const int angle = transformToRotation(transform()); if (angle) { const QSize center = s / 2; @@ -184,20 +187,25 @@ QPoint p = globalPos - AbstractWaylandOutput::globalPos(); - // TODO: Respect OR combinations of values - switch (orientation()) { - case Qt::PrimaryOrientation: - case Qt::LandscapeOrientation: + // TODO: Do we need to handle the flipped cases differently? + switch (transform()) { + case Transform::Normal: + case Transform::Flipped: break; - case Qt::PortraitOrientation: + case Transform::Rotated90: + case Transform::Flipped90: p = QPoint(p.y(), pixelSize().height() - p.x()); break; - case Qt::InvertedPortraitOrientation: + case Transform::Rotated270: + case Transform::Flipped270: p = QPoint(pixelSize().width() - p.y(), p.x()); break; - case Qt::InvertedLandscapeOrientation: + case Transform::Rotated180: + case Transform::Flipped180: p = QPoint(pixelSize().width() - p.x(), pixelSize().height() - p.y()); break; + default: + Q_UNREACHABLE(); } p *= scale(); p -= hotspotMatrix.map(m_backend->softwareCursorHotspot()); @@ -641,58 +649,47 @@ return true; } -// TODO: Rotation is currently broken in the DRM backend for 90° and 270°. Disable all rotation for -// now to not break user setups until it is possible again. -#if 1 -void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) +void DrmOutput::updateTransform(Transform transform) { - using KWayland::Server::OutputDeviceInterface; - switch (transform) { - case OutputDeviceInterface::Transform::Normal: + case Transform::Normal: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate0); } break; - case OutputDeviceInterface::Transform::Rotated90: + case Transform::Rotated90: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate90); } break; - case OutputDeviceInterface::Transform::Rotated180: + case Transform::Rotated180: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate180); } break; - case OutputDeviceInterface::Transform::Rotated270: + case Transform::Rotated270: if (m_primaryPlane) { m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate270); } break; - case OutputDeviceInterface::Transform::Flipped: + case Transform::Flipped: // TODO: what is this exactly? break; - case OutputDeviceInterface::Transform::Flipped90: + case Transform::Flipped90: // TODO: what is this exactly? break; - case OutputDeviceInterface::Transform::Flipped180: + case Transform::Flipped180: // TODO: what is this exactly? break; - case OutputDeviceInterface::Transform::Flipped270: + case Transform::Flipped270: // TODO: what is this exactly? break; } m_modesetRequested = true; // the cursor might need to get rotated updateCursor(); showCursor(); } -#else -void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform) -{ - Q_UNUSED(transform) -} -#endif void DrmOutput::updateMode(int modeIndex) { @@ -841,7 +838,7 @@ // go back to previous state if (m_lastWorkingState.valid) { m_mode = m_lastWorkingState.mode; - setOrientation(m_lastWorkingState.orientation); + setTransform(m_lastWorkingState.transform); setGlobalPos(m_lastWorkingState.globalPos); if (m_primaryPlane) { m_primaryPlane->setTransformation(m_lastWorkingState.planeTransformations); @@ -865,7 +862,7 @@ if (wasModeset) { // store current mode set as new good state m_lastWorkingState.mode = m_mode; - m_lastWorkingState.orientation = orientation(); + m_lastWorkingState.transform = transform(); m_lastWorkingState.globalPos = globalPos(); if (m_primaryPlane) { m_lastWorkingState.planeTransformations = m_primaryPlane->transformation(); @@ -1067,37 +1064,37 @@ } const auto supportedTransformations = m_primaryPlane->supportedTransformations(); const auto requestedTransformation = screens()->orientationSensor()->orientation(); - using KWayland::Server::OutputDeviceInterface; - OutputDeviceInterface::Transform newTransformation = OutputDeviceInterface::Transform::Normal; + + Transform newTransformation = Transform::Normal; switch (requestedTransformation) { case OrientationSensor::Orientation::TopUp: - newTransformation = OutputDeviceInterface::Transform::Normal; + newTransformation = Transform::Normal; break; case OrientationSensor::Orientation::TopDown: if (!supportedTransformations.testFlag(DrmPlane::Transformation::Rotate180)) { return; } - newTransformation = OutputDeviceInterface::Transform::Rotated180; + newTransformation = Transform::Rotated180; break; case OrientationSensor::Orientation::LeftUp: if (!supportedTransformations.testFlag(DrmPlane::Transformation::Rotate90)) { return; } - newTransformation = OutputDeviceInterface::Transform::Rotated90; + newTransformation = Transform::Rotated90; break; case OrientationSensor::Orientation::RightUp: if (!supportedTransformations.testFlag(DrmPlane::Transformation::Rotate270)) { return; } - newTransformation = OutputDeviceInterface::Transform::Rotated270; + newTransformation = Transform::Rotated270; break; case OrientationSensor::Orientation::FaceUp: case OrientationSensor::Orientation::FaceDown: case OrientationSensor::Orientation::Undefined: // unsupported return; } - transform(newTransformation); + setTransform(newTransformation); emit screens()->changed(); }