Changeset View
Changeset View
Standalone View
Standalone View
src/server/outputdevice_interface.cpp
Show All 18 Lines | |||||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | #include "outputdevice_interface.h" | 20 | #include "outputdevice_interface.h" | ||
21 | #include "global_p.h" | 21 | #include "global_p.h" | ||
22 | #include "display.h" | 22 | #include "display.h" | ||
23 | #include "logging.h" | 23 | #include "logging.h" | ||
24 | 24 | | |||
25 | #include <wayland-server.h> | 25 | #include <wayland-server.h> | ||
26 | #include "wayland-org_kde_kwin_outputdevice-server-protocol.h" | 26 | #include "wayland-org_kde_kwin_outputdevice-server-protocol.h" | ||
27 | #include <QDebug> | | |||
28 | 27 | | |||
29 | namespace KWayland | 28 | namespace KWayland | ||
30 | { | 29 | { | ||
31 | namespace Server | 30 | namespace Server | ||
32 | { | 31 | { | ||
33 | 32 | | |||
34 | class OutputDeviceInterface::Private : public Global::Private | 33 | class OutputDeviceInterface::Private : public Global::Private | ||
35 | { | 34 | { | ||
36 | public: | 35 | public: | ||
37 | struct ResourceData { | 36 | struct ResourceData { | ||
38 | wl_resource *resource; | 37 | wl_resource *resource; | ||
39 | uint32_t version; | 38 | uint32_t version; | ||
40 | }; | 39 | }; | ||
41 | Private(OutputDeviceInterface *q, Display *d); | 40 | Private(OutputDeviceInterface *q, Display *d); | ||
42 | ~Private(); | 41 | ~Private(); | ||
43 | 42 | | |||
44 | | ||||
45 | void updateGeometry(); | 43 | void updateGeometry(); | ||
46 | void updateUuid(); | 44 | void updateUuid(); | ||
47 | void updateEdid(); | 45 | void updateEdid(); | ||
48 | void updateEnabled(); | 46 | void updateEnabled(); | ||
49 | void updateScale(); | 47 | void updateScale(); | ||
48 | void updateCloneGroupId(); | ||||
49 | void updateReplicationSource(); | ||||
50 | void updateColorCurves(); | 50 | void updateColorCurves(); | ||
51 | void updateEisaId(); | 51 | void updateEisaId(); | ||
52 | void updateSerialNumber(); | 52 | void updateSerialNumber(); | ||
53 | 53 | | |||
54 | void sendGeometry(wl_resource *resource); | 54 | void sendGeometry(wl_resource *resource); | ||
55 | void sendMode(wl_resource *resource, const Mode &mode); | 55 | void sendMode(wl_resource *resource, const Mode &mode); | ||
56 | void sendDone(const ResourceData &data); | 56 | void sendDone(const ResourceData &data); | ||
57 | void sendUuid(const ResourceData &data); | 57 | void sendUuid(const ResourceData &data); | ||
58 | void sendEdid(const ResourceData &data); | 58 | void sendEdid(const ResourceData &data); | ||
59 | void sendEnabled(const ResourceData &data); | 59 | void sendEnabled(const ResourceData &data); | ||
60 | void sendScale(const ResourceData &data); | 60 | void sendScale(const ResourceData &data); | ||
61 | void sendColorCurves(const ResourceData &data); | 61 | void sendColorCurves(const ResourceData &data); | ||
62 | void sendCloneGroupId(const ResourceData &data); | ||||
63 | void sendReplicationSource(const ResourceData &data); | ||||
62 | void sendEisaId(const ResourceData &data); | 64 | void sendEisaId(const ResourceData &data); | ||
63 | void sendSerialNumber(const ResourceData &data); | 65 | void sendSerialNumber(const ResourceData &data); | ||
64 | 66 | | |||
67 | void setViewGeometry(const QRect &geo); | ||||
68 | void resetViewGeometry(); | ||||
69 | | ||||
70 | void resetLogicalPosition(); | ||||
71 | void resetLogicalSize(); | ||||
72 | | ||||
73 | void setClientsScale(int scale); | ||||
74 | void resetClientsScale(); | ||||
75 | void addReplica(OutputDeviceInterface *replica); | ||||
76 | void removeReplica(OutputDeviceInterface *replica); | ||||
77 | | ||||
65 | QSize physicalSize; | 78 | QSize physicalSize; | ||
79 | QRect viewGeometry; | ||||
80 | | ||||
66 | QPoint globalPosition; | 81 | QPoint globalPosition; | ||
82 | QPoint logicalPosition; | ||||
83 | QSize globalSize; | ||||
84 | QSize logicalSize; | ||||
85 | | ||||
67 | QString manufacturer = QStringLiteral("org.kde.kwin"); | 86 | QString manufacturer = QStringLiteral("org.kde.kwin"); | ||
68 | QString model = QStringLiteral("none"); | 87 | QString model = QStringLiteral("none"); | ||
69 | qreal scale = 1.0; | 88 | qreal scale = 1.0; | ||
89 | int clientsScale = 1; | ||||
70 | QString serialNumber; | 90 | QString serialNumber; | ||
71 | QString eisaId; | 91 | QString eisaId; | ||
72 | SubPixel subPixel = SubPixel::Unknown; | 92 | SubPixel subPixel = SubPixel::Unknown; | ||
73 | Transform transform = Transform::Normal; | 93 | Transform transform = Transform::Normal; | ||
74 | ColorCurves colorCurves; | 94 | ColorCurves colorCurves; | ||
75 | QList<Mode> modes; | 95 | QList<Mode> modes; | ||
76 | Mode currentMode; | 96 | Mode currentMode; | ||
97 | quint32 cloneGroupId = 0; | ||||
98 | OutputDeviceInterface *replicationSource = nullptr; | ||||
99 | QVector<OutputDeviceInterface*> replicas; | ||||
77 | QList<ResourceData> resources; | 100 | QList<ResourceData> resources; | ||
78 | 101 | | |||
79 | QByteArray edid; | 102 | QByteArray edid; | ||
80 | Enablement enabled = Enablement::Enabled; | 103 | Enablement enabled = Enablement::Enabled; | ||
81 | QByteArray uuid; | 104 | QByteArray uuid; | ||
82 | 105 | | |||
83 | static OutputDeviceInterface *get(wl_resource *native); | 106 | static OutputDeviceInterface *get(wl_resource *native); | ||
84 | 107 | | |||
85 | private: | 108 | private: | ||
86 | static Private *cast(wl_resource *native); | 109 | static Private *cast(wl_resource *native); | ||
87 | static void unbind(wl_resource *resource); | 110 | static void unbind(wl_resource *resource); | ||
88 | void bind(wl_client *client, uint32_t version, uint32_t id) override; | 111 | void bind(wl_client *client, uint32_t version, uint32_t id) override; | ||
89 | int32_t toTransform() const; | 112 | int32_t toTransform() const; | ||
90 | int32_t toSubPixel() const; | 113 | int32_t toSubPixel() const; | ||
91 | 114 | | |||
92 | static const quint32 s_version; | 115 | static const quint32 s_version; | ||
93 | OutputDeviceInterface *q; | 116 | OutputDeviceInterface *q; | ||
94 | static QVector<Private*> s_privates; | 117 | static QVector<Private*> s_privates; | ||
95 | }; | 118 | }; | ||
96 | 119 | | |||
97 | const quint32 OutputDeviceInterface::Private::s_version = 2; | 120 | const quint32 OutputDeviceInterface::Private::s_version = 3; | ||
98 | 121 | | |||
99 | QVector<OutputDeviceInterface::Private*> OutputDeviceInterface::Private::s_privates; | 122 | QVector<OutputDeviceInterface::Private*> OutputDeviceInterface::Private::s_privates; | ||
100 | 123 | | |||
101 | OutputDeviceInterface::Private::Private(OutputDeviceInterface *q, Display *d) | 124 | OutputDeviceInterface::Private::Private(OutputDeviceInterface *q, Display *d) | ||
102 | : Global::Private(d, &org_kde_kwin_outputdevice_interface, s_version) | 125 | : Global::Private(d, &org_kde_kwin_outputdevice_interface, s_version) | ||
103 | , q(q) | 126 | , q(q) | ||
104 | { | 127 | { | ||
105 | s_privates << this; | 128 | s_privates << this; | ||
Show All 40 Lines | 158 | { | |||
146 | ); | 169 | ); | ||
147 | connect(this, &OutputDeviceInterface::subPixelChanged, this, [this, d] { d->updateGeometry(); }); | 170 | connect(this, &OutputDeviceInterface::subPixelChanged, this, [this, d] { d->updateGeometry(); }); | ||
148 | connect(this, &OutputDeviceInterface::transformChanged, this, [this, d] { d->updateGeometry(); }); | 171 | connect(this, &OutputDeviceInterface::transformChanged, this, [this, d] { d->updateGeometry(); }); | ||
149 | connect(this, &OutputDeviceInterface::globalPositionChanged, this, [this, d] { d->updateGeometry(); }); | 172 | connect(this, &OutputDeviceInterface::globalPositionChanged, this, [this, d] { d->updateGeometry(); }); | ||
150 | connect(this, &OutputDeviceInterface::modelChanged, this, [this, d] { d->updateGeometry(); }); | 173 | connect(this, &OutputDeviceInterface::modelChanged, this, [this, d] { d->updateGeometry(); }); | ||
151 | connect(this, &OutputDeviceInterface::manufacturerChanged, this, [this, d] { d->updateGeometry(); }); | 174 | connect(this, &OutputDeviceInterface::manufacturerChanged, this, [this, d] { d->updateGeometry(); }); | ||
152 | connect(this, &OutputDeviceInterface::scaleFChanged, this, [this, d] { d->updateScale(); }); | 175 | connect(this, &OutputDeviceInterface::scaleFChanged, this, [this, d] { d->updateScale(); }); | ||
153 | connect(this, &OutputDeviceInterface::scaleChanged, this, [this, d] { d->updateScale(); }); | 176 | connect(this, &OutputDeviceInterface::scaleChanged, this, [this, d] { d->updateScale(); }); | ||
177 | connect(this, &OutputDeviceInterface::cloneGroupIdChanged, this, [this, d] { d->updateCloneGroupId(); }); | ||||
178 | connect(this, &OutputDeviceInterface::replicationSourceChanged, this, [this, d] { d->updateReplicationSource(); }); | ||||
154 | connect(this, &OutputDeviceInterface::colorCurvesChanged, this, [this, d] { d->updateColorCurves(); }); | 179 | connect(this, &OutputDeviceInterface::colorCurvesChanged, this, [this, d] { d->updateColorCurves(); }); | ||
155 | } | 180 | } | ||
156 | 181 | | |||
157 | OutputDeviceInterface::~OutputDeviceInterface() = default; | 182 | OutputDeviceInterface::~OutputDeviceInterface() = default; | ||
158 | 183 | | |||
159 | QSize OutputDeviceInterface::pixelSize() const | 184 | QSize OutputDeviceInterface::pixelSize() const | ||
160 | { | 185 | { | ||
161 | Q_D(); | 186 | Q_D(); | ||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Line(s) | 244 | return mode.size == mode_it.size && | |||
220 | mode.refreshRate == mode_it.refreshRate && | 245 | mode.refreshRate == mode_it.refreshRate && | ||
221 | mode.id == mode_it.id; | 246 | mode.id == mode_it.id; | ||
222 | } | 247 | } | ||
223 | ); | 248 | ); | ||
224 | auto emitChanges = [this, d, mode] { | 249 | auto emitChanges = [this, d, mode] { | ||
225 | emit modesChanged(); | 250 | emit modesChanged(); | ||
226 | if (mode.flags.testFlag(ModeFlag::Current)) { | 251 | if (mode.flags.testFlag(ModeFlag::Current)) { | ||
227 | d->currentMode = mode; | 252 | d->currentMode = mode; | ||
253 | d->resetLogicalSize(); | ||||
254 | d->resetViewGeometry(); | ||||
228 | emit refreshRateChanged(mode.refreshRate); | 255 | emit refreshRateChanged(mode.refreshRate); | ||
229 | emit pixelSizeChanged(mode.size); | 256 | emit pixelSizeChanged(mode.size); | ||
230 | emit currentModeChanged(); | 257 | emit currentModeChanged(); | ||
231 | } | 258 | } | ||
232 | }; | 259 | }; | ||
233 | if (existingModeIt != d->modes.end()) { | 260 | if (existingModeIt != d->modes.end()) { | ||
234 | if ((*existingModeIt).flags == mode.flags) { | 261 | if ((*existingModeIt).flags == mode.flags) { | ||
235 | // nothing to do | 262 | // nothing to do | ||
Show All 35 Lines | 297 | auto existingModeIt = std::find_if(d->modes.begin(), d->modes.end(), | |||
271 | [modeId](const Mode &mode) { | 298 | [modeId](const Mode &mode) { | ||
272 | return mode.id == modeId; | 299 | return mode.id == modeId; | ||
273 | } | 300 | } | ||
274 | ); | 301 | ); | ||
275 | 302 | | |||
276 | Q_ASSERT(existingModeIt != d->modes.end()); | 303 | Q_ASSERT(existingModeIt != d->modes.end()); | ||
277 | (*existingModeIt).flags |= ModeFlag::Current; | 304 | (*existingModeIt).flags |= ModeFlag::Current; | ||
278 | d->currentMode = *existingModeIt; | 305 | d->currentMode = *existingModeIt; | ||
306 | d->resetLogicalSize(); | ||||
307 | d->resetViewGeometry(); | ||||
279 | emit modesChanged(); | 308 | emit modesChanged(); | ||
280 | emit refreshRateChanged((*existingModeIt).refreshRate); | 309 | emit refreshRateChanged((*existingModeIt).refreshRate); | ||
281 | emit pixelSizeChanged((*existingModeIt).size); | 310 | emit pixelSizeChanged((*existingModeIt).size); | ||
282 | emit currentModeChanged(); | 311 | emit currentModeChanged(); | ||
283 | } | 312 | } | ||
284 | 313 | | |||
314 | void OutputDeviceInterface::setCloneGroupId(const quint32 groupId) | ||||
315 | { | ||||
316 | Q_D(); | ||||
317 | if (d->cloneGroupId == groupId) { | ||||
318 | return; | ||||
319 | } | ||||
320 | d->cloneGroupId = groupId; | ||||
321 | emit cloneGroupIdChanged(groupId); | ||||
322 | } | ||||
323 | | ||||
324 | void OutputDeviceInterface::setReplicationSource(OutputDeviceInterface *source) | ||||
325 | { | ||||
326 | Q_D(); | ||||
327 | if (d->replicationSource == source) { | ||||
328 | return; | ||||
329 | } | ||||
330 | if (source) { | ||||
331 | source->d_func()->addReplica(this); | ||||
332 | } else { | ||||
333 | d->replicationSource->d_func()->removeReplica(this); | ||||
334 | } | ||||
335 | d->replicationSource = source; | ||||
336 | | ||||
337 | d->resetLogicalPosition(); | ||||
338 | d->resetLogicalSize(); | ||||
339 | d->resetViewGeometry(); | ||||
340 | | ||||
341 | emit replicationSourceChanged(source); | ||||
342 | } | ||||
343 | | ||||
285 | int32_t OutputDeviceInterface::Private::toTransform() const | 344 | int32_t OutputDeviceInterface::Private::toTransform() const | ||
286 | { | 345 | { | ||
287 | switch (transform) { | 346 | switch (transform) { | ||
288 | case Transform::Normal: | 347 | case Transform::Normal: | ||
289 | return WL_OUTPUT_TRANSFORM_NORMAL; | 348 | return WL_OUTPUT_TRANSFORM_NORMAL; | ||
290 | case Transform::Rotated90: | 349 | case Transform::Rotated90: | ||
291 | return WL_OUTPUT_TRANSFORM_90; | 350 | return WL_OUTPUT_TRANSFORM_90; | ||
292 | case Transform::Rotated180: | 351 | case Transform::Rotated180: | ||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Line(s) | 387 | { | |||
337 | ResourceData r; | 396 | ResourceData r; | ||
338 | r.resource = resource; | 397 | r.resource = resource; | ||
339 | r.version = version; | 398 | r.version = version; | ||
340 | resources << r; | 399 | resources << r; | ||
341 | 400 | | |||
342 | sendGeometry(resource); | 401 | sendGeometry(resource); | ||
343 | sendScale(r); | 402 | sendScale(r); | ||
344 | sendColorCurves(r); | 403 | sendColorCurves(r); | ||
404 | sendReplicationSource(r); | ||||
345 | sendEisaId(r); | 405 | sendEisaId(r); | ||
346 | sendSerialNumber(r); | 406 | sendSerialNumber(r); | ||
347 | 407 | | |||
348 | auto currentModeIt = modes.constEnd(); | 408 | auto currentModeIt = modes.constEnd(); | ||
349 | for (auto it = modes.constBegin(); it != modes.constEnd(); ++it) { | 409 | for (auto it = modes.constBegin(); it != modes.constEnd(); ++it) { | ||
350 | const Mode &mode = *it; | 410 | const Mode &mode = *it; | ||
351 | if (mode.flags.testFlag(ModeFlag::Current)) { | 411 | if (mode.flags.testFlag(ModeFlag::Current)) { | ||
352 | // needs to be sent as last mode | 412 | // needs to be sent as last mode | ||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Line(s) | 484 | { | |||
440 | 500 | | |||
441 | org_kde_kwin_outputdevice_send_colorcurves(data.resource, &wlRed, &wlGreen, &wlBlue); | 501 | org_kde_kwin_outputdevice_send_colorcurves(data.resource, &wlRed, &wlGreen, &wlBlue); | ||
442 | 502 | | |||
443 | wl_array_release(&wlRed); | 503 | wl_array_release(&wlRed); | ||
444 | wl_array_release(&wlGreen); | 504 | wl_array_release(&wlGreen); | ||
445 | wl_array_release(&wlBlue); | 505 | wl_array_release(&wlBlue); | ||
446 | } | 506 | } | ||
447 | 507 | | |||
508 | void OutputDeviceInterface::Private::sendCloneGroupId(const ResourceData &data) | ||||
509 | { | ||||
510 | if (wl_resource_get_version(data.resource) < ORG_KDE_KWIN_OUTPUTDEVICE_CLONE_SINCE_VERSION) { | ||||
511 | return; | ||||
512 | } | ||||
513 | org_kde_kwin_outputdevice_send_clone(data.resource, cloneGroupId); | ||||
514 | } | ||||
515 | | ||||
516 | void OutputDeviceInterface::Private::sendReplicationSource(const ResourceData &data) | ||||
517 | { | ||||
518 | if (wl_resource_get_version(data.resource) < ORG_KDE_KWIN_OUTPUTDEVICE_REPLICATE_SINCE_VERSION) { | ||||
519 | return; | ||||
520 | } | ||||
521 | org_kde_kwin_outputdevice_send_replicate(data.resource, | ||||
522 | replicationSource ? replicationSource->uuid().constData() : nullptr); | ||||
523 | } | ||||
524 | | ||||
448 | void KWayland::Server::OutputDeviceInterface::Private::sendSerialNumber(const ResourceData &data) | 525 | void KWayland::Server::OutputDeviceInterface::Private::sendSerialNumber(const ResourceData &data) | ||
449 | { | 526 | { | ||
450 | if (wl_resource_get_version(data.resource) >= ORG_KDE_KWIN_OUTPUTDEVICE_SERIAL_NUMBER_SINCE_VERSION) { | 527 | if (wl_resource_get_version(data.resource) >= ORG_KDE_KWIN_OUTPUTDEVICE_SERIAL_NUMBER_SINCE_VERSION) { | ||
451 | org_kde_kwin_outputdevice_send_serial_number(data.resource, | 528 | org_kde_kwin_outputdevice_send_serial_number(data.resource, | ||
452 | qPrintable(serialNumber)); | 529 | qPrintable(serialNumber)); | ||
453 | } | 530 | } | ||
454 | } | 531 | } | ||
455 | 532 | | |||
Show All 22 Lines | |||||
478 | void OutputDeviceInterface::Private::updateScale() | 555 | void OutputDeviceInterface::Private::updateScale() | ||
479 | { | 556 | { | ||
480 | for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { | 557 | for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { | ||
481 | sendScale(*it); | 558 | sendScale(*it); | ||
482 | sendDone(*it); | 559 | sendDone(*it); | ||
483 | } | 560 | } | ||
484 | } | 561 | } | ||
485 | 562 | | |||
563 | void OutputDeviceInterface::Private::updateCloneGroupId() | ||||
564 | { | ||||
565 | for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { | ||||
566 | sendCloneGroupId(*it); | ||||
567 | sendDone(*it); | ||||
568 | } | ||||
569 | } | ||||
570 | | ||||
571 | void OutputDeviceInterface::Private::updateReplicationSource() | ||||
572 | { | ||||
573 | for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { | ||||
574 | sendReplicationSource(*it); | ||||
575 | sendDone(*it); | ||||
576 | } | ||||
577 | } | ||||
578 | | ||||
486 | void OutputDeviceInterface::Private::updateColorCurves() | 579 | void OutputDeviceInterface::Private::updateColorCurves() | ||
487 | { | 580 | { | ||
488 | for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { | 581 | for (auto it = resources.constBegin(); it != resources.constEnd(); ++it) { | ||
489 | sendColorCurves(*it); | 582 | sendColorCurves(*it); | ||
490 | sendDone(*it); | 583 | sendDone(*it); | ||
491 | } | 584 | } | ||
492 | } | 585 | } | ||
493 | 586 | | |||
587 | void OutputDeviceInterface::Private::setViewGeometry(const QRect &geo) | ||||
588 | { | ||||
589 | if (viewGeometry == geo) { | ||||
590 | return; | ||||
591 | } | ||||
592 | viewGeometry = geo; | ||||
593 | resetClientsScale(); | ||||
594 | emit q->viewGeometryChanged(geo); | ||||
595 | } | ||||
596 | | ||||
597 | void OutputDeviceInterface::Private::resetViewGeometry() | ||||
598 | { | ||||
599 | if (!replicationSource) { | ||||
600 | setViewGeometry(QRect(QPoint(0, 0), q->pixelSize())); | ||||
601 | return; | ||||
602 | } | ||||
603 | | ||||
604 | // Fit view into output mode keeping the aspect ratio. | ||||
605 | const QSize modeSize = q->pixelSize(); | ||||
606 | const QSize sourceSize = replicationSource->pixelSize(); | ||||
607 | | ||||
608 | QSize viewSize; | ||||
609 | viewSize.setWidth(modeSize.width()); | ||||
610 | viewSize.setHeight(viewSize.width() * sourceSize.height() / (double)sourceSize.width()); | ||||
611 | | ||||
612 | if (viewSize.height() > modeSize.height()) { | ||||
613 | const QSize oldSize = viewSize; | ||||
614 | viewSize.setHeight(modeSize.height()); | ||||
615 | viewSize.setWidth(oldSize.width() * viewSize.height() / (double)oldSize.height()); | ||||
616 | } | ||||
617 | | ||||
618 | Q_ASSERT(viewSize.height() <= modeSize.height()); | ||||
619 | Q_ASSERT(viewSize.width() <= modeSize.width()); | ||||
620 | | ||||
621 | const QPoint pos((modeSize.width() - viewSize.width()) / 2, | ||||
622 | (modeSize.height() - viewSize.height()) / 2); | ||||
623 | | ||||
624 | setViewGeometry(QRect(pos, viewSize)); | ||||
625 | } | ||||
626 | | ||||
627 | void OutputDeviceInterface::Private::resetLogicalPosition() | ||||
628 | { | ||||
629 | const QPoint pos = replicationSource ? replicationSource->d_func()->logicalPosition : | ||||
630 | globalPosition; | ||||
631 | if (logicalPosition == pos) { | ||||
632 | return; | ||||
633 | } | ||||
634 | logicalPosition = pos; | ||||
635 | for (auto *replica : replicas) { | ||||
636 | replica->d_func()->resetLogicalPosition(); | ||||
637 | } | ||||
638 | emit q->logicalPositionChanged(pos); | ||||
639 | } | ||||
640 | | ||||
641 | void OutputDeviceInterface::Private::resetLogicalSize() | ||||
642 | { | ||||
643 | const QSize size = replicationSource ? replicationSource->d_func()->logicalSize : | ||||
644 | q->pixelSize() / scale; | ||||
645 | if (logicalSize == size) { | ||||
646 | return; | ||||
647 | } | ||||
648 | logicalSize = size; | ||||
649 | for (auto *replica : replicas) { | ||||
650 | replica->d_func()->resetLogicalSize(); | ||||
651 | } | ||||
652 | emit q->logicalSizeChanged(size); | ||||
653 | } | ||||
654 | | ||||
655 | void OutputDeviceInterface::Private::addReplica(OutputDeviceInterface *replica) | ||||
656 | { | ||||
657 | replicas << replica; | ||||
658 | resetClientsScale(); | ||||
659 | } | ||||
660 | | ||||
661 | void OutputDeviceInterface::Private::removeReplica(OutputDeviceInterface *replica) | ||||
662 | { | ||||
663 | replicas.removeOne(replica); | ||||
664 | resetClientsScale(); | ||||
665 | } | ||||
666 | | ||||
667 | void OutputDeviceInterface::Private::setClientsScale(int scale) | ||||
668 | { | ||||
669 | if (clientsScale == scale) { | ||||
670 | return; | ||||
671 | } | ||||
672 | clientsScale = scale; | ||||
673 | for (auto *replica : replicas) { | ||||
674 | replica->d_func()->setClientsScale(scale); | ||||
675 | } | ||||
676 | resetLogicalSize(); | ||||
677 | emit q->clientsScaleChanged(scale); | ||||
678 | } | ||||
679 | | ||||
680 | void OutputDeviceInterface::Private::resetClientsScale() | ||||
681 | { | ||||
682 | if (replicationSource) { | ||||
683 | // The clients scale is set on the replication source. | ||||
684 | setClientsScale(replicationSource->clientsScale()); | ||||
685 | return; | ||||
686 | } | ||||
687 | | ||||
688 | const QSize size = q->viewGeometry().size(); | ||||
689 | | ||||
690 | int maxWidth = size.width(); | ||||
691 | int maxHeight = size.height(); | ||||
692 | for (auto *replica : replicas) { | ||||
693 | const QSize replicaSize = replica->viewGeometry().size(); | ||||
694 | maxWidth = qMax(replicaSize.width(), maxWidth); | ||||
695 | maxHeight = qMax(replicaSize.height(), maxHeight); | ||||
696 | } | ||||
697 | | ||||
698 | if (size.width() == maxWidth && size.height() == maxHeight) { | ||||
699 | setClientsScale(std::ceil(scale)); | ||||
700 | return; | ||||
701 | } | ||||
702 | | ||||
703 | qreal factor = qMax(maxWidth / (qreal)size.width(), maxHeight / (qreal)size.height()); | ||||
704 | setClientsScale(std::ceil(factor)); | ||||
705 | } | ||||
706 | | ||||
494 | bool OutputDeviceInterface::ColorCurves::operator==(const ColorCurves &cc) const | 707 | bool OutputDeviceInterface::ColorCurves::operator==(const ColorCurves &cc) const | ||
495 | { | 708 | { | ||
496 | return red == cc.red && green == cc.green && blue == cc.blue; | 709 | return red == cc.red && green == cc.green && blue == cc.blue; | ||
497 | } | 710 | } | ||
498 | bool OutputDeviceInterface::ColorCurves::operator!=(const ColorCurves &cc) const { | 711 | bool OutputDeviceInterface::ColorCurves::operator!=(const ColorCurves &cc) const { | ||
499 | return !operator==(cc); | 712 | return !operator==(cc); | ||
500 | } | 713 | } | ||
501 | 714 | | |||
502 | #define SETTER(setterName, type, argumentName) \ | 715 | #define SETTER(setterName, type, argumentName) \ | ||
503 | void OutputDeviceInterface::setterName(type arg) \ | 716 | void OutputDeviceInterface::setterName(type arg) \ | ||
504 | { \ | 717 | { \ | ||
505 | Q_D(); \ | 718 | Q_D(); \ | ||
506 | if (d->argumentName == arg) { \ | 719 | if (d->argumentName == arg) { \ | ||
507 | return; \ | 720 | return; \ | ||
508 | } \ | 721 | } \ | ||
509 | d->argumentName = arg; \ | 722 | d->argumentName = arg; \ | ||
510 | emit argumentName##Changed(d->argumentName); \ | 723 | emit argumentName##Changed(d->argumentName); \ | ||
511 | } | 724 | } | ||
512 | 725 | | |||
513 | SETTER(setPhysicalSize, const QSize&, physicalSize) | 726 | SETTER(setPhysicalSize, const QSize&, physicalSize) | ||
514 | SETTER(setGlobalPosition, const QPoint&, globalPosition) | | |||
515 | SETTER(setManufacturer, const QString&, manufacturer) | 727 | SETTER(setManufacturer, const QString&, manufacturer) | ||
516 | SETTER(setModel, const QString&, model) | 728 | SETTER(setModel, const QString&, model) | ||
517 | SETTER(setSerialNumber, const QString&, serialNumber) | 729 | SETTER(setSerialNumber, const QString&, serialNumber) | ||
518 | SETTER(setEisaId, const QString&, eisaId) | 730 | SETTER(setEisaId, const QString&, eisaId) | ||
519 | SETTER(setSubPixel, SubPixel, subPixel) | 731 | SETTER(setSubPixel, SubPixel, subPixel) | ||
520 | SETTER(setTransform, Transform, transform) | 732 | SETTER(setTransform, Transform, transform) | ||
521 | 733 | | |||
522 | #undef SETTER | 734 | #undef SETTER | ||
523 | 735 | | |||
736 | void OutputDeviceInterface::setGlobalPosition(const QPoint& pos) \ | ||||
737 | { | ||||
738 | Q_D(); | ||||
739 | if (d->globalPosition == pos) { | ||||
740 | return; | ||||
741 | } | ||||
742 | d->globalPosition = pos; | ||||
743 | for (auto *replica : d->replicas) { | ||||
744 | replica->d_func()->resetLogicalPosition(); | ||||
745 | } | ||||
746 | d->resetLogicalPosition(); | ||||
747 | emit globalPositionChanged(pos); | ||||
748 | } | ||||
749 | | ||||
524 | void OutputDeviceInterface::setScale(int scale) | 750 | void OutputDeviceInterface::setScale(int scale) | ||
525 | { | 751 | { | ||
526 | Q_D(); | 752 | Q_D(); | ||
527 | if (d->scale == scale) { | 753 | if (d->scale == scale) { | ||
528 | return; | 754 | return; | ||
529 | } | 755 | } | ||
530 | d->scale = scale; | 756 | d->scale = scale; | ||
757 | d->resetClientsScale(); | ||||
531 | emit scaleChanged(d->scale); | 758 | emit scaleChanged(d->scale); | ||
532 | emit scaleFChanged(d->scale); | 759 | emit scaleFChanged(d->scale); | ||
533 | } | 760 | } | ||
534 | 761 | | |||
535 | void OutputDeviceInterface::setScaleF(qreal scale) | 762 | void OutputDeviceInterface::setScaleF(qreal scale) | ||
536 | { | 763 | { | ||
537 | Q_D(); | 764 | Q_D(); | ||
538 | if (qFuzzyCompare(d->scale, scale)) { | 765 | if (qFuzzyCompare(d->scale, scale)) { | ||
539 | return; | 766 | return; | ||
540 | } | 767 | } | ||
541 | d->scale = scale; | 768 | d->scale = scale; | ||
769 | d->resetClientsScale(); | ||||
542 | emit scaleChanged(qRound(d->scale)); | 770 | emit scaleChanged(qRound(d->scale)); | ||
543 | emit scaleFChanged(d->scale); | 771 | emit scaleFChanged(d->scale); | ||
544 | } | 772 | } | ||
545 | 773 | | |||
546 | QSize OutputDeviceInterface::physicalSize() const | 774 | QSize OutputDeviceInterface::physicalSize() const | ||
547 | { | 775 | { | ||
548 | Q_D(); | 776 | Q_D(); | ||
549 | return d->physicalSize; | 777 | return d->physicalSize; | ||
550 | } | 778 | } | ||
551 | 779 | | |||
552 | QPoint OutputDeviceInterface::globalPosition() const | 780 | QPoint OutputDeviceInterface::globalPosition() const | ||
553 | { | 781 | { | ||
554 | Q_D(); | 782 | Q_D(); | ||
555 | return d->globalPosition; | 783 | return d->globalPosition; | ||
556 | } | 784 | } | ||
557 | 785 | | |||
786 | QPoint OutputDeviceInterface::logicalPosition() const | ||||
787 | { | ||||
788 | Q_D(); | ||||
789 | return d->logicalPosition; | ||||
790 | } | ||||
791 | | ||||
792 | QSize OutputDeviceInterface::logicalSize() const | ||||
793 | { | ||||
794 | Q_D(); | ||||
795 | return d->logicalSize; | ||||
796 | } | ||||
797 | | ||||
798 | QRect OutputDeviceInterface::viewGeometry() const | ||||
799 | { | ||||
800 | Q_D(); | ||||
801 | return d->viewGeometry; | ||||
802 | } | ||||
803 | | ||||
558 | QString OutputDeviceInterface::manufacturer() const | 804 | QString OutputDeviceInterface::manufacturer() const | ||
559 | { | 805 | { | ||
560 | Q_D(); | 806 | Q_D(); | ||
561 | return d->manufacturer; | 807 | return d->manufacturer; | ||
562 | } | 808 | } | ||
563 | 809 | | |||
564 | QString OutputDeviceInterface::model() const | 810 | QString OutputDeviceInterface::model() const | ||
565 | { | 811 | { | ||
566 | Q_D(); | 812 | Q_D(); | ||
567 | return d->model; | 813 | return d->model; | ||
568 | } | 814 | } | ||
569 | 815 | | |||
816 | quint32 OutputDeviceInterface::cloneGroupId() const | ||||
817 | { | ||||
818 | Q_D(); | ||||
819 | return d->cloneGroupId; | ||||
820 | } | ||||
821 | | ||||
822 | OutputDeviceInterface* OutputDeviceInterface::replicationSource() const | ||||
823 | { | ||||
824 | Q_D(); | ||||
825 | return d->replicationSource; | ||||
826 | } | ||||
827 | | ||||
570 | QString OutputDeviceInterface::serialNumber() const | 828 | QString OutputDeviceInterface::serialNumber() const | ||
571 | { | 829 | { | ||
572 | Q_D(); | 830 | Q_D(); | ||
573 | return d->serialNumber; | 831 | return d->serialNumber; | ||
574 | } | 832 | } | ||
575 | 833 | | |||
576 | QString OutputDeviceInterface::eisaId() const | 834 | QString OutputDeviceInterface::eisaId() const | ||
577 | { | 835 | { | ||
578 | Q_D(); | 836 | Q_D(); | ||
579 | return d->eisaId; | 837 | return d->eisaId; | ||
580 | } | 838 | } | ||
581 | 839 | | |||
582 | int OutputDeviceInterface::scale() const | 840 | int OutputDeviceInterface::scale() const | ||
583 | { | 841 | { | ||
584 | Q_D(); | 842 | Q_D(); | ||
585 | return qRound(d->scale); | 843 | return qRound(d->scale); | ||
586 | } | 844 | } | ||
587 | 845 | | |||
588 | qreal OutputDeviceInterface::scaleF() const | 846 | qreal OutputDeviceInterface::scaleF() const | ||
589 | { | 847 | { | ||
590 | Q_D(); | 848 | Q_D(); | ||
591 | return d->scale; | 849 | return d->scale; | ||
592 | } | 850 | } | ||
593 | 851 | | |||
852 | int OutputDeviceInterface::clientsScale() const | ||||
853 | { | ||||
854 | Q_D(); | ||||
855 | return d->clientsScale; | ||||
856 | } | ||||
594 | 857 | | |||
595 | OutputDeviceInterface::SubPixel OutputDeviceInterface::subPixel() const | 858 | OutputDeviceInterface::SubPixel OutputDeviceInterface::subPixel() const | ||
596 | { | 859 | { | ||
597 | Q_D(); | 860 | Q_D(); | ||
598 | return d->subPixel; | 861 | return d->subPixel; | ||
599 | } | 862 | } | ||
600 | 863 | | |||
601 | OutputDeviceInterface::Transform OutputDeviceInterface::transform() const | 864 | OutputDeviceInterface::Transform OutputDeviceInterface::transform() const | ||
▲ Show 20 Lines • Show All 141 Lines • Show Last 20 Lines |