7 #include "outputdevice.h"
9 #include "wayland_pointer_p.h"
15 #include "wayland-org_kde_kwin_outputdevice-client-protocol.h"
16 #include <wayland-client-protocol.h>
24 class Q_DECL_HIDDEN OutputDevice::Private
27 Private(OutputDevice *q);
28 void setup(org_kde_kwin_outputdevice *o);
30 WaylandPointer<org_kde_kwin_outputdevice, org_kde_kwin_outputdevice_destroy> output;
31 EventQueue *queue =
nullptr;
39 SubPixel subPixel = SubPixel::Unknown;
42 Modes::iterator currentMode = modes.
end();
45 OutputDevice::Enablement enabled = OutputDevice::Enablement::Enabled;
48 ColorCurves colorCurves;
51 uint32_t overscan = 0;
52 VrrPolicy vrrPolicy = VrrPolicy::Automatic;
57 static void geometryCallback(
void *data,
58 org_kde_kwin_outputdevice *output,
61 int32_t physicalWidth,
62 int32_t physicalHeight,
67 static void modeCallback(
void *data, org_kde_kwin_outputdevice *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh, int32_t mode_id);
68 static void doneCallback(
void *data, org_kde_kwin_outputdevice *output);
69 static void scaleCallback(
void *data, org_kde_kwin_outputdevice *output, int32_t scale);
70 static void scaleFCallback(
void *data, org_kde_kwin_outputdevice *output, wl_fixed_t scale);
72 static void edidCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *raw);
73 static void enabledCallback(
void *data, org_kde_kwin_outputdevice *output, int32_t enabled);
74 static void uuidCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *uuid);
76 static void colorcurvesCallback(
void *data, org_kde_kwin_outputdevice *output, wl_array *red, wl_array *green, wl_array *blue);
78 static void serialNumberCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *serialNumber);
79 static void eisaIdCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *eisa);
80 static void capabilitiesCallback(
void *data, org_kde_kwin_outputdevice *output, uint32_t capabilities);
81 static void overscanCallback(
void *data, org_kde_kwin_outputdevice *output, uint32_t overscan);
82 static void vrrPolicyCallback(
void *data, org_kde_kwin_outputdevice *output, uint32_t vrrPolicy);
84 void setPhysicalSize(
const QSize &size);
85 void setGlobalPosition(
const QPoint &pos);
86 void setManufacturer(
const QString &manufacturer);
87 void setModel(
const QString &model);
88 void setScale(qreal scale);
89 void setSerialNumber(
const QString &serialNumber);
90 void setEisaId(
const QString &eisaId);
91 void setSubPixel(SubPixel subPixel);
92 void setTransform(Transform transform);
93 void addMode(uint32_t flags, int32_t width, int32_t height, int32_t refresh, int32_t mode_id);
96 static struct org_kde_kwin_outputdevice_listener s_outputListener;
99 OutputDevice::Private::Private(OutputDevice *q)
104 void OutputDevice::Private::setup(org_kde_kwin_outputdevice *o)
109 org_kde_kwin_outputdevice_add_listener(output, &s_outputListener,
this);
112 bool OutputDevice::Mode::operator==(
const OutputDevice::Mode &m)
const
114 return size == m.size && refreshRate == m.refreshRate && flags == m.flags && output == m.output;
117 bool OutputDevice::ColorCurves::operator==(
const OutputDevice::ColorCurves &cc)
const
119 return red == cc.red &&
green == cc.green &&
blue == cc.blue;
121 bool OutputDevice::ColorCurves::operator!=(
const ColorCurves &cc)
const
126 OutputDevice::OutputDevice(
QObject *parent)
128 , d(new Private(this))
132 OutputDevice::~OutputDevice()
137 org_kde_kwin_outputdevice_listener OutputDevice::Private::s_outputListener = {
147 serialNumberCallback,
149 capabilitiesCallback,
154 void OutputDevice::Private::geometryCallback(
void *data,
155 org_kde_kwin_outputdevice *output,
158 int32_t physicalWidth,
159 int32_t physicalHeight,
166 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
167 Q_ASSERT(o->output == output);
168 o->setGlobalPosition(
QPoint(x, y));
169 o->setManufacturer(make);
171 o->setPhysicalSize(
QSize(physicalWidth, physicalHeight));
172 auto toSubPixel = [subPixel]() {
174 case WL_OUTPUT_SUBPIXEL_NONE:
175 return SubPixel::None;
176 case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
177 return SubPixel::HorizontalRGB;
178 case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
179 return SubPixel::HorizontalBGR;
180 case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
181 return SubPixel::VerticalRGB;
182 case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
183 return SubPixel::VerticalBGR;
184 case WL_OUTPUT_SUBPIXEL_UNKNOWN:
186 return SubPixel::Unknown;
189 o->setSubPixel(toSubPixel());
192 case WL_OUTPUT_TRANSFORM_90:
193 return Transform::Rotated90;
194 case WL_OUTPUT_TRANSFORM_180:
195 return Transform::Rotated180;
196 case WL_OUTPUT_TRANSFORM_270:
197 return Transform::Rotated270;
198 case WL_OUTPUT_TRANSFORM_FLIPPED:
199 return Transform::Flipped;
200 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
201 return Transform::Flipped90;
202 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
203 return Transform::Flipped180;
204 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
205 return Transform::Flipped270;
206 case WL_OUTPUT_TRANSFORM_NORMAL:
208 return Transform::Normal;
211 o->setTransform(toTransform());
214 void OutputDevice::Private::modeCallback(
void *data,
215 org_kde_kwin_outputdevice *output,
222 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
223 Q_ASSERT(o->output == output);
224 o->addMode(flags, width, height, refresh, mode_id);
227 void OutputDevice::Private::addMode(uint32_t flags, int32_t width, int32_t height, int32_t refresh, int32_t mode_id)
231 mode.refreshRate = refresh;
232 mode.size =
QSize(width, height);
234 if (flags & WL_OUTPUT_MODE_CURRENT) {
235 mode.flags |= Mode::Flag::Current;
237 if (flags & WL_OUTPUT_MODE_PREFERRED) {
238 mode.flags |= Mode::Flag::Preferred;
241 bool existing =
false;
242 if (flags & WL_OUTPUT_MODE_CURRENT) {
243 auto it = modes.begin();
244 while (it != modes.end()) {
246 if (m.flags.testFlag(Mode::Flag::Current)) {
247 m.flags &= ~
Mode::Flags(Mode::Flag::Current);
248 Q_EMIT q->modeChanged(m);
250 if (m.refreshRate == mode.refreshRate && m.size == mode.size) {
251 it = modes.erase(it);
260 const auto last = modes.insert(modes.end(), mode);
261 if (flags & WL_OUTPUT_MODE_CURRENT) {
266 Q_EMIT q->modeChanged(mode);
268 Q_EMIT q->modeAdded(mode);
272 KWayland::Client::OutputDevice::Mode OutputDevice::currentMode()
const
274 for (
const auto &m :
modes()) {
275 if (m.flags.testFlag(KWayland::Client::OutputDevice::Mode::Flag::Current)) {
279 qCWarning(KWAYLAND_CLIENT) <<
"current mode not found";
283 void OutputDevice::Private::scaleCallback(
void *data, org_kde_kwin_outputdevice *output, int32_t scale)
285 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
286 Q_ASSERT(o->output == output);
290 void OutputDevice::Private::scaleFCallback(
void *data, org_kde_kwin_outputdevice *output, wl_fixed_t scale_fixed)
292 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
293 Q_ASSERT(o->output == output);
294 o->setScale(wl_fixed_to_double(scale_fixed));
297 void OutputDevice::Private::doneCallback(
void *data, org_kde_kwin_outputdevice *output)
299 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
300 Q_ASSERT(o->output == output);
302 Q_EMIT o->q->changed();
306 void OutputDevice::Private::edidCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *raw)
309 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
313 void OutputDevice::Private::enabledCallback(
void *data, org_kde_kwin_outputdevice *output, int32_t enabled)
316 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
318 OutputDevice::Enablement _enabled = OutputDevice::Enablement::Disabled;
319 if (enabled == ORG_KDE_KWIN_OUTPUTDEVICE_ENABLEMENT_ENABLED) {
320 _enabled = OutputDevice::Enablement::Enabled;
322 if (o->enabled != _enabled) {
323 o->enabled = _enabled;
324 Q_EMIT o->q->enabledChanged(o->enabled);
326 Q_EMIT o->q->changed();
331 void OutputDevice::Private::uuidCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *uuid)
334 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
335 if (o->uuid != uuid) {
337 Q_EMIT o->q->uuidChanged(o->uuid);
339 Q_EMIT o->q->changed();
344 void OutputDevice::Private::colorcurvesCallback(
void *data, org_kde_kwin_outputdevice *output, wl_array *red, wl_array *green, wl_array *blue)
347 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
349 auto cc = ColorCurves();
352 destination->resize(curve->size /
sizeof(uint16_t));
353 memcpy(destination->data(), curve->data, curve->size);
355 setCurve(red, &cc.red);
356 setCurve(green, &cc.green);
357 setCurve(blue, &cc.blue);
359 if (o->colorCurves != cc) {
361 Q_EMIT o->q->colorCurvesChanged();
363 Q_EMIT o->q->changed();
368 void OutputDevice::Private::serialNumberCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *raw)
370 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
372 o->setSerialNumber(raw);
375 void OutputDevice::Private::eisaIdCallback(
void *data, org_kde_kwin_outputdevice *output,
const char *raw)
377 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
382 void OutputDevice::Private::capabilitiesCallback(
void *data, org_kde_kwin_outputdevice *output, uint32_t capabilities)
384 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
387 if (o->capabilities != caps) {
388 o->capabilities = caps;
389 Q_EMIT o->q->capabilitiesChanged(caps);
391 Q_EMIT o->q->changed();
396 void OutputDevice::Private::overscanCallback(
void *data, org_kde_kwin_outputdevice *output, uint32_t overscan)
398 auto o =
reinterpret_cast<OutputDevice::Private *
>(data);
400 if (o->overscan != overscan) {
401 o->overscan = overscan;
402 Q_EMIT o->q->overscanChanged(overscan);
404 Q_EMIT o->q->changed();
409 void OutputDevice::Private::vrrPolicyCallback(
void *data, org_kde_kwin_outputdevice *output, uint32_t vrr_policy)
411 auto o =
reinterpret_cast<OutputDevice::Private*
>(data);
413 auto vrrPolicy =
static_cast<VrrPolicy
>(vrr_policy);
414 if (o->vrrPolicy != vrrPolicy) {
415 o->vrrPolicy = vrrPolicy;
416 Q_EMIT o->q->vrrPolicyChanged(vrrPolicy);
418 Q_EMIT o->q->changed();
438 void OutputDevice::Private::setGlobalPosition(
const QPoint &pos)
440 globalPosition = pos;
443 void OutputDevice::Private::setManufacturer(
const QString &m)
448 void OutputDevice::Private::setModel(
const QString &m)
453 void OutputDevice::Private::setSerialNumber(
const QString &sn)
458 void OutputDevice::Private::setEisaId(
const QString &e)
463 void OutputDevice::Private::setPhysicalSize(
const QSize &size)
468 void OutputDevice::Private::setScale(qreal s)
475 if (d->currentMode == d->modes.end()) {
481 void OutputDevice::Private::setSubPixel(OutputDevice::SubPixel s)
486 void OutputDevice::Private::setTransform(OutputDevice::Transform t)
493 return d->globalPosition;
498 return d->manufacturer;
508 return d->serialNumber;
516 org_kde_kwin_outputdevice *OutputDevice::output()
523 return d->physicalSize;
528 if (d->currentMode == d->modes.end()) {
531 return (*d->currentMode).size;
536 if (d->currentMode == d->modes.end()) {
539 return (*d->currentMode).refreshRate;
542 #if KWAYLANDCLIENT_BUILD_DEPRECATED_SINCE(5, 50)
545 return qRound(d->scale);
556 return d->output.isValid();
574 OutputDevice::operator org_kde_kwin_outputdevice *()
579 OutputDevice::operator org_kde_kwin_outputdevice *()
const
601 return d->colorCurves;
606 return d->capabilities;