Changeset View
Standalone View
src/server/surface_interface.cpp
Show All 22 Lines | |||||
23 | #include "clientconnection.h" | 23 | #include "clientconnection.h" | ||
24 | #include "compositor_interface.h" | 24 | #include "compositor_interface.h" | ||
25 | #include "idleinhibit_interface_p.h" | 25 | #include "idleinhibit_interface_p.h" | ||
26 | #include "pointerconstraints_interface_p.h" | 26 | #include "pointerconstraints_interface_p.h" | ||
27 | #include "region_interface.h" | 27 | #include "region_interface.h" | ||
28 | #include "subcompositor_interface.h" | 28 | #include "subcompositor_interface.h" | ||
29 | #include "subsurface_interface_p.h" | 29 | #include "subsurface_interface_p.h" | ||
30 | #include "surfacerole_p.h" | 30 | #include "surfacerole_p.h" | ||
31 | #include "viewporter_interface.h" | ||||
32 | | ||||
33 | #include <wayland-viewporter-server-protocol.h> | ||||
31 | // Qt | 34 | // Qt | ||
32 | #include <QListIterator> | 35 | #include <QListIterator> | ||
36 | | ||||
33 | // Wayland | 37 | // Wayland | ||
34 | #include <wayland-server.h> | 38 | #include <wayland-server.h> | ||
35 | // std | 39 | // std | ||
36 | #include <algorithm> | 40 | #include <algorithm> | ||
37 | 41 | | |||
38 | namespace KWayland | 42 | namespace KWayland | ||
39 | { | 43 | { | ||
40 | namespace Server | 44 | namespace Server | ||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Line(s) | |||||
172 | } | 176 | } | ||
173 | 177 | | |||
174 | void SurfaceInterface::Private::setContrast(const QPointer<ContrastInterface> &contrast) | 178 | void SurfaceInterface::Private::setContrast(const QPointer<ContrastInterface> &contrast) | ||
175 | { | 179 | { | ||
176 | pending.contrast = contrast; | 180 | pending.contrast = contrast; | ||
177 | pending.contrastIsSet = true; | 181 | pending.contrastIsSet = true; | ||
178 | } | 182 | } | ||
179 | 183 | | |||
184 | void SurfaceInterface::Private::setSourceRectangle(const QRectF &source) | ||||
185 | { | ||||
186 | pending.sourceRectangle = source; | ||||
187 | pending.sourceRectangleIsSet = true; | ||||
188 | } | ||||
189 | | ||||
190 | void SurfaceInterface::Private::setDestinationSize(const QSize &dest) | ||||
191 | { | ||||
192 | pending.destinationSize = dest; | ||||
193 | pending.destinationSizeIsSet = true; | ||||
194 | } | ||||
195 | | ||||
196 | void SurfaceInterface::Private::installViewport(ViewportInterface *vp) | ||||
197 | { | ||||
198 | Q_ASSERT(viewport.isNull()); | ||||
199 | viewport = QPointer<ViewportInterface>(vp); | ||||
200 | connect(viewport, &ViewportInterface::destinationSizeSet, q_func(), | ||||
201 | [this](const QSize &size) { | ||||
202 | setDestinationSize(size); | ||||
203 | } | ||||
204 | ); | ||||
205 | connect(viewport, &ViewportInterface::sourceRectangleSet, q_func(), | ||||
206 | [this](const QRectF &rect) { | ||||
207 | setSourceRectangle(rect); | ||||
208 | } | ||||
209 | ); | ||||
210 | connect(viewport, &ViewportInterface::unbound, q_func(), | ||||
211 | [this] { | ||||
212 | setDestinationSize(QSize()); | ||||
213 | setSourceRectangle(QRectF()); | ||||
214 | } | ||||
215 | ); | ||||
216 | } | ||||
217 | | ||||
180 | void SurfaceInterface::Private::installPointerConstraint(LockedPointerInterface *lock) | 218 | void SurfaceInterface::Private::installPointerConstraint(LockedPointerInterface *lock) | ||
181 | { | 219 | { | ||
182 | Q_ASSERT(lockedPointer.isNull()); | 220 | Q_ASSERT(lockedPointer.isNull()); | ||
183 | Q_ASSERT(confinedPointer.isNull()); | 221 | Q_ASSERT(confinedPointer.isNull()); | ||
184 | lockedPointer = QPointer<LockedPointerInterface>(lock); | 222 | lockedPointer = QPointer<LockedPointerInterface>(lock); | ||
185 | 223 | | |||
186 | auto cleanUp = [this]() { | 224 | auto cleanUp = [this]() { | ||
187 | lockedPointer.clear(); | 225 | lockedPointer.clear(); | ||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Line(s) | 371 | { | |||
336 | const bool opaqueRegionChanged = source->opaqueIsSet; | 374 | const bool opaqueRegionChanged = source->opaqueIsSet; | ||
337 | const bool inputRegionChanged = source->inputIsSet; | 375 | const bool inputRegionChanged = source->inputIsSet; | ||
338 | const bool scaleFactorChanged = source->scaleIsSet && (target->scale != source->scale); | 376 | const bool scaleFactorChanged = source->scaleIsSet && (target->scale != source->scale); | ||
339 | const bool transformChanged = source->transformIsSet && (target->transform != source->transform); | 377 | const bool transformChanged = source->transformIsSet && (target->transform != source->transform); | ||
340 | const bool shadowChanged = source->shadowIsSet; | 378 | const bool shadowChanged = source->shadowIsSet; | ||
341 | const bool blurChanged = source->blurIsSet; | 379 | const bool blurChanged = source->blurIsSet; | ||
342 | const bool contrastChanged = source->contrastIsSet; | 380 | const bool contrastChanged = source->contrastIsSet; | ||
343 | const bool slideChanged = source->slideIsSet; | 381 | const bool slideChanged = source->slideIsSet; | ||
382 | const bool sourceRectangleChanged = source->sourceRectangleIsSet; | ||||
383 | const bool destinationSizeChanged = source->destinationSizeIsSet; | ||||
344 | const bool childrenChanged = source->childrenChanged; | 384 | const bool childrenChanged = source->childrenChanged; | ||
345 | bool sizeChanged = false; | 385 | bool sizeChanged = false; | ||
346 | auto buffer = target->buffer; | 386 | auto buffer = target->buffer; | ||
347 | if (bufferChanged) { | 387 | if (bufferChanged) { | ||
348 | // TODO: is the reffing correct for subsurfaces? | 388 | // TODO: is the reffing correct for subsurfaces? | ||
349 | QSize oldSize; | 389 | QSize oldSize; | ||
350 | if (target->buffer) { | 390 | if (target->buffer) { | ||
351 | oldSize = target->buffer->size(); | 391 | oldSize = target->buffer->size(); | ||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | |||||
412 | if (scaleFactorChanged) { | 452 | if (scaleFactorChanged) { | ||
413 | target->scale = source->scale; | 453 | target->scale = source->scale; | ||
414 | target->scaleIsSet = true; | 454 | target->scaleIsSet = true; | ||
415 | } | 455 | } | ||
416 | if (transformChanged) { | 456 | if (transformChanged) { | ||
417 | target->transform = source->transform; | 457 | target->transform = source->transform; | ||
418 | target->transformIsSet = true; | 458 | target->transformIsSet = true; | ||
419 | } | 459 | } | ||
460 | if (destinationSizeChanged) { | ||||
461 | target->destinationSize = source->destinationSize; | ||||
462 | target->destinationSizeIsSet = true; | ||||
463 | | ||||
464 | sizeChanged |= (bool)buffer; | ||||
davidedmundson: C-style casts are frowned upon. | |||||
465 | } | ||||
466 | if (sourceRectangleChanged) { | ||||
467 | if (!target->destinationSize.isValid() && source->sourceRectangle.isValid()) { | ||||
468 | // Check on size being integer-valued. | ||||
469 | const double width = source->sourceRectangle.width(); | ||||
470 | const double height = source->sourceRectangle.height(); | ||||
471 | if (!qFuzzyCompare(width, (int)width) || !qFuzzyCompare(height, (int)height)) { | ||||
472 | wl_resource_post_error(viewport->parentResource(), WP_VIEWPORT_ERROR_BAD_SIZE, | ||||
473 | "Source rectangle not integer valued"); | ||||
474 | } | ||||
475 | if (buffer) { | ||||
476 | QSizeF bufferSize = buffer->size() / target->scale; | ||||
477 | | ||||
478 | if (target->transform == OutputInterface::Transform::Rotated90 || | ||||
479 | target->transform == OutputInterface::Transform::Rotated270 || | ||||
480 | target->transform == OutputInterface::Transform::Flipped90 || | ||||
481 | target->transform == OutputInterface::Transform::Flipped270) { | ||||
482 | bufferSize.transpose(); | ||||
483 | } | ||||
484 | if (!QRectF(QPointF(), bufferSize).contains(source->sourceRectangle)) { | ||||
485 | wl_resource_post_error(viewport->parentResource(), | ||||
We're not testing this error in the case of: buffer is set then later this should be an error too. davidedmundson: We're not testing this error in the case of:
buffer is set
viewporter.sourceRect is set
then… | |||||
Good point. Same should be done for when the transform or scale changes. romangg: Good point. Same should be done for when the transform or scale changes. | |||||
486 | WP_VIEWPORT_ERROR_OUT_OF_BUFFER, | ||||
487 | "Source rectangle not contained in buffer"); | ||||
488 | } | ||||
489 | // TODO: We should make this dependent on the previous size being different. | ||||
490 | // But looking at above sizeChanged calculation when setting the buffer | ||||
491 | // we need to do fix this there as well (does not look at buffer transform | ||||
492 | // and destination size). | ||||
493 | sizeChanged = true; | ||||
494 | } | ||||
495 | } | ||||
496 | target->sourceRectangle = source->sourceRectangle; | ||||
497 | target->sourceRectangleIsSet = true; | ||||
498 | } | ||||
420 | if (!lockedPointer.isNull()) { | 499 | if (!lockedPointer.isNull()) { | ||
421 | lockedPointer->d_func()->commit(); | 500 | lockedPointer->d_func()->commit(); | ||
422 | } | 501 | } | ||
423 | if (!confinedPointer.isNull()) { | 502 | if (!confinedPointer.isNull()) { | ||
424 | confinedPointer->d_func()->commit(); | 503 | confinedPointer->d_func()->commit(); | ||
425 | } | 504 | } | ||
426 | 505 | | |||
427 | *source = State{}; | 506 | *source = State{}; | ||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Line(s) | 578 | if (blurChanged) { | |||
500 | emit q->blurChanged(); | 579 | emit q->blurChanged(); | ||
501 | } | 580 | } | ||
502 | if (contrastChanged) { | 581 | if (contrastChanged) { | ||
503 | emit q->contrastChanged(); | 582 | emit q->contrastChanged(); | ||
504 | } | 583 | } | ||
505 | if (slideChanged) { | 584 | if (slideChanged) { | ||
506 | emit q->slideOnShowHideChanged(); | 585 | emit q->slideOnShowHideChanged(); | ||
507 | } | 586 | } | ||
587 | if (sourceRectangleChanged) { | ||||
588 | emit q->sourceRectangleChanged(); | ||||
589 | } | ||||
508 | if (childrenChanged) { | 590 | if (childrenChanged) { | ||
509 | emit q->subSurfaceTreeChanged(); | 591 | emit q->subSurfaceTreeChanged(); | ||
510 | } | 592 | } | ||
511 | } | 593 | } | ||
512 | 594 | | |||
513 | void SurfaceInterface::Private::commit() | 595 | void SurfaceInterface::Private::commit() | ||
514 | { | 596 | { | ||
515 | Q_Q(SurfaceInterface); | 597 | Q_Q(SurfaceInterface); | ||
▲ Show 20 Lines • Show All 226 Lines • ▼ Show 20 Line(s) | |||||
742 | } | 824 | } | ||
743 | 825 | | |||
744 | BufferInterface *SurfaceInterface::buffer() | 826 | BufferInterface *SurfaceInterface::buffer() | ||
745 | { | 827 | { | ||
746 | Q_D(); | 828 | Q_D(); | ||
747 | return d->current.buffer; | 829 | return d->current.buffer; | ||
748 | } | 830 | } | ||
749 | 831 | | |||
832 | BufferInterface *SurfaceInterface::constBuffer() const | ||||
833 | { | ||||
834 | Q_D(); | ||||
835 | return d->current.buffer; | ||||
836 | } | ||||
837 | | ||||
750 | QPoint SurfaceInterface::offset() const | 838 | QPoint SurfaceInterface::offset() const | ||
751 | { | 839 | { | ||
752 | Q_D(); | 840 | Q_D(); | ||
753 | return d->current.offset; | 841 | return d->current.offset; | ||
754 | } | 842 | } | ||
755 | 843 | | |||
844 | QRectF SurfaceInterface::sourceRectangle() const | ||||
845 | { | ||||
846 | Q_D(); | ||||
847 | return d->current.sourceRectangle; | ||||
848 | } | ||||
849 | | ||||
756 | SurfaceInterface *SurfaceInterface::get(wl_resource *native) | 850 | SurfaceInterface *SurfaceInterface::get(wl_resource *native) | ||
757 | { | 851 | { | ||
758 | return Private::get<SurfaceInterface>(native); | 852 | return Private::get<SurfaceInterface>(native); | ||
759 | } | 853 | } | ||
760 | 854 | | |||
761 | SurfaceInterface *SurfaceInterface::get(quint32 id, const ClientConnection *client) | 855 | SurfaceInterface *SurfaceInterface::get(quint32 id, const ClientConnection *client) | ||
762 | { | 856 | { | ||
763 | return Private::get<SurfaceInterface>(id, client); | 857 | return Private::get<SurfaceInterface>(id, client); | ||
Show All 9 Lines | |||||
773 | { | 867 | { | ||
774 | Q_D(); | 868 | Q_D(); | ||
775 | return d->subSurface; | 869 | return d->subSurface; | ||
776 | } | 870 | } | ||
777 | 871 | | |||
778 | QSize SurfaceInterface::size() const | 872 | QSize SurfaceInterface::size() const | ||
779 | { | 873 | { | ||
780 | Q_D(); | 874 | Q_D(); | ||
875 | if (!d->current.buffer) { | ||||
876 | return QSize(); | ||||
877 | } | ||||
878 | if (d->current.destinationSize.isValid()) { | ||||
879 | return d->current.destinationSize; | ||||
880 | } | ||||
881 | if (d->current.sourceRectangle.isValid()) { | ||||
882 | return d->current.sourceRectangle.size().toSize(); | ||||
Should this be d->current.sourceRectangle.size()/ scale() It would be a somewhat weird case to use both viewporter and wl_buffer.scale, but it's what the spec implies and you seem to be assuming that in the kwin render path. destinationSize would be as-is. davidedmundson: Should this be
d->current.sourceRectangle.size()/ scale()
It would be a somewhat weird case… | |||||
How I read the spec: the source rectangle is always specified in coordinates after scale and transform. [1] SurfaceInterface::size() returns the scaled and transformed (not yet) buffer size so since viewporter coordinates are to this base we can just directly return them. romangg: How I read the spec: the source rectangle is always specified in coordinates after scale and… | |||||
Yeah, on re-reading I think your intepretation is right. Leave your stuff as-is. davidedmundson: Yeah, on re-reading I think your intepretation is right. Leave your stuff as-is. | |||||
883 | } | ||||
781 | // TODO: apply transform to the buffer size | 884 | // TODO: apply transform to the buffer size | ||
782 | if (d->current.buffer) { | | |||
783 | return d->current.buffer->size() / scale(); | 885 | return d->current.buffer->size() / scale(); | ||
784 | } | 886 | } | ||
785 | return QSize(); | | |||
786 | } | | |||
787 | 887 | | |||
788 | QPointer< ShadowInterface > SurfaceInterface::shadow() const | 888 | QPointer< ShadowInterface > SurfaceInterface::shadow() const | ||
789 | { | 889 | { | ||
790 | Q_D(); | 890 | Q_D(); | ||
791 | return d->current.shadow; | 891 | return d->current.shadow; | ||
792 | } | 892 | } | ||
793 | 893 | | |||
794 | QPointer< BlurInterface > SurfaceInterface::blur() const | 894 | QPointer< BlurInterface > SurfaceInterface::blur() const | ||
▲ Show 20 Lines • Show All 176 Lines • Show Last 20 Lines |
C-style casts are frowned upon.