diff --git a/src/core/output.cpp b/src/core/output.cpp index 9f24aaadf4..30f47223ce 100644 --- a/src/core/output.cpp +++ b/src/core/output.cpp @@ -60,6 +60,81 @@ OutputMode::Flags OutputMode::flags() const return m_flags; } +Output::Transform invertOutputTransform(Output::Transform transform) +{ + switch (transform) { + case Output::Transform::Normal: + return Output::Transform::Normal; + case Output::Transform::Rotated90: + return Output::Transform::Rotated270; + case Output::Transform::Rotated180: + return Output::Transform::Rotated180; + case Output::Transform::Rotated270: + return Output::Transform::Rotated90; + case Output::Transform::Flipped: + case Output::Transform::Flipped90: + case Output::Transform::Flipped180: + case Output::Transform::Flipped270: + return transform; // inverse transform of a flip transform is itself + } +} + +QRectF applyOutputTransform(const QRectF &rect, const QSizeF &bounds, Output::Transform transform) +{ + QRectF dest; + + switch (transform) { + case Output::Transform::Normal: + case Output::Transform::Rotated180: + case Output::Transform::Flipped: + case Output::Transform::Flipped180: + dest.setWidth(rect.width()); + dest.setHeight(rect.height()); + break; + default: + dest.setWidth(rect.height()); + dest.setHeight(rect.width()); + break; + } + + switch (transform) { + case Output::Transform::Normal: + dest.setX(rect.x()); + dest.setY(rect.y()); + break; + case Output::Transform::Rotated90: + dest.setX(bounds.height() - (rect.y() + rect.height())); + dest.setY(rect.x()); + break; + case Output::Transform::Rotated180: + dest.setX(bounds.width() - (rect.x() + rect.width())); + dest.setY(bounds.height() - (rect.y() + rect.height())); + break; + case Output::Transform::Rotated270: + dest.setX(rect.y()); + dest.setY(bounds.width() - (rect.x() + rect.width())); + break; + case Output::Transform::Flipped: + dest.setX(bounds.width() - (rect.x() + rect.width())); + dest.setY(rect.y()); + break; + case Output::Transform::Flipped90: + dest.setX(rect.y()); + dest.setY(rect.x()); + break; + case Output::Transform::Flipped180: + dest.setX(rect.x()); + dest.setY(bounds.height() - (rect.y() + rect.height())); + break; + case Output::Transform::Flipped270: + dest.setX(bounds.height() - (rect.y() + rect.height())); + dest.setY(bounds.width() - (rect.x() + rect.width())); + break; + } + + return dest; +} + Output::Output(QObject *parent) : QObject(parent) { diff --git a/src/core/output.h b/src/core/output.h index ebdcad3578..8a2fc87eea 100644 --- a/src/core/output.h +++ b/src/core/output.h @@ -371,6 +371,10 @@ protected: friend class EffectScreenImpl; // to access m_effectScreen }; +// TODO: Introduce an OutputTransform type with two methods: invert + apply? +KWIN_EXPORT Output::Transform invertOutputTransform(Output::Transform transform); +KWIN_EXPORT QRectF applyOutputTransform(const QRectF &rect, const QSizeF &bounds, Output::Transform transform); + inline QRect Output::rect() const { return QRect(QPoint(0, 0), geometry().size()); diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index 83a4006775..2f3390be79 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -785,6 +785,20 @@ QRegion SurfaceInterface::input() const return d->inputRegion; } +QRectF SurfaceInterface::bufferSourceBox() const +{ + if (!d->current.viewport.sourceGeometryIsSet) { + return QRectF(0, 0, d->bufferSize.width(), d->bufferSize.height()); + } + + const QRectF box(d->current.viewport.sourceGeometry.x() * d->current.bufferScale, + d->current.viewport.sourceGeometry.y() * d->current.bufferScale, + d->current.viewport.sourceGeometry.width() * d->current.bufferScale, + d->current.viewport.sourceGeometry.height() * d->current.bufferScale); + + return KWin::applyOutputTransform(box, d->bufferSize, KWin::invertOutputTransform(d->current.bufferTransform)); +} + KWin::Output::Transform SurfaceInterface::bufferTransform() const { return d->current.bufferTransform; diff --git a/src/wayland/surface_interface.h b/src/wayland/surface_interface.h index 33af20acb9..62c7049628 100644 --- a/src/wayland/surface_interface.h +++ b/src/wayland/surface_interface.h @@ -145,6 +145,7 @@ public: QRegion opaque() const; QRegion input() const; QRegion bufferDamage() const; + QRectF bufferSourceBox() const; /** * Returns the buffer transform that had been applied to the buffer to compensate for * output rotation.