Use Transform enum internally

Summary:
Instead of using Qt::ScreenOrientation use an enum class that is directly
mapped to KWayland's transformation enums. This simplifies the code.

Test Plan: Compiles and transformations work as before.

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin

Tags: #kwin

Maniphest Tasks: T11670

Differential Revision: https://phabricator.kde.org/D25558
master
Roman Gilg 2019-11-26 23:53:17 +01:00
parent eb186a78a1
commit e827d0a8ee
4 changed files with 77 additions and 108 deletions

View File

@ -151,6 +151,18 @@ void AbstractWaylandOutput::setTransform(DeviceInterface::Transform transform)
}
}
inline
AbstractWaylandOutput::Transform toTransform(DeviceInterface::Transform deviceTransform)
{
return static_cast<AbstractWaylandOutput::Transform>(deviceTransform);
}
inline
DeviceInterface::Transform toDeviceTransform(AbstractWaylandOutput::Transform transform)
{
return static_cast<DeviceInterface::Transform>(transform);
}
void AbstractWaylandOutput::applyChanges(const KWayland::Server::OutputChangeSet *changeSet)
{
qCDebug(KWIN_CORE) << "Apply changes to the Wayland output.";
@ -165,7 +177,7 @@ void AbstractWaylandOutput::applyChanges(const KWayland::Server::OutputChangeSet
}
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 @@ QSize AbstractWaylandOutput::orientateSize(const QSize &size) const
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<Transform>(m_waylandOutputDevice->transform());
}
}

View File

@ -56,6 +56,17 @@ class KWIN_EXPORT AbstractWaylandOutput : public AbstractOutput
{
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 @@ protected:
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 @@ protected:
* - Rotated 270° and flipped along the horizontal axis is inv. portrait + inv. landscape +
* portrait
*/
Qt::ScreenOrientations orientation() const;
Transform transform() const;
private:
void createWaylandOutput();

View File

@ -128,18 +128,21 @@ bool DrmOutput::showCursor()
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 @@ int orientationToRotation(Qt::ScreenOrientations orientation)
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 @@ void DrmOutput::moveCursor(const QPoint &globalPos)
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,44 +649,39 @@ bool DrmOutput::dpmsLegacyApply()
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;
}
@ -687,12 +690,6 @@ void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform tra
updateCursor();
showCursor();
}
#else
void DrmOutput::transform(KWayland::Server::OutputDeviceInterface::Transform transform)
{
Q_UNUSED(transform)
}
#endif
void DrmOutput::updateMode(int modeIndex)
{
@ -841,7 +838,7 @@ bool DrmOutput::presentAtomically(DrmBuffer *buffer)
// 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 @@ bool DrmOutput::presentAtomically(DrmBuffer *buffer)
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,29 +1064,29 @@ void DrmOutput::automaticRotation()
}
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:
@ -1097,7 +1094,7 @@ void DrmOutput::automaticRotation()
// unsupported
return;
}
transform(newTransformation);
setTransform(newTransformation);
emit screens()->changed();
}

View File

@ -123,7 +123,7 @@ private:
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 @@ private:
bool m_modesetRequested = true;
struct {
Qt::ScreenOrientations orientation;
Transform transform;
drmModeModeInfo mode;
DrmPlane::Transformations planeTransformations;
QPoint globalPos;