Changeset View
Changeset View
Standalone View
Standalone View
abstract_wayland_output.cpp
- This file was copied from abstract_output.cpp.
1 | /******************************************************************** | 1 | /******************************************************************** | ||
---|---|---|---|---|---|
2 | KWin - the KDE window manager | 2 | KWin - the KDE window manager | ||
3 | This file is part of the KDE project. | 3 | This file is part of the KDE project. | ||
4 | 4 | | |||
5 | Copyright 2018 Roman Gilg <subdiff@gmail.com> | 5 | Copyright 2019 Roman Gilg <subdiff@gmail.com> | ||
6 | 6 | | |||
7 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | 8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | 9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | 10 | (at your option) any later version. | ||
11 | 11 | | |||
12 | This program is distributed in the hope that it will be useful, | 12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | 15 | GNU General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | #include "abstract_output.h" | 20 | #include "abstract_wayland_output.h" | ||
21 | #include "wayland_server.h" | 21 | #include "wayland_server.h" | ||
22 | 22 | | |||
23 | // KWayland | 23 | // KWayland | ||
24 | #include <KWayland/Server/display.h> | 24 | #include <KWayland/Server/display.h> | ||
25 | #include <KWayland/Server/outputchangeset.h> | 25 | #include <KWayland/Server/outputchangeset.h> | ||
26 | #include <KWayland/Server/xdgoutput_interface.h> | 26 | #include <KWayland/Server/xdgoutput_interface.h> | ||
27 | // KF5 | 27 | // KF5 | ||
28 | #include <KLocalizedString> | 28 | #include <KLocalizedString> | ||
29 | 29 | | |||
30 | #include <cmath> | 30 | #include <cmath> | ||
31 | 31 | | |||
32 | namespace KWin | 32 | namespace KWin | ||
33 | { | 33 | { | ||
34 | 34 | | |||
35 | AbstractOutput::AbstractOutput(QObject *parent) | 35 | AbstractWaylandOutput::AbstractWaylandOutput(QObject *parent) | ||
36 | : QObject(parent) | 36 | : AbstractOutput(parent) | ||
37 | { | 37 | { | ||
38 | } | 38 | } | ||
39 | 39 | | |||
40 | AbstractOutput::~AbstractOutput() | 40 | AbstractWaylandOutput::~AbstractWaylandOutput() | ||
41 | { | 41 | { | ||
42 | delete m_waylandOutputDevice.data(); | 42 | delete m_waylandOutputDevice.data(); | ||
43 | delete m_xdgOutput.data(); | 43 | delete m_xdgOutput.data(); | ||
44 | delete m_waylandOutput.data(); | 44 | delete m_waylandOutput.data(); | ||
45 | } | 45 | } | ||
46 | 46 | | |||
47 | QString AbstractOutput::name() const | 47 | QString AbstractWaylandOutput::name() const | ||
48 | { | 48 | { | ||
49 | if (!m_waylandOutput) { | 49 | if (!m_waylandOutput) { | ||
50 | return i18n("unknown"); | 50 | return i18n("unknown"); | ||
51 | } | 51 | } | ||
52 | return QStringLiteral("%1 %2").arg(m_waylandOutput->manufacturer()).arg(m_waylandOutput->model()); | 52 | return QStringLiteral("%1 %2").arg(m_waylandOutput->manufacturer()).arg(m_waylandOutput->model()); | ||
53 | } | 53 | } | ||
54 | 54 | | |||
55 | QRect AbstractOutput::geometry() const | 55 | QRect AbstractWaylandOutput::geometry() const | ||
56 | { | 56 | { | ||
57 | return QRect(m_globalPos, pixelSize() / scale()); | 57 | return QRect(m_globalPos, pixelSize() / scale()); | ||
58 | } | 58 | } | ||
59 | 59 | | |||
60 | QSize AbstractOutput::physicalSize() const | 60 | QSize AbstractWaylandOutput::physicalSize() const | ||
61 | { | 61 | { | ||
62 | return orientateSize(m_physicalSize); | 62 | return orientateSize(m_physicalSize); | ||
63 | } | 63 | } | ||
64 | 64 | | |||
65 | int AbstractOutput::refreshRate() const | 65 | int AbstractWaylandOutput::refreshRate() const | ||
66 | { | 66 | { | ||
67 | if (!m_waylandOutput) { | 67 | if (!m_waylandOutput) { | ||
68 | return 60000; | 68 | return 60000; | ||
69 | } | 69 | } | ||
70 | return m_waylandOutput->refreshRate(); | 70 | return m_waylandOutput->refreshRate(); | ||
71 | } | 71 | } | ||
72 | 72 | | |||
73 | void AbstractOutput::setGlobalPos(const QPoint &pos) | 73 | void AbstractWaylandOutput::setGlobalPos(const QPoint &pos) | ||
74 | { | 74 | { | ||
75 | m_globalPos = pos; | 75 | m_globalPos = pos; | ||
76 | if (m_waylandOutput) { | 76 | if (m_waylandOutput) { | ||
77 | m_waylandOutput->setGlobalPosition(pos); | 77 | m_waylandOutput->setGlobalPosition(pos); | ||
78 | } | 78 | } | ||
79 | if (m_waylandOutputDevice) { | 79 | if (m_waylandOutputDevice) { | ||
80 | m_waylandOutputDevice->setGlobalPosition(pos); | 80 | m_waylandOutputDevice->setGlobalPosition(pos); | ||
81 | } | 81 | } | ||
82 | if (m_xdgOutput) { | 82 | if (m_xdgOutput) { | ||
83 | m_xdgOutput->setLogicalPosition(pos); | 83 | m_xdgOutput->setLogicalPosition(pos); | ||
84 | m_xdgOutput->done(); | 84 | m_xdgOutput->done(); | ||
85 | } | 85 | } | ||
86 | } | 86 | } | ||
87 | 87 | | |||
88 | void AbstractOutput::setScale(qreal scale) | 88 | void AbstractWaylandOutput::setScale(qreal scale) | ||
89 | { | 89 | { | ||
90 | m_scale = scale; | 90 | m_scale = scale; | ||
91 | if (m_waylandOutput) { | 91 | if (m_waylandOutput) { | ||
92 | // this is the scale that clients will ideally use for their buffers | 92 | // this is the scale that clients will ideally use for their buffers | ||
93 | // this has to be an int which is fine | 93 | // this has to be an int which is fine | ||
94 | 94 | | |||
95 | // I don't know whether we want to round or ceil | 95 | // I don't know whether we want to round or ceil | ||
96 | // or maybe even set this to 3 when we're scaling to 1.5 | 96 | // or maybe even set this to 3 when we're scaling to 1.5 | ||
97 | // don't treat this like it's chosen deliberately | 97 | // don't treat this like it's chosen deliberately | ||
98 | m_waylandOutput->setScale(std::ceil(scale)); | 98 | m_waylandOutput->setScale(std::ceil(scale)); | ||
99 | } | 99 | } | ||
100 | if (m_waylandOutputDevice) { | 100 | if (m_waylandOutputDevice) { | ||
101 | m_waylandOutputDevice->setScaleF(scale); | 101 | m_waylandOutputDevice->setScaleF(scale); | ||
102 | } | 102 | } | ||
103 | if (m_xdgOutput) { | 103 | if (m_xdgOutput) { | ||
104 | m_xdgOutput->setLogicalSize(pixelSize() / m_scale); | 104 | m_xdgOutput->setLogicalSize(pixelSize() / m_scale); | ||
105 | m_xdgOutput->done(); | 105 | m_xdgOutput->done(); | ||
106 | } | 106 | } | ||
107 | emit modeChanged(); | 107 | emit modeChanged(); | ||
108 | } | 108 | } | ||
109 | 109 | | |||
110 | void AbstractOutput::setChanges(KWayland::Server::OutputChangeSet *changes) | 110 | void AbstractWaylandOutput::setChanges(KWayland::Server::OutputChangeSet *changes) | ||
111 | { | 111 | { | ||
112 | qCDebug(KWIN_CORE) << "Set changes in AbstractOutput."; | 112 | qCDebug(KWIN_CORE) << "Set changes in AbstractWaylandOutput."; | ||
113 | Q_ASSERT(!m_waylandOutputDevice.isNull()); | 113 | Q_ASSERT(!m_waylandOutputDevice.isNull()); | ||
114 | 114 | | |||
115 | if (!changes) { | 115 | if (!changes) { | ||
116 | qCDebug(KWIN_CORE) << "No changes."; | 116 | qCDebug(KWIN_CORE) << "No changes."; | ||
117 | // No changes to an output is an entirely valid thing | 117 | // No changes to an output is an entirely valid thing | ||
118 | } | 118 | } | ||
119 | //enabledChanged is handled by plugin code | 119 | //enabledChanged is handled by plugin code | ||
120 | if (changes->modeChanged()) { | 120 | if (changes->modeChanged()) { | ||
Show All 11 Lines | 129 | if (changes->positionChanged()) { | |||
132 | // may just work already! | 132 | // may just work already! | ||
133 | } | 133 | } | ||
134 | if (changes->scaleChanged()) { | 134 | if (changes->scaleChanged()) { | ||
135 | qCDebug(KWIN_CORE) << "Setting scale:" << changes->scale(); | 135 | qCDebug(KWIN_CORE) << "Setting scale:" << changes->scale(); | ||
136 | setScale(changes->scaleF()); | 136 | setScale(changes->scaleF()); | ||
137 | } | 137 | } | ||
138 | } | 138 | } | ||
139 | 139 | | |||
140 | void AbstractOutput::setEnabled(bool enable) | 140 | void AbstractWaylandOutput::setEnabled(bool enable) | ||
141 | { | 141 | { | ||
142 | if (enable == isEnabled()) { | 142 | if (enable == isEnabled()) { | ||
143 | return; | 143 | return; | ||
144 | } | 144 | } | ||
145 | if (enable) { | 145 | if (enable) { | ||
146 | updateDpms(KWayland::Server::OutputInterface::DpmsMode::On); | 146 | updateDpms(KWayland::Server::OutputInterface::DpmsMode::On); | ||
147 | initWaylandOutput(); | 147 | initWaylandOutput(); | ||
148 | } else { | 148 | } else { | ||
149 | updateDpms(KWayland::Server::OutputInterface::DpmsMode::Off); | 149 | updateDpms(KWayland::Server::OutputInterface::DpmsMode::Off); | ||
150 | delete waylandOutput().data(); | 150 | delete waylandOutput().data(); | ||
151 | } | 151 | } | ||
152 | waylandOutputDevice()->setEnabled(enable ? KWayland::Server::OutputDeviceInterface::Enablement::Enabled : | 152 | waylandOutputDevice()->setEnabled(enable ? KWayland::Server::OutputDeviceInterface::Enablement::Enabled : | ||
153 | KWayland::Server::OutputDeviceInterface::Enablement::Disabled); | 153 | KWayland::Server::OutputDeviceInterface::Enablement::Disabled); | ||
154 | } | 154 | } | ||
155 | 155 | | |||
156 | void AbstractOutput::setWaylandMode(const QSize &size, int refreshRate) | 156 | void AbstractWaylandOutput::setWaylandMode(const QSize &size, int refreshRate) | ||
157 | { | 157 | { | ||
158 | if (m_waylandOutput.isNull()) { | 158 | if (m_waylandOutput.isNull()) { | ||
159 | return; | 159 | return; | ||
160 | } | 160 | } | ||
161 | m_waylandOutput->setCurrentMode(size, refreshRate); | 161 | m_waylandOutput->setCurrentMode(size, refreshRate); | ||
162 | if (m_xdgOutput) { | 162 | if (m_xdgOutput) { | ||
163 | m_xdgOutput->setLogicalSize(pixelSize() / scale()); | 163 | m_xdgOutput->setLogicalSize(pixelSize() / scale()); | ||
164 | m_xdgOutput->done(); | 164 | m_xdgOutput->done(); | ||
165 | } | 165 | } | ||
166 | } | 166 | } | ||
167 | 167 | | |||
168 | void AbstractOutput::createXdgOutput() | 168 | void AbstractWaylandOutput::createXdgOutput() | ||
169 | { | 169 | { | ||
170 | if (!m_waylandOutput || m_xdgOutput) { | 170 | if (!m_waylandOutput || m_xdgOutput) { | ||
171 | return; | 171 | return; | ||
172 | } | 172 | } | ||
173 | m_xdgOutput = waylandServer()->xdgOutputManager()->createXdgOutput(m_waylandOutput, m_waylandOutput); | 173 | m_xdgOutput = waylandServer()->xdgOutputManager()->createXdgOutput(m_waylandOutput, m_waylandOutput); | ||
174 | m_xdgOutput->setLogicalSize(pixelSize() / scale()); | | |||
175 | m_xdgOutput->setLogicalPosition(m_globalPos); | | |||
176 | m_xdgOutput->done(); | | |||
177 | } | 174 | } | ||
178 | 175 | | |||
179 | void AbstractOutput::initWaylandOutput() | 176 | void AbstractWaylandOutput::initWaylandOutput() | ||
180 | { | 177 | { | ||
181 | Q_ASSERT(m_waylandOutputDevice); | 178 | Q_ASSERT(m_waylandOutputDevice); | ||
182 | 179 | | |||
183 | if (!m_waylandOutput.isNull()) { | 180 | if (!m_waylandOutput.isNull()) { | ||
184 | delete m_waylandOutput.data(); | 181 | delete m_waylandOutput.data(); | ||
185 | m_waylandOutput.clear(); | 182 | m_waylandOutput.clear(); | ||
186 | } | 183 | } | ||
187 | m_waylandOutput = waylandServer()->display()->createOutput(); | 184 | m_waylandOutput = waylandServer()->display()->createOutput(); | ||
Show All 29 Lines | |||||
217 | m_waylandOutput->setDpmsMode(m_dpms); | 214 | m_waylandOutput->setDpmsMode(m_dpms); | ||
218 | connect(m_waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this, | 215 | connect(m_waylandOutput.data(), &KWayland::Server::OutputInterface::dpmsModeRequested, this, | ||
219 | [this] (KWayland::Server::OutputInterface::DpmsMode mode) { | 216 | [this] (KWayland::Server::OutputInterface::DpmsMode mode) { | ||
220 | updateDpms(mode); | 217 | updateDpms(mode); | ||
221 | }, Qt::QueuedConnection | 218 | }, Qt::QueuedConnection | ||
222 | ); | 219 | ); | ||
223 | } | 220 | } | ||
224 | 221 | | |||
225 | void AbstractOutput::initWaylandOutputDevice(const QString &model, | 222 | void AbstractWaylandOutput::initWaylandOutputDevice(const QString &model, | ||
226 | const QString &manufacturer, | 223 | const QString &manufacturer, | ||
227 | const QByteArray &uuid, | 224 | const QByteArray &uuid, | ||
228 | const QVector<KWayland::Server::OutputDeviceInterface::Mode> &modes) | 225 | const QVector<KWayland::Server::OutputDeviceInterface::Mode> &modes) | ||
229 | { | 226 | { | ||
230 | if (!m_waylandOutputDevice.isNull()) { | 227 | if (!m_waylandOutputDevice.isNull()) { | ||
231 | delete m_waylandOutputDevice.data(); | 228 | delete m_waylandOutputDevice.data(); | ||
232 | m_waylandOutputDevice.clear(); | 229 | m_waylandOutputDevice.clear(); | ||
233 | } | 230 | } | ||
Show All 12 Lines | |||||
246 | int i = 0; | 243 | int i = 0; | ||
247 | for (auto mode : modes) { | 244 | for (auto mode : modes) { | ||
248 | qCDebug(KWIN_CORE).nospace() << "Adding mode " << ++i << ": " << mode.size << " [" << mode.refreshRate << "]"; | 245 | qCDebug(KWIN_CORE).nospace() << "Adding mode " << ++i << ": " << mode.size << " [" << mode.refreshRate << "]"; | ||
249 | m_waylandOutputDevice->addMode(mode); | 246 | m_waylandOutputDevice->addMode(mode); | ||
250 | } | 247 | } | ||
251 | m_waylandOutputDevice->create(); | 248 | m_waylandOutputDevice->create(); | ||
252 | } | 249 | } | ||
253 | 250 | | |||
254 | QSize AbstractOutput::orientateSize(const QSize &size) const | 251 | QSize AbstractWaylandOutput::orientateSize(const QSize &size) const | ||
255 | { | 252 | { | ||
256 | if (m_orientation == Qt::PortraitOrientation || m_orientation == Qt::InvertedPortraitOrientation) { | 253 | if (m_orientation == Qt::PortraitOrientation || m_orientation == Qt::InvertedPortraitOrientation) { | ||
257 | return size.transposed(); | 254 | return size.transposed(); | ||
258 | } | 255 | } | ||
259 | return size; | 256 | return size; | ||
260 | } | 257 | } | ||
261 | 258 | | |||
262 | } | 259 | } |