File indexing completed on 2024-05-19 16:35:28

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