File indexing completed on 2024-12-22 05:09:24

0001 /*
0002     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #ifndef WAYLAND_SURFACE_H
0007 #define WAYLAND_SURFACE_H
0008 
0009 #include "buffer.h"
0010 
0011 #include <QObject>
0012 #include <QPoint>
0013 #include <QSize>
0014 #include <QWindow>
0015 
0016 #include "KWayland/Client/kwaylandclient_export.h"
0017 
0018 struct wl_buffer;
0019 struct wl_surface;
0020 
0021 class QWindow;
0022 
0023 namespace KWayland
0024 {
0025 namespace Client
0026 {
0027 class Output;
0028 class Region;
0029 
0030 /**
0031  * @short Wrapper for the wl_surface interface.
0032  *
0033  * This class is a convenient wrapper for the wl_surface interface.
0034  * To create a Surface call Compositor::createSurface.
0035  *
0036  * The main purpose of this class is to setup the next frame which
0037  * should be rendered. Therefore it provides methods to add damage
0038  * and to attach a new Buffer and to finalize the frame by calling
0039  * commit.
0040  *
0041  * @see Compositor
0042  **/
0043 class KWAYLANDCLIENT_EXPORT Surface : public QObject
0044 {
0045     Q_OBJECT
0046 public:
0047     explicit Surface(QObject *parent = nullptr);
0048     ~Surface() override;
0049 
0050     /**
0051      * Creates a Surface for the given @p window.
0052      * This is an integration feature for QtWayland. On non-wayland platforms this method returns
0053      * @c nullptr as well as for not created QWindows.
0054      *
0055      * The returned Surface will be fully setup, but won't be released. It gets automatically
0056      * destroyed together with the @p window or when the internal wl_surface get destroyed.
0057      * QtWayland may destroy wl_surface when hiding the window, you should always call
0058      * this function instead of holding the returned pointer.
0059      * @since 5.4
0060      **/
0061     static Surface *fromWindow(QWindow *window);
0062 
0063     /**
0064      * Creates a Surface for the given @p winId.
0065      * This is an integration feature for QtWayland. On non-wayland platforms this method returns
0066      * @c nullptr as well as for not created QWindows.
0067      *
0068      * The returned Surface will be fully setup, but won't be released. It gets automatically
0069      * destroyed together with the QWindow or the wl_surface corresponding.
0070      * the @p wid.
0071      * @since 5.5
0072      * @see fromWindow
0073      **/
0074     static Surface *fromQtWinId(WId wid);
0075 
0076     /**
0077      * Setup this Surface to manage the @p surface.
0078      * When using Compositor::createSurface there is no need to call this
0079      * method.
0080      **/
0081     void setup(wl_surface *surface);
0082     /**
0083      * Releases the wl_surface interface.
0084      * After the interface has been released the Surface instance is no
0085      * longer valid and can be setup with another wl_surface interface.
0086      **/
0087     void release();
0088     /**
0089      * Destroys the data held by this Surface.
0090      * This method is supposed to be used when the connection to the Wayland
0091      * server goes away. If the connection is not valid anymore, it's not
0092      * possible to call release anymore as that calls into the Wayland
0093      * connection and the call would fail. This method cleans up the data, so
0094      * that the instance can be deleted or set up to a new wl_surface interface
0095      * once there is a new connection available.
0096      *
0097      * This method is automatically invoked when the Registry which created this
0098      * Surface gets destroyed.
0099      *
0100      * @see release
0101      **/
0102     void destroy();
0103     /**
0104      * @returns @c true if managing a wl_surface.
0105      **/
0106     bool isValid() const;
0107     /**
0108      * Registers a frame rendered callback.
0109      * This registers a callback in the Wayland server to be notified once the
0110      * next frame for this Surface has been rendered. The Surface will emit the
0111      * signal frameRendered after receiving the callback from the server.
0112      *
0113      * Instead of using this method one should prefer using the CommitFlag::FrameCallback
0114      * in commit. This method is intended for cases when the Surface is going to
0115      * be committed on other ways, e.g. through the OpenGL/EGL stack.
0116      *
0117      * @see frameRendered
0118      * @see commit
0119      **/
0120     void setupFrameCallback();
0121     /**
0122      * Flags to be added to commit.
0123      * @li None: no flag
0124      * @li FrameCallback: register a frame rendered callback
0125      *
0126      * Instead of setting the FrameCallback flag one can also call
0127      * setupFrameCallback. If one uses setupFrameCallback one may not
0128      * use the FrameCallback flag when committing the Surface.
0129      *
0130      * @see commit
0131      * @see setupFrameCallback
0132      **/
0133     enum class CommitFlag {
0134         None,
0135         FrameCallback,
0136     };
0137     void commit(CommitFlag flag = CommitFlag::FrameCallback);
0138     /**
0139      * Mark @p rect as damaged for the next frame.
0140      * @see damageBuffer
0141      **/
0142     void damage(const QRect &rect);
0143     /**
0144      * Mark @p region as damaged for the next frame.
0145      * @see damageBuffer
0146      **/
0147     void damage(const QRegion &region);
0148     /**
0149      * Mark @p rect in buffer coordinates as damaged for the next frame.
0150      * @see damage
0151      * @since 5.59
0152      **/
0153     void damageBuffer(const QRect &rect);
0154     /**
0155      * Mark @p region in buffer coordinates as damaged for the next frame.
0156      * @see damage
0157      * @since 5.59
0158      **/
0159     void damageBuffer(const QRegion &region);
0160     /**
0161      * Attaches the @p buffer to this Surface for the next frame.
0162      * @param buffer The buffer to attach to this Surface
0163      * @param offset Position of the new upper-left corner in relation to previous frame
0164      **/
0165     void attachBuffer(wl_buffer *buffer, const QPoint &offset = QPoint());
0166     /**
0167      * Overloaded method for convenience.
0168      **/
0169     void attachBuffer(Buffer *buffer, const QPoint &offset = QPoint());
0170     /**
0171      * Overloaded method for convenience.
0172      **/
0173     void attachBuffer(Buffer::Ptr buffer, const QPoint &offset = QPoint());
0174     /**
0175      * Sets the input region to @p region.
0176      *
0177      * This is a double buffered state and will be applied with the next Surface
0178      * commit. Initially the Surface is set up to an infinite input region.
0179      * By passing @c null as the input region, it gets reset to an infinite input
0180      * region.
0181      *
0182      * Note: the Region is being copied and can be destroyed directly after passing
0183      * to this method.
0184      *
0185      * @param region The new input region or an infinite region if @c null
0186      * @see commit
0187      **/
0188     void setInputRegion(const Region *region = nullptr);
0189     /**
0190      * Sets the opaque region to @p region.
0191      *
0192      * This is a double buffered state and will be applied with the next Surface
0193      * commit. Initially the Surface is set up to an empty opaque region.
0194      * By passing @c null as the opaque region, it gets reset to an empty opaque
0195      * region.
0196      *
0197      * Note: the Region is being copied and can be destroyed directly after passing
0198      * to this method.
0199      *
0200      * @param region The new opaque region or an empty region if @c null
0201      * @see commit
0202      **/
0203     void setOpaqueRegion(const Region *region = nullptr);
0204     void setSize(const QSize &size);
0205     QSize size() const;
0206 
0207     /**
0208      * The purpose of this method is to allow to supply higher resolution buffer data for use
0209      * on high resolution outputs. It's intended that the same buffer scale as the scale of the
0210      * output that the surface is displayed on is used.
0211      * This means the compositor can avoid scaling when rendering the surface on that output.
0212      *
0213      * Note that if @p scale is larger than 1 you have to attach a buffer that is larger
0214      * (by a factor of scale in each dimension) than the desired surface size.
0215      *
0216      * The default scale factor is 1.
0217      *
0218      * The state is only applied with the next commit.
0219      *
0220      * @see scale
0221      * @see commit
0222      * @since 5.22
0223      **/
0224     void setScale(qint32 scale);
0225     /**
0226      * @returns The current scale factor, if not explicitly set it's @c 1.
0227      * @see setScale
0228      * @since 5.22
0229      **/
0230     qint32 scale() const;
0231 
0232     operator wl_surface *();
0233     operator wl_surface *() const;
0234 
0235     /**
0236      * @returns the id of the referenced wl_proxy.
0237      * @since 5.4
0238      **/
0239     quint32 id() const;
0240 
0241     /**
0242      * @returns All Outputs the Surface is on, may be none.
0243      * @see outputEntered
0244      * @see outputLeft
0245      * @since 5.27
0246      **/
0247     QList<Output *> outputs() const;
0248 
0249     /**
0250      * All Surfaces which are currently created.
0251      * TODO: KF6 return QList<Surface*> instead of const-ref
0252      **/
0253     static const QList<Surface *> &all(); // krazy:exclude=constref
0254     /**
0255      * @returns The Surface referencing the @p native wl_surface or @c null if there is no such Surface.
0256      **/
0257     static Surface *get(wl_surface *native);
0258 
0259 Q_SIGNALS:
0260     /**
0261      * Emitted when the server indicates that the last committed frame has been rendered.
0262      * The signal will only be emitted if a callback has been registered by either calling
0263      * setupFrameCallback or calling commit with the CommitFlag::FrameCallback.
0264      * @see setupFrameCallback
0265      * @see commit
0266      **/
0267     void frameRendered();
0268     void sizeChanged(const QSize &);
0269 
0270     /**
0271      * Emitted whenever a change in the Surface (e.g. creation, movement, resize) results in
0272      * a part of the Surface being within the scanout region of the Output @p o.
0273      *
0274      * @param o The Output the Surface intersects with
0275      * @see outputLeft
0276      * @see outputs
0277      * @since 5.27
0278      **/
0279     void outputEntered(KWayland::Client::Output *o);
0280 
0281     /**
0282      * Emitted whenever a change in the Surface (e.g. creation, movement, resize, unmapping)
0283      * results in the Surface no longer being within the scanout region of the Output @p o.
0284      *
0285      * @param o The Output the Surface no longer intersects with
0286      * @see outputEntered
0287      * @see outputs
0288      * @since 5.27
0289      **/
0290     void outputLeft(KWayland::Client::Output *o);
0291 
0292 private:
0293     class Private;
0294     QScopedPointer<Private> d;
0295 };
0296 
0297 }
0298 }
0299 
0300 #endif