File indexing completed on 2024-05-12 05:32:29

0001 /*
0002     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 #pragma once
0008 
0009 #include "core/colorspace.h"
0010 #include "core/output.h"
0011 #include "core/renderbackend.h"
0012 
0013 #include <QObject>
0014 #include <QRegion>
0015 
0016 struct wl_resource;
0017 
0018 namespace KWin
0019 {
0020 
0021 class GraphicsBuffer;
0022 class BlurInterface;
0023 class ClientConnection;
0024 class ConfinedPointerV1Interface;
0025 class ContrastInterface;
0026 class CompositorInterface;
0027 class LinuxDmaBufV1Feedback;
0028 class LockedPointerV1Interface;
0029 class OutputInterface;
0030 class ShadowInterface;
0031 class SlideInterface;
0032 class SubSurfaceInterface;
0033 class SurfaceInterfacePrivate;
0034 class Transaction;
0035 
0036 /**
0037  * The SurfaceRole class represents a role assigned to a wayland surface.
0038  */
0039 class KWIN_EXPORT SurfaceRole
0040 {
0041 public:
0042     explicit SurfaceRole(const QByteArray &name);
0043 
0044     /**
0045      * The human readable name of the surface role.
0046      */
0047     QByteArray name() const;
0048 
0049 private:
0050     QByteArray m_name;
0051 };
0052 
0053 /**
0054  * @brief Resource representing a wl_surface.
0055  *
0056  * The SurfaceInterface gets created by the CompositorInterface. A SurfaceInterface normally
0057  * takes up a role by being "attached" to either a ShellSurfaceInterface, a SubSurfaceInterface
0058  * or a Cursor.
0059  *
0060  * The implementation of the SurfaceInterface does not only wrap the features exposed by wl_surface,
0061  * but goes further by integrating the information added to a SurfaceInterface by other interfaces.
0062  * This should make interacting from the server easier, it only needs to monitor the SurfaceInterface
0063  * and does not need to track each specific interface.
0064  *
0065  * The SurfaceInterface takes care of reference/unreferencing the GraphicsBuffer attached to it.
0066  * As long as a GraphicsBuffer is attached, the released signal won't be sent. If the GraphicsBuffer
0067  * is no longer needed by the SurfaceInterface, it will get unreferenced and might be automatically
0068  * deleted (if it's no longer referenced).
0069  *
0070  * @see CompositorInterface
0071  * @see GraphicsBuffer
0072  * @see SubSurfaceInterface
0073  * @see BlurInterface
0074  * @see ContrastInterface
0075  * @see ShadowInterface
0076  * @see SlideInterface
0077  * @see LinuxDmaBufV1Feedback
0078  */
0079 class KWIN_EXPORT SurfaceInterface : public QObject
0080 {
0081     Q_OBJECT
0082     /**
0083      * The opaque region for a translucent buffer.
0084      */
0085     Q_PROPERTY(QRegion opaque READ opaque NOTIFY opaqueChanged)
0086     /**
0087      * The current input region.
0088      */
0089     Q_PROPERTY(QRegion input READ input NOTIFY inputChanged)
0090     Q_PROPERTY(QSizeF size READ size NOTIFY sizeChanged)
0091 public:
0092     explicit SurfaceInterface(CompositorInterface *compositor, wl_resource *resource);
0093     ~SurfaceInterface() override;
0094 
0095     /**
0096      * Returns the object id for this Wayland surface.
0097      */
0098     uint32_t id() const;
0099     /**
0100      * Returns the Wayland client that owns this SurfaceInterface.
0101      */
0102     ClientConnection *client() const;
0103     /**
0104      * Returns the Wayland resource corresponding to this SurfaceInterface.
0105      */
0106     wl_resource *resource() const;
0107     /**
0108      * Returns the compositor for this SurfaceInterface.
0109      */
0110     CompositorInterface *compositor() const;
0111 
0112     /**
0113      * Returns the role of this surface, or @c null if no role has been assigned to the surface.
0114      *
0115      * Once a role is given to the surface, it is permanent.
0116      */
0117     SurfaceRole *role() const;
0118     void setRole(SurfaceRole *role);
0119 
0120     /**
0121      * Maps the specified @a point in this surface's coordinate system to the equivalent point
0122      * within the @a child's coordinate system, and returns the mapped point.
0123      *
0124      * If this surface is not an ancestor of the @a child, a null point is returned.
0125      */
0126     QPointF mapToChild(SurfaceInterface *child, const QPointF &point) const;
0127 
0128     void frameRendered(quint32 msec);
0129     bool hasFrameCallbacks() const;
0130 
0131     std::unique_ptr<PresentationFeedback> takePresentationFeedback(Output *output);
0132 
0133     QRegion opaque() const;
0134     QRegion input() const;
0135     QRegion bufferDamage() const;
0136     QRectF bufferSourceBox() const;
0137     /**
0138      * Returns the buffer transform that had been applied to the buffer to compensate for
0139      * output rotation.
0140      *
0141      * If the surface is on an output that is rotated 90 degrees clockwise, the buffer will
0142      * be rotated 90 degrees counter clockwise.
0143      */
0144     OutputTransform bufferTransform() const;
0145     /**
0146      * @returns the current GraphicsBuffer, might be @c nullptr.
0147      */
0148     GraphicsBuffer *buffer() const;
0149     QPoint offset() const;
0150     /**
0151      * Returns the current size of the surface, in surface coordinates.
0152      *
0153      * Note that there is no direct relationship between the surface size and the buffer size.
0154      * In order to determine the size of the currently attached buffer, use buffer()->size().
0155      */
0156     QSizeF size() const;
0157     /**
0158      * Returns the rectangle that bounds this surface and all of its sub-surfaces.
0159      *
0160      * QPoint(0, 0) corresponds to the upper left corner of this surface.
0161      */
0162     QRectF boundingRect() const;
0163     /**
0164      * Returns the size of the attached buffer, in device pixels.
0165      *
0166      * If no buffer is attached to this surface, an invalid QSize will be returned.
0167      */
0168     QSize bufferSize() const;
0169 
0170     /**
0171      * @returns The SubSurface for this Surface in case there is one.
0172      */
0173     SubSurfaceInterface *subSurface() const;
0174     /**
0175      * Returns the sub-surfaces that are below this surface. The sub-surfaces are sorted
0176      * from bottom to top.
0177      */
0178     QList<SubSurfaceInterface *> below() const;
0179     /**
0180      * Returns the sub-surfaces that are above this surface. The sub-surfaces are sorted
0181      * from bottom to top.
0182      */
0183     QList<SubSurfaceInterface *> above() const;
0184 
0185     /**
0186      * @returns The Shadow for this Surface.
0187      */
0188     ShadowInterface *shadow() const;
0189 
0190     /**
0191      * @returns The Blur for this Surface.
0192      */
0193     BlurInterface *blur() const;
0194 
0195     /**
0196      * @returns The Slide for this Surface.
0197      */
0198     SlideInterface *slideOnShowHide() const;
0199 
0200     /**
0201      * @returns The Contrast for this Surface.
0202      */
0203     ContrastInterface *contrast() const;
0204 
0205     /**
0206      * Whether the SurfaceInterface is currently considered to be mapped.
0207      * A SurfaceInterface is mapped if it has a non-null GraphicsBuffer attached.
0208      * If the SurfaceInterface references a SubSurfaceInterface it is only considered
0209      * mapped if it has a GraphicsBuffer attached and the parent SurfaceInterface is mapped.
0210      *
0211      * @returns Whether the SurfaceInterface is currently mapped
0212      */
0213     bool isMapped() const;
0214 
0215     /**
0216      * Finds the SurfaceInterface at the given @p position in surface-local coordinates.
0217      * This can be either a descendant SurfaceInterface honoring the stacking order or
0218      * the SurfaceInterface itself if its geometry contains the given @p position.
0219      *
0220      * If no such SurfaceInterface is found, e.g. because the SurfaceInterface is unmapped,
0221      * @c nullptr is returned.
0222      *
0223      * @param position The position in surface-local coordinates
0224      * @returns Child surface at the given @p position or surface itself at the position, might be @c nullptr
0225      */
0226     SurfaceInterface *surfaceAt(const QPointF &position);
0227 
0228     /**
0229      * Finds the input receiving SurfaceInterface at the given @p position in surface-local coordinates.
0230      * This can be either a descendant SurfaceInterface honoring the stacking order or
0231      * the SurfaceInterface itself if its geometry contains the given @p position.
0232      *
0233      * If no such SurfaceInterface is found, e.g. because the SurfaceInterface is unmapped or there is no
0234      * input region containing the position,
0235      * @c nullptr is returned.
0236      *
0237      * @param position The position in surface-local coordinates
0238      * @returns Input receiving child surface at the given @p position or surface itself at the position, might be @c nullptr
0239      */
0240     SurfaceInterface *inputSurfaceAt(const QPointF &position);
0241 
0242     /**
0243      * Sets the @p outputs this SurfaceInterface overlaps with, may be empty.
0244      *
0245      * The compositor should update whenever the SurfaceInterface becomes visible on
0246      * an OutputInterface by e.g. getting (un)mapped, resized, moved, etc.
0247      *
0248      * @see outputs
0249      */
0250     void setOutputs(const QList<OutputInterface *> &outputs, OutputInterface *primaryOutput);
0251 
0252     /**
0253      * @returns All OutputInterfaces the SurfaceInterface is on.
0254      * @see setOutputs
0255      */
0256     QList<OutputInterface *> outputs() const;
0257 
0258     /**
0259      * Pointer confinement installed on this SurfaceInterface.
0260      * @see pointerConstraintsChanged
0261      */
0262     ConfinedPointerV1Interface *confinedPointer() const;
0263 
0264     /**
0265      * Pointer lock installed on this SurfaceInterface.
0266      * @see pointerConstraintsChanged
0267      */
0268     LockedPointerV1Interface *lockedPointer() const;
0269 
0270     /**
0271      * @returns Whether this SurfaceInterface wants idle to be inhibited on the Output it is shown
0272      * @see inhibitsIdleChanged
0273      */
0274     bool inhibitsIdle() const;
0275 
0276     /**
0277      * dmabuf feedback installed on this SurfaceInterface
0278      */
0279     LinuxDmaBufV1Feedback *dmabufFeedbackV1() const;
0280 
0281     /**
0282      * @returns the current content type of this surface
0283      */
0284     ContentType contentType() const;
0285 
0286     /**
0287      * @returns The SurfaceInterface for the @p native resource.
0288      */
0289     static SurfaceInterface *get(wl_resource *native);
0290     /**
0291      * @returns The SurfaceInterface with given @p id for @p client, if it exists, otherwise @c nullptr.
0292      */
0293     static SurfaceInterface *get(quint32 id, const ClientConnection *client);
0294 
0295     /**
0296      * @see ClientConnection::setScaleOverride
0297      */
0298     qreal scaleOverride() const;
0299     /**
0300      * Convert a co-ordinate from kwin logical space to surface logical space
0301      * @internal
0302      */
0303     QPoint toSurfaceLocal(const QPoint &point) const;
0304     /**
0305      * Convert a co-ordinate from kwin logical space to surface logical space
0306      * @internal
0307      */
0308     QPointF toSurfaceLocal(const QPointF &point) const;
0309 
0310     /**
0311      * @returns if the client thinks the content of this surface is suitable for presentation with tearing
0312      */
0313     PresentationModeHint presentationModeHint() const;
0314 
0315     /**
0316      * Sets a preferred buffer scale that clients should provide buffers in
0317      * @param scale
0318      */
0319     void setPreferredBufferScale(qreal scale);
0320 
0321     /**
0322      * Sets the preferred buffer transform for this surface.
0323      *
0324      * This indicates to the client the preferred buffer transform to use when
0325      * attaching buffers to this surface.
0326      */
0327     void setPreferredBufferTransform(OutputTransform transform);
0328 
0329     /**
0330      * The first committed transaction that is scheduled to be applied to this surface.
0331      */
0332     Transaction *firstTransaction() const;
0333     void setFirstTransaction(Transaction *transaction);
0334 
0335     /**
0336      * The last committed transaction that is scheduled to be applied to this surface.
0337      */
0338     Transaction *lastTransaction() const;
0339     void setLastTransaction(Transaction *transaction);
0340 
0341     const ColorDescription &colorDescription() const;
0342 
0343     void setPreferredColorDescription(const ColorDescription &descr);
0344 
0345     /**
0346      * Traverses the surface sub-tree with this surface as the root.
0347      */
0348     void traverseTree(std::function<void(SurfaceInterface *surface)> callback);
0349 
0350 Q_SIGNALS:
0351     /**
0352      * This signal is emitted when the underlying wl_surface resource is about to be freed.
0353      *
0354      * The unbound() signal is emitted either when the client that owns the surface has been
0355      * destroyed or if the surface has been destroyed due to a destructor request.
0356      *
0357      * The SurfaceInterface object and the associated wl_surface resource are valid when this
0358      * signal is emitted.
0359      */
0360     void aboutToBeDestroyed();
0361     /**
0362      * Emitted whenever the SurfaceInterface got damaged.
0363      * The signal is only emitted during the commit of state.
0364      * A damage means that a new GraphicsBuffer got attached.
0365      *
0366      * @see buffer
0367      * @see damage
0368      */
0369     void damaged(const QRegion &);
0370     void opaqueChanged(const QRegion &);
0371     void inputChanged(const QRegion &);
0372     /**
0373      * This signal is emitted when the buffer transform has changed.
0374      */
0375     void bufferTransformChanged(KWin::OutputTransform);
0376     void bufferSourceBoxChanged();
0377     /**
0378      * This signal is emitted when the size of the attached buffer has changed.
0379      */
0380     void bufferSizeChanged();
0381     /**
0382      * Emitted when the Surface becomes visible, i.e. a non-null buffer has been attached.
0383      */
0384     void mapped();
0385     /**
0386      * Emitted when the Surface removes its content
0387      */
0388     void unmapped();
0389     /**
0390      * This signal is emitted when the surface size has changed.
0391      */
0392     void sizeChanged();
0393     void shadowChanged();
0394     void blurChanged();
0395     void slideOnShowHideChanged();
0396     void contrastChanged();
0397     /**
0398      * Emitted whenever a new child sub-surface @p subSurface is added.
0399      */
0400     void childSubSurfaceAdded(SubSurfaceInterface *subSurface);
0401     /**
0402      * Emitted whenver the child sub-surface @p subSurface is removed.
0403      */
0404     void childSubSurfaceRemoved(SubSurfaceInterface *subSurface);
0405     /**
0406      * This signal is emitted when the list of child subsurfaces changes.
0407      */
0408     void childSubSurfacesChanged();
0409 
0410     /**
0411      * Emitted whenever a pointer constraint get (un)installed on this SurfaceInterface.
0412      *
0413      * The pointer constraint does not get activated, the compositor needs to activate
0414      * the lock/confinement.
0415      *
0416      * @see confinedPointer
0417      * @see lockedPointer
0418      */
0419     void pointerConstraintsChanged();
0420 
0421     /**
0422      * Emitted whenever the SurfaceInterface starts/ends to inhibit idle.
0423      * @see inhibitsIdle
0424      */
0425     void inhibitsIdleChanged();
0426 
0427     void colorDescriptionChanged();
0428     void presentationModeHintChanged();
0429 
0430     /**
0431      * Emitted when the Surface has been committed.
0432      *
0433      * This signal is emitted after all the relevant damage and xyzChanged signals
0434      * for this commit are emitted.
0435      */
0436     void committed();
0437 
0438     /**
0439      * This signal is emitted when a surface commit with the specified \a serial has been cached
0440      * to be applied later.
0441      */
0442     void stateStashed(quint32 serial);
0443 
0444     /**
0445      * This signal is emitted when the state in a surface commit with the specified \a serial
0446      * has been applied.
0447      */
0448     void stateApplied(quint32 serial);
0449 
0450 private:
0451     std::unique_ptr<SurfaceInterfacePrivate> d;
0452     friend class SurfaceInterfacePrivate;
0453 };
0454 
0455 /**
0456  * The SurfaceExtension class is the base class for wl_surface extensions. The SurfaceExtension
0457  * helps with managing extension state and keeping it in sync with the surface state.
0458  */
0459 template<typename Commit>
0460 class SurfaceExtension : public QObject
0461 {
0462 public:
0463     explicit SurfaceExtension(SurfaceInterface *surface)
0464     {
0465         connect(surface, &SurfaceInterface::stateStashed, this, &SurfaceExtension::stashState);
0466         connect(surface, &SurfaceInterface::stateApplied, this, &SurfaceExtension::applyState);
0467     }
0468 
0469     virtual void apply(Commit *commit) = 0;
0470 
0471     Commit pending;
0472     QMap<quint32, Commit> stashed;
0473 
0474 private:
0475     void stashState(quint32 serial)
0476     {
0477         Commit stash = std::exchange(pending, Commit{});
0478         stashed.insert(serial, stash);
0479     }
0480 
0481     void applyState(quint32 serial)
0482     {
0483         if (!stashed.isEmpty()) {
0484             if (stashed.firstKey() == serial) {
0485                 Commit stash = stashed.take(serial);
0486                 apply(&stash);
0487             }
0488             return;
0489         }
0490 
0491         apply(&pending);
0492         pending = Commit{};
0493     }
0494 };
0495 
0496 } // namespace KWin
0497 
0498 Q_DECLARE_METATYPE(KWin::SurfaceInterface *)