KWaylandServer

outputdevice_v2_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
3  SPDX-FileCopyrightText: 2021 Méven Car <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 #include "outputdevice_v2_interface.h"
8 
9 #include "display_p.h"
10 #include "display.h"
11 #include "logging.h"
12 #include "utils.h"
13 
14 #include <QDebug>
15 #include <QString>
16 #include <QPointer>
17 
18 #include "qwayland-server-kde-output-device-v2.h"
19 
20 namespace KWaylandServer
21 {
22 
23 static const quint32 s_version = 1;
24 
25 class OutputDeviceV2InterfacePrivate : public QtWaylandServer::kde_output_device_v2
26 {
27 public:
28  OutputDeviceV2InterfacePrivate(OutputDeviceV2Interface *q, Display *display);
29  ~OutputDeviceV2InterfacePrivate() override;
30 
31  void updateGeometry();
32  void updateUuid();
33  void updateEdid();
34  void updateEnabled();
35  void updateScale();
36  void updateEisaId();
37  void updateSerialNumber();
38  void updateCapabilities();
39  void updateOverscan();
40  void updateVrrPolicy();
41  void updateRgbRange();
42 
43  void sendGeometry(Resource *resource);
44  wl_resource *sendNewMode(Resource *resource, OutputDeviceModeV2Interface *mode);
45  void sendCurrentMode(Resource *resource, OutputDeviceModeV2Interface *mode);
46  void sendDone(Resource *resource);
47  void sendUuid(Resource *resource);
48  void sendEdid(Resource *resource);
49  void sendEnabled(Resource *resource);
50  void sendScale(Resource *resource);
51  void sendEisaId(Resource *resource);
52  void sendSerialNumber(Resource *resource);
53  void sendCapabilities(Resource *resource);
54  void sendOverscan(Resource *resource);
55  void sendVrrPolicy(Resource *resource);
56  void sendRgbRange(Resource *resource);
57 
58  QSize physicalSize;
59  QPoint globalPosition;
60  QString manufacturer = QStringLiteral("org.kde.kwin");
61  QString model = QStringLiteral("none");
62  qreal scale = 1.0;
63  QString serialNumber;
64  QString eisaId;
65  OutputDeviceV2Interface::SubPixel subPixel = OutputDeviceV2Interface::SubPixel::Unknown;
66  OutputDeviceV2Interface::Transform transform = OutputDeviceV2Interface::Transform::Normal;
67 
69  OutputDeviceModeV2Interface *currentMode = nullptr;
70 
71  QByteArray edid;
72  bool enabled = true;
73  QUuid uuid;
74  OutputDeviceV2Interface::Capabilities capabilities;
75  uint32_t overscan = 0;
76  OutputDeviceV2Interface::VrrPolicy vrrPolicy = OutputDeviceV2Interface::VrrPolicy::Automatic;
77  OutputDeviceV2Interface::RgbRange rgbRange = OutputDeviceV2Interface::RgbRange::Automatic;
78 
79  QPointer<Display> display;
80  OutputDeviceV2Interface *q;
81 
82 private:
83  int32_t toTransform() const;
84  int32_t toSubPixel() const;
85 
86 protected:
87  void kde_output_device_v2_bind_resource(Resource *resource) override;
88  void kde_output_device_v2_destroy_global() override;
89 };
90 
91 class OutputDeviceModeV2InterfacePrivate : public QtWaylandServer::kde_output_device_mode_v2
92 {
93 public:
94  struct ModeResource : Resource {
95  OutputDeviceV2InterfacePrivate::Resource *output;
96  };
97 
98  OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, const QSize &size, int refreshRate, OutputDeviceModeV2Interface::ModeFlags flags);
99  ~OutputDeviceModeV2InterfacePrivate() override;
100 
101  Resource *createResource(OutputDeviceV2InterfacePrivate::Resource *output);
102  Resource *findResource(OutputDeviceV2InterfacePrivate::Resource *output) const;
103 
104  void bindResource(wl_resource *resource);
105 
106  static OutputDeviceModeV2InterfacePrivate *get(OutputDeviceModeV2Interface *mode) { return mode->d.data(); }
107 
108  OutputDeviceModeV2Interface *q;
109 
110  QSize m_size;
111  int m_refreshRate = 60000;
112  OutputDeviceModeV2Interface::ModeFlags m_flags;
113 
114 protected:
115  Resource *kde_output_device_mode_v2_allocate() override;
116 };
117 
118 OutputDeviceV2InterfacePrivate::OutputDeviceV2InterfacePrivate(OutputDeviceV2Interface *q, Display *display)
119  : QtWaylandServer::kde_output_device_v2(*display, s_version)
120  , display(display)
121  , q(q)
122 {
123  DisplayPrivate *displayPrivate = DisplayPrivate::get(display);
124  displayPrivate->outputdevicesV2.append(q);
125 }
126 
127 OutputDeviceV2InterfacePrivate::~OutputDeviceV2InterfacePrivate()
128 {
129  if (display) {
130  DisplayPrivate *displayPrivate = DisplayPrivate::get(display);
131  displayPrivate->outputdevicesV2.removeOne(q);
132  }
133 }
134 
135 OutputDeviceV2Interface::OutputDeviceV2Interface(Display *display, QObject *parent)
136  : QObject(parent)
137  , d(new OutputDeviceV2InterfacePrivate(this, display))
138 {
139  connect(this, &OutputDeviceV2Interface::subPixelChanged, this, [this] { d->updateGeometry(); });
140  connect(this, &OutputDeviceV2Interface::transformChanged, this, [this] { d->updateGeometry(); });
141  connect(this, &OutputDeviceV2Interface::globalPositionChanged, this, [this] { d->updateGeometry(); });
142  connect(this, &OutputDeviceV2Interface::modelChanged, this, [this] { d->updateGeometry(); });
143  connect(this, &OutputDeviceV2Interface::manufacturerChanged, this, [this] { d->updateGeometry(); });
144  connect(this, &OutputDeviceV2Interface::scaleChanged, this, [this] { d->updateScale(); });
145 }
146 
147 OutputDeviceV2Interface::~OutputDeviceV2Interface()
148 {
149  d->globalRemove();
150 }
151 
152 void OutputDeviceV2Interface::remove()
153 {
154  if (d->isGlobalRemoved()) {
155  return;
156  }
157 
158  if (d->display) {
159  DisplayPrivate *displayPrivate = DisplayPrivate::get(d->display);
160  displayPrivate->outputdevicesV2.removeOne(this);
161  }
162 
163  d->globalRemove();
164 }
165 
166 QSize OutputDeviceV2Interface::pixelSize() const
167 {
168  if (d->currentMode == nullptr) {
169  return QSize();
170  }
171  return d->currentMode->size();
172 }
173 
174 int OutputDeviceV2Interface::refreshRate() const
175 {
176  if (d->currentMode == nullptr) {
177  return 60000;
178  }
179  return d->currentMode->refreshRate();
180 }
181 
182 void OutputDeviceV2Interface::setCurrentMode(OutputDeviceModeV2Interface *mode)
183 {
184  if (mode == d->currentMode) {
185  return;
186  }
187  if (d->currentMode) {
188  // another mode has the current flag - remove
189  d->currentMode->setFlags(d->currentMode->flags() & ~uint(OutputDeviceModeV2Interface::ModeFlag::Current));
190  }
191 
192  mode->setFlags(mode->flags() | OutputDeviceModeV2Interface::ModeFlag::Current);
193  d->currentMode = mode;
194 
195  const auto clientResources = d->resourceMap();
196  for (auto it = clientResources.begin(); it != clientResources.end(); ++it) {
197  auto resource = *it;
198  d->sendCurrentMode(resource, d->currentMode);
199  d->sendDone(resource);
200  }
201 
202  Q_EMIT currentModeChanged();
203 }
204 
205 bool OutputDeviceV2Interface::setCurrentMode(const QSize &size, int refreshRate)
206 {
207  auto mode = std::find_if(d->modes.begin(), d->modes.end(),
208  [size, refreshRate](OutputDeviceModeV2Interface *mode) {
209  return mode->size() == size && mode->refreshRate() == refreshRate;
210  }
211  );
212  if (mode == d->modes.end()) {
213  return false;
214  }
215  setCurrentMode(*mode);
216  return true;
217 }
218 
219 int32_t OutputDeviceV2InterfacePrivate::toTransform() const
220 {
221  switch (transform) {
222  case OutputDeviceV2Interface::Transform::Normal:
223  return WL_OUTPUT_TRANSFORM_NORMAL;
224  case OutputDeviceV2Interface::Transform::Rotated90:
225  return WL_OUTPUT_TRANSFORM_90;
226  case OutputDeviceV2Interface::Transform::Rotated180:
227  return WL_OUTPUT_TRANSFORM_180;
228  case OutputDeviceV2Interface::Transform::Rotated270:
229  return WL_OUTPUT_TRANSFORM_270;
230  case OutputDeviceV2Interface::Transform::Flipped:
231  return WL_OUTPUT_TRANSFORM_FLIPPED;
232  case OutputDeviceV2Interface::Transform::Flipped90:
233  return WL_OUTPUT_TRANSFORM_FLIPPED_90;
234  case OutputDeviceV2Interface::Transform::Flipped180:
235  return WL_OUTPUT_TRANSFORM_FLIPPED_180;
236  case OutputDeviceV2Interface::Transform::Flipped270:
237  return WL_OUTPUT_TRANSFORM_FLIPPED_270;
238  default:
239  Q_UNREACHABLE();
240  }
241 }
242 
243 int32_t OutputDeviceV2InterfacePrivate::toSubPixel() const
244 {
245  switch (subPixel) {
246  case OutputDeviceV2Interface::SubPixel::Unknown:
247  return WL_OUTPUT_SUBPIXEL_UNKNOWN;
248  case OutputDeviceV2Interface::SubPixel::None:
249  return WL_OUTPUT_SUBPIXEL_NONE;
250  case OutputDeviceV2Interface::SubPixel::HorizontalRGB:
251  return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
252  case OutputDeviceV2Interface::SubPixel::HorizontalBGR:
253  return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
254  case OutputDeviceV2Interface::SubPixel::VerticalRGB:
255  return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
256  case OutputDeviceV2Interface::SubPixel::VerticalBGR:
257  return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
258  default:
259  Q_UNREACHABLE();
260  }
261 }
262 
263 void OutputDeviceV2InterfacePrivate::kde_output_device_v2_destroy_global()
264 {
265  delete q;
266 }
267 
268 void OutputDeviceV2InterfacePrivate::kde_output_device_v2_bind_resource(Resource *resource)
269 {
270  sendGeometry(resource);
271  sendScale(resource);
272  sendEisaId(resource);
273  sendSerialNumber(resource);
274 
275  auto currentModeIt = modes.end();
276  for (auto it = modes.begin(); it != modes.end(); ++it) {
277  auto &mode = *it;
278  if (mode->flags().testFlag(OutputDeviceModeV2Interface::ModeFlag::Current)) {
279  // needs to be sent as last mode
280  currentModeIt = it;
281  continue;
282  }
283  sendNewMode(resource, mode);
284  }
285 
286  if (currentModeIt != modes.end()) {
287  auto modeResource = sendNewMode(resource, *currentModeIt);
288  send_current_mode(resource->handle, modeResource);
289  }
290 
291  sendUuid(resource);
292  sendEdid(resource);
293  sendEnabled(resource);
294  sendCapabilities(resource);
295  sendOverscan(resource);
296  sendVrrPolicy(resource);
297  sendRgbRange(resource);
298  sendDone(resource);
299 }
300 
301 wl_resource *OutputDeviceV2InterfacePrivate::sendNewMode(Resource *resource, OutputDeviceModeV2Interface *mode)
302 {
303  auto privateMode = OutputDeviceModeV2InterfacePrivate::get(mode);
304  // bind mode to client
305  const auto modeResource = privateMode->createResource(resource);
306 
307  send_mode(resource->handle, modeResource->handle);
308 
309  privateMode->bindResource(modeResource->handle);
310 
311  return modeResource->handle;
312 }
313 
314 void OutputDeviceV2InterfacePrivate::sendCurrentMode(Resource *outputResource, OutputDeviceModeV2Interface *mode)
315 {
316  const auto modeResource = OutputDeviceModeV2InterfacePrivate::get(mode)->findResource(outputResource);
317  send_current_mode(outputResource->handle, modeResource->handle);
318 }
319 
320 void OutputDeviceV2InterfacePrivate::sendGeometry(Resource *resource)
321 {
322  send_geometry(resource->handle,
323  globalPosition.x(),
324  globalPosition.y(),
325  physicalSize.width(),
326  physicalSize.height(),
327  toSubPixel(),
328  manufacturer,
329  model,
330  toTransform());
331 }
332 
333 void OutputDeviceV2InterfacePrivate::sendScale(Resource *resource)
334 {
335  send_scale(resource->handle, wl_fixed_from_double(scale));
336 }
337 
338 void OutputDeviceV2InterfacePrivate::sendSerialNumber(Resource *resource)
339 {
340  send_serial_number(resource->handle, serialNumber);
341 }
342 
343 void OutputDeviceV2InterfacePrivate::sendEisaId(Resource *resource)
344 {
345  send_eisa_id(resource->handle, eisaId);
346 }
347 
348 void OutputDeviceV2InterfacePrivate::sendDone(Resource *resource)
349 {
350  send_done(resource->handle);
351 }
352 
353 void OutputDeviceV2InterfacePrivate::updateGeometry()
354 {
355  const auto clientResources = resourceMap();
356  for (auto resource : clientResources) {
357  sendGeometry(resource);
358  sendDone(resource);
359  }
360 }
361 
362 void OutputDeviceV2InterfacePrivate::updateScale()
363 {
364  const auto clientResources = resourceMap();
365  for (auto resource : clientResources) {
366  sendScale(resource);
367  sendDone(resource);
368  }
369 }
370 
371 void OutputDeviceV2Interface::setPhysicalSize(const QSize &arg)
372 {
373  if (d->physicalSize == arg) {
374  return;
375  }
376  d->physicalSize = arg;
377  Q_EMIT physicalSizeChanged(d->physicalSize);
378 }
379 
380 void OutputDeviceV2Interface::setGlobalPosition(const QPoint &arg)
381 {
382  if (d->globalPosition == arg) {
383  return;
384  }
385  d->globalPosition = arg;
386  Q_EMIT globalPositionChanged(d->globalPosition);
387 }
388 
389 void OutputDeviceV2Interface::setManufacturer(const QString &arg)
390 {
391  if (d->manufacturer == arg) {
392  return;
393  }
394  d->manufacturer = arg;
395  Q_EMIT manufacturerChanged(d->manufacturer);
396 }
397 
398 void OutputDeviceV2Interface::setModel(const QString &arg)
399 {
400  if (d->model == arg) {
401  return;
402  }
403  d->model = arg;
404  Q_EMIT modelChanged(d->model);
405 }
406 
407 void OutputDeviceV2Interface::setSerialNumber(const QString &arg)
408 {
409  if (d->serialNumber == arg) {
410  return;
411  }
412  d->serialNumber = arg;
413  Q_EMIT serialNumberChanged(d->serialNumber);
414 }
415 
416 void OutputDeviceV2Interface::setEisaId(const QString &arg)
417 {
418  if (d->eisaId == arg) {
419  return;
420  }
421  d->eisaId = arg;
422  Q_EMIT eisaIdChanged(d->eisaId);
423 }
424 
425 void OutputDeviceV2Interface::setSubPixel(SubPixel arg)
426 {
427  if (d->subPixel == arg) {
428  return;
429  }
430  d->subPixel = arg;
431  Q_EMIT subPixelChanged(d->subPixel);
432 }
433 
434 void OutputDeviceV2Interface::setTransform(Transform arg)
435 {
436  if (d->transform == arg) {
437  return;
438  }
439  d->transform = arg;
440  Q_EMIT transformChanged(d->transform);
441 }
442 
443 void OutputDeviceV2Interface::setScale(qreal scale)
444 {
445  if (qFuzzyCompare(d->scale, scale)) {
446  return;
447  }
448  d->scale = scale;
449  Q_EMIT scaleChanged(d->scale);
450 }
451 
452 QSize OutputDeviceV2Interface::physicalSize() const
453 {
454  return d->physicalSize;
455 }
456 
457 QPoint OutputDeviceV2Interface::globalPosition() const
458 {
459  return d->globalPosition;
460 }
461 
462 QString OutputDeviceV2Interface::manufacturer() const
463 {
464  return d->manufacturer;
465 }
466 
467 QString OutputDeviceV2Interface::model() const
468 {
469  return d->model;
470 }
471 
472 QString OutputDeviceV2Interface::serialNumber() const
473 {
474  return d->serialNumber;
475 }
476 
477 QString OutputDeviceV2Interface::eisaId() const
478 {
479  return d->eisaId;
480 }
481 
482 qreal OutputDeviceV2Interface::scale() const
483 {
484  return d->scale;
485 }
486 
487 OutputDeviceV2Interface::SubPixel OutputDeviceV2Interface::subPixel() const
488 {
489  return d->subPixel;
490 }
491 
492 OutputDeviceV2Interface::Transform OutputDeviceV2Interface::transform() const
493 {
494  return d->transform;
495 }
496 
497 void OutputDeviceV2Interface::setModes(const QList<OutputDeviceModeV2Interface *> &modes)
498 {
499  if (modes.isEmpty()) {
500  qCWarning(KWAYLAND_SERVER) << "Tried to set no modes for output";
501  return;
502  }
503 
504  const auto clientResources = d->resourceMap();
505 
506  const auto oldModes = d->modes;
507  d->modes.clear();
508 
509  const auto oldCurrentMode = d->currentMode;
510  d->currentMode = nullptr;
511 
512  for (OutputDeviceModeV2Interface *outputDeviceMode : modes) {
513  d->modes << outputDeviceMode;
514  outputDeviceMode->setParent(this);
515 
516  if (outputDeviceMode->flags().testFlag(OutputDeviceModeV2Interface::ModeFlag::Current)) {
517  d->currentMode = outputDeviceMode;
518  } else {
519  for (auto resource : clientResources) {
520  d->sendNewMode(resource, outputDeviceMode);
521  }
522  }
523  }
524 
525  if (!d->currentMode) {
526  d->currentMode = d->modes.at(0);
527  }
528 
529  for (auto resource : clientResources) {
530  d->sendNewMode(resource, d->currentMode);
531  d->sendCurrentMode(resource, d->currentMode);
532  }
533 
534  qDeleteAll(oldModes.crbegin(), oldModes.crend());
535 
536  for (auto resource : clientResources) {
537  d->sendDone(resource);
538  }
539 
540  if (oldCurrentMode != d->currentMode) {
541  Q_EMIT currentModeChanged();
542  }
543 
544  Q_EMIT modesChanged();
545 }
546 
547 void OutputDeviceV2Interface::setEdid(const QByteArray &edid)
548 {
549  d->edid = edid;
550  d->updateEdid();
551  Q_EMIT edidChanged();
552 }
553 
554 QByteArray OutputDeviceV2Interface::edid() const
555 {
556  return d->edid;
557 }
558 
559 void OutputDeviceV2Interface::setEnabled(bool enabled)
560 {
561  if (d->enabled != enabled) {
562  d->enabled = enabled;
563  d->updateEnabled();
564  Q_EMIT enabledChanged();
565  }
566 }
567 
568 bool OutputDeviceV2Interface::enabled() const
569 {
570  return d->enabled;
571 }
572 
573 void OutputDeviceV2Interface::setUuid(const QUuid &uuid)
574 {
575  if (d->uuid != uuid) {
576  d->uuid = uuid;
577  d->updateUuid();
578  Q_EMIT uuidChanged();
579  }
580 }
581 
582 QUuid OutputDeviceV2Interface::uuid() const
583 {
584  return d->uuid;
585 }
586 
587 void OutputDeviceV2InterfacePrivate::sendEdid(Resource *resource)
588 {
589  send_edid(resource->handle, QString::fromStdString(edid.toBase64().toStdString()));
590 }
591 
592 void OutputDeviceV2InterfacePrivate::sendEnabled(Resource *resource)
593 {
594  send_enabled(resource->handle, enabled);
595 }
596 
597 void OutputDeviceV2InterfacePrivate::sendUuid(Resource *resource)
598 {
599  send_uuid(resource->handle, uuid.toString(QUuid::WithoutBraces));
600 }
601 
602 void OutputDeviceV2InterfacePrivate::updateEnabled()
603 {
604  const auto clientResources = resourceMap();
605  for (auto resource : clientResources) {
606  sendEnabled(resource);
607  sendDone(resource);
608  }
609 }
610 
611 void OutputDeviceV2InterfacePrivate::updateEdid()
612 {
613  const auto clientResources = resourceMap();
614  for (auto resource : clientResources) {
615  sendEdid(resource);
616  sendDone(resource);
617  }
618 }
619 
620 void OutputDeviceV2InterfacePrivate::updateUuid()
621 {
622  const auto clientResources = resourceMap();
623  for (auto resource : clientResources) {
624  sendUuid(resource);
625  sendDone(resource);
626  }
627 }
628 
629 void OutputDeviceV2InterfacePrivate::updateEisaId()
630 {
631  const auto clientResources = resourceMap();
632  for (auto resource : clientResources) {
633  sendEisaId(resource);
634  sendDone(resource);
635  }
636 }
637 
638 uint32_t OutputDeviceV2Interface::overscan() const
639 {
640  return d->overscan;
641 }
642 
643 OutputDeviceV2Interface::Capabilities OutputDeviceV2Interface::capabilities() const
644 {
645  return d->capabilities;
646 }
647 
648 void OutputDeviceV2Interface::setCapabilities(Capabilities cap)
649 {
650  if (d->capabilities != cap) {
651  d->capabilities = cap;
652  d->updateCapabilities();
653  Q_EMIT capabilitiesChanged();
654  }
655 }
656 
657 void OutputDeviceV2InterfacePrivate::sendCapabilities(Resource *resource)
658 {
659  send_capabilities(resource->handle, static_cast<uint32_t>(capabilities));
660 }
661 
662 void OutputDeviceV2InterfacePrivate::updateCapabilities()
663 {
664  const auto clientResources = resourceMap();
665  for (const auto &resource : clientResources) {
666  sendCapabilities(resource);
667  sendDone(resource);
668  }
669 }
670 
671 void OutputDeviceV2Interface::setOverscan(uint32_t overscan)
672 {
673  if (d->overscan != overscan) {
674  d->overscan = overscan;
675  d->updateOverscan();
676  Q_EMIT overscanChanged();
677  }
678 }
679 
680 void OutputDeviceV2InterfacePrivate::sendOverscan(Resource *resource)
681 {
682  send_overscan(resource->handle, static_cast<uint32_t>(overscan));
683 }
684 
685 void OutputDeviceV2InterfacePrivate::updateOverscan()
686 {
687  const auto clientResources = resourceMap();
688  for (const auto &resource : clientResources) {
689  sendOverscan(resource);
690  sendDone(resource);
691  }
692 }
693 
694 void OutputDeviceV2InterfacePrivate::sendVrrPolicy(Resource *resource)
695 {
696  send_vrr_policy(resource->handle, static_cast<uint32_t>(vrrPolicy));
697 }
698 
699 OutputDeviceV2Interface::VrrPolicy OutputDeviceV2Interface::vrrPolicy() const
700 {
701  return d->vrrPolicy;
702 }
703 
704 void OutputDeviceV2Interface::setVrrPolicy(VrrPolicy policy)
705 {
706  if (d->vrrPolicy != policy) {
707  d->vrrPolicy = policy;
708  d->updateVrrPolicy();
709  Q_EMIT vrrPolicyChanged();
710  }
711 }
712 
713 void OutputDeviceV2InterfacePrivate::updateVrrPolicy()
714 {
715  const auto clientResources = resourceMap();
716  for (const auto &resource : clientResources) {
717  sendVrrPolicy(resource);
718  sendDone(resource);
719  }
720 }
721 
722 OutputDeviceV2Interface::RgbRange OutputDeviceV2Interface::rgbRange() const
723 {
724  return d->rgbRange;
725 }
726 
727 void OutputDeviceV2Interface::setRgbRange(RgbRange rgbRange)
728 {
729  if (d->rgbRange != rgbRange) {
730  d->rgbRange = rgbRange;
731  d->updateRgbRange();
732  Q_EMIT rgbRangeChanged();
733  }
734 }
735 
736 void OutputDeviceV2InterfacePrivate::sendRgbRange(Resource *resource)
737 {
738  send_rgb_range(resource->handle, static_cast<uint32_t>(rgbRange));
739 }
740 
741 void OutputDeviceV2InterfacePrivate::updateRgbRange()
742 {
743  const auto clientResources = resourceMap();
744  for (const auto &resource : clientResources) {
745  sendRgbRange(resource);
746  sendDone(resource);
747  }
748 }
749 
750 OutputDeviceV2Interface *OutputDeviceV2Interface::get(wl_resource *native)
751 {
752  if (auto devicePrivate = resource_cast<OutputDeviceV2InterfacePrivate *>(native)) {
753  return devicePrivate->q;
754  }
755  return nullptr;
756 }
757 
758 OutputDeviceModeV2InterfacePrivate::OutputDeviceModeV2InterfacePrivate(OutputDeviceModeV2Interface *q, const QSize &size, int refreshRate, OutputDeviceModeV2Interface::ModeFlags flags)
759  : QtWaylandServer::kde_output_device_mode_v2()
760  , q(q)
761  , m_size(size)
762  , m_refreshRate(refreshRate)
763  , m_flags(flags)
764 {}
765 
766 OutputDeviceModeV2Interface::OutputDeviceModeV2Interface(const QSize &size, int refreshRate, ModeFlags flags, QObject *parent)
767  : QObject(parent)
768  , d(new OutputDeviceModeV2InterfacePrivate(this, size, refreshRate, flags))
769 {}
770 
771 OutputDeviceModeV2Interface::~OutputDeviceModeV2Interface() = default;
772 
773 OutputDeviceModeV2InterfacePrivate::~OutputDeviceModeV2InterfacePrivate()
774 {
775  const auto map = resourceMap();
776  for (Resource *resource : map) {
777  send_removed(resource->handle);
778  }
779 }
780 
781 OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::createResource(OutputDeviceV2InterfacePrivate::Resource *output)
782 {
783  const auto modeResource = static_cast<ModeResource *>(add(output->client(), output->version()));
784  modeResource->output = output;
785  return modeResource;
786 }
787 
788 OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::findResource(OutputDeviceV2InterfacePrivate::Resource *output) const
789 {
790  const auto resources = resourceMap();
791  for (const auto &resource : resources) {
792  auto modeResource = static_cast<ModeResource *>(resource);
793  if (modeResource->output == output) {
794  return resource;
795  }
796  }
797  return nullptr;
798 }
799 
800 OutputDeviceModeV2InterfacePrivate::Resource *OutputDeviceModeV2InterfacePrivate::kde_output_device_mode_v2_allocate()
801 {
802  return new ModeResource;
803 }
804 
805 QSize OutputDeviceModeV2Interface::size() const
806 {
807  return d->m_size;
808 }
809 
810 int OutputDeviceModeV2Interface::refreshRate() const
811 {
812  return d->m_refreshRate;
813 }
814 
815 OutputDeviceModeV2Interface::ModeFlags OutputDeviceModeV2Interface::flags() const
816 {
817  return d->m_flags;
818 }
819 
820 void OutputDeviceModeV2Interface::setFlags(OutputDeviceModeV2Interface::ModeFlags flags)
821 {
822  d->m_flags = flags;
823 }
824 
825 void OutputDeviceModeV2InterfacePrivate::bindResource(wl_resource *resource)
826 {
827  send_size(resource, m_size.width(), m_size.height());
828  send_refresh(resource, m_refreshRate);
829 
830  if (m_flags.testFlag(OutputDeviceModeV2Interface::ModeFlag::Preferred)) {
831  send_preferred(resource);
832  }
833 }
834 
835 OutputDeviceModeV2Interface *OutputDeviceModeV2Interface::get(wl_resource *native)
836 {
837  if (auto devicePrivate = resource_cast<OutputDeviceModeV2InterfacePrivate *>(native)) {
838  return devicePrivate->q;
839  }
840  return nullptr;
841 }
842 
843 }
KDOCTOOLS_EXPORT QString transform(const QString &file, const QString &stylesheet, const QVector< const char * > &params=QVector< const char * >())
std::string toStdString() const const
void clear()
QString fromStdString(const std::string &str)
bool isEmpty() const const
Capabilities capabilities()
Represents an output device, the difference to Output is that this output can be disabled, so not currently used to display content.
QString toString() const const
QByteArray toBase64(QByteArray::Base64Options options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:08:27 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.