1/*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6#ifndef WAYLAND_SURFACE_H
7#define WAYLAND_SURFACE_H
8
9#include "buffer.h"
10
11#include <QObject>
12#include <QPoint>
13#include <QSize>
14#include <QWindow>
15
16#include "KWayland/Client/kwaylandclient_export.h"
17
18struct wl_buffer;
19struct wl_surface;
20
21class QWindow;
22
23namespace KWayland
24{
25namespace Client
26{
27class Output;
28class Region;
29
30/**
31 * @short Wrapper for the wl_surface interface.
32 *
33 * This class is a convenient wrapper for the wl_surface interface.
34 * To create a Surface call Compositor::createSurface.
35 *
36 * The main purpose of this class is to setup the next frame which
37 * should be rendered. Therefore it provides methods to add damage
38 * and to attach a new Buffer and to finalize the frame by calling
39 * commit.
40 *
41 * @see Compositor
42 **/
43class KWAYLANDCLIENT_EXPORT Surface : public QObject
44{
45 Q_OBJECT
46public:
47 explicit Surface(QObject *parent = nullptr);
48 ~Surface() override;
49
50 /**
51 * Creates a Surface for the given @p window.
52 * This is an integration feature for QtWayland. On non-wayland platforms this method returns
53 * @c nullptr as well as for not created QWindows.
54 *
55 * The returned Surface will be fully setup, but won't be released. It gets automatically
56 * destroyed together with the @p window or when the internal wl_surface get destroyed.
57 * QtWayland may destroy wl_surface when hiding the window, you should always call
58 * this function instead of holding the returned pointer.
59 * @since 5.4
60 **/
61 static Surface *fromWindow(QWindow *window);
62
63 /**
64 * Creates a Surface for the given @p winId.
65 * This is an integration feature for QtWayland. On non-wayland platforms this method returns
66 * @c nullptr as well as for not created QWindows.
67 *
68 * The returned Surface will be fully setup, but won't be released. It gets automatically
69 * destroyed together with the QWindow or the wl_surface corresponding.
70 * the @p wid.
71 * @since 5.5
72 * @see fromWindow
73 **/
74 static Surface *fromQtWinId(WId wid);
75
76 /**
77 * Setup this Surface to manage the @p surface.
78 * When using Compositor::createSurface there is no need to call this
79 * method.
80 **/
81 void setup(wl_surface *surface);
82 /**
83 * Releases the wl_surface interface.
84 * After the interface has been released the Surface instance is no
85 * longer valid and can be setup with another wl_surface interface.
86 **/
87 void release();
88 /**
89 * Destroys the data held by this Surface.
90 * This method is supposed to be used when the connection to the Wayland
91 * server goes away. If the connection is not valid anymore, it's not
92 * possible to call release anymore as that calls into the Wayland
93 * connection and the call would fail. This method cleans up the data, so
94 * that the instance can be deleted or set up to a new wl_surface interface
95 * once there is a new connection available.
96 *
97 * This method is automatically invoked when the Registry which created this
98 * Surface gets destroyed.
99 *
100 * @see release
101 **/
102 void destroy();
103 /**
104 * @returns @c true if managing a wl_surface.
105 **/
106 bool isValid() const;
107 /**
108 * Registers a frame rendered callback.
109 * This registers a callback in the Wayland server to be notified once the
110 * next frame for this Surface has been rendered. The Surface will emit the
111 * signal frameRendered after receiving the callback from the server.
112 *
113 * Instead of using this method one should prefer using the CommitFlag::FrameCallback
114 * in commit. This method is intended for cases when the Surface is going to
115 * be committed on other ways, e.g. through the OpenGL/EGL stack.
116 *
117 * @see frameRendered
118 * @see commit
119 **/
120 void setupFrameCallback();
121 /**
122 * Flags to be added to commit.
123 * @li None: no flag
124 * @li FrameCallback: register a frame rendered callback
125 *
126 * Instead of setting the FrameCallback flag one can also call
127 * setupFrameCallback. If one uses setupFrameCallback one may not
128 * use the FrameCallback flag when committing the Surface.
129 *
130 * @see commit
131 * @see setupFrameCallback
132 **/
133 enum class CommitFlag {
134 None,
135 FrameCallback,
136 };
137 void commit(CommitFlag flag = CommitFlag::FrameCallback);
138 /**
139 * Mark @p rect as damaged for the next frame.
140 * @see damageBuffer
141 **/
142 void damage(const QRect &rect);
143 /**
144 * Mark @p region as damaged for the next frame.
145 * @see damageBuffer
146 **/
147 void damage(const QRegion &region);
148 /**
149 * Mark @p rect in buffer coordinates as damaged for the next frame.
150 * @see damage
151 * @since 5.59
152 **/
153 void damageBuffer(const QRect &rect);
154 /**
155 * Mark @p region in buffer coordinates as damaged for the next frame.
156 * @see damage
157 * @since 5.59
158 **/
159 void damageBuffer(const QRegion &region);
160 /**
161 * Attaches the @p buffer to this Surface for the next frame.
162 * @param buffer The buffer to attach to this Surface
163 * @param offset Position of the new upper-left corner in relation to previous frame
164 **/
165 void attachBuffer(wl_buffer *buffer, const QPoint &offset = QPoint());
166 /**
167 * Overloaded method for convenience.
168 **/
169 void attachBuffer(Buffer *buffer, const QPoint &offset = QPoint());
170 /**
171 * Overloaded method for convenience.
172 **/
173 void attachBuffer(Buffer::Ptr buffer, const QPoint &offset = QPoint());
174 /**
175 * Sets the input region to @p region.
176 *
177 * This is a double buffered state and will be applied with the next Surface
178 * commit. Initially the Surface is set up to an infinite input region.
179 * By passing @c null as the input region, it gets reset to an infinite input
180 * region.
181 *
182 * Note: the Region is being copied and can be destroyed directly after passing
183 * to this method.
184 *
185 * @param region The new input region or an infinite region if @c null
186 * @see commit
187 **/
188 void setInputRegion(const Region *region = nullptr);
189 /**
190 * Sets the opaque region to @p region.
191 *
192 * This is a double buffered state and will be applied with the next Surface
193 * commit. Initially the Surface is set up to an empty opaque region.
194 * By passing @c null as the opaque region, it gets reset to an empty opaque
195 * region.
196 *
197 * Note: the Region is being copied and can be destroyed directly after passing
198 * to this method.
199 *
200 * @param region The new opaque region or an empty region if @c null
201 * @see commit
202 **/
203 void setOpaqueRegion(const Region *region = nullptr);
204 void setSize(const QSize &size);
205 QSize size() const;
206
207 /**
208 * The purpose of this method is to allow to supply higher resolution buffer data for use
209 * on high resolution outputs. It's intended that the same buffer scale as the scale of the
210 * output that the surface is displayed on is used.
211 * This means the compositor can avoid scaling when rendering the surface on that output.
212 *
213 * Note that if @p scale is larger than 1 you have to attach a buffer that is larger
214 * (by a factor of scale in each dimension) than the desired surface size.
215 *
216 * The default scale factor is 1.
217 *
218 * The state is only applied with the next commit.
219 *
220 * @see scale
221 * @see commit
222 * @since 5.22
223 **/
224 void setScale(qint32 scale);
225 /**
226 * @returns The current scale factor, if not explicitly set it's @c 1.
227 * @see setScale
228 * @since 5.22
229 **/
230 qint32 scale() const;
231
232 operator wl_surface *();
233 operator wl_surface *() const;
234
235 /**
236 * @returns the id of the referenced wl_proxy.
237 * @since 5.4
238 **/
239 quint32 id() const;
240
241 /**
242 * @returns All Outputs the Surface is on, may be none.
243 * @see outputEntered
244 * @see outputLeft
245 * @since 5.27
246 **/
247 QList<Output *> outputs() const;
248
249 /**
250 * All Surfaces which are currently created.
251 * TODO: KF6 return QList<Surface*> instead of const-ref
252 **/
253 static const QList<Surface *> &all(); // krazy:exclude=constref
254 /**
255 * @returns The Surface referencing the @p native wl_surface or @c null if there is no such Surface.
256 **/
257 static Surface *get(wl_surface *native);
258
259Q_SIGNALS:
260 /**
261 * Emitted when the server indicates that the last committed frame has been rendered.
262 * The signal will only be emitted if a callback has been registered by either calling
263 * setupFrameCallback or calling commit with the CommitFlag::FrameCallback.
264 * @see setupFrameCallback
265 * @see commit
266 **/
267 void frameRendered();
268 void sizeChanged(const QSize &);
269
270 /**
271 * Emitted whenever a change in the Surface (e.g. creation, movement, resize) results in
272 * a part of the Surface being within the scanout region of the Output @p o.
273 *
274 * @param o The Output the Surface intersects with
275 * @see outputLeft
276 * @see outputs
277 * @since 5.27
278 **/
279 void outputEntered(KWayland::Client::Output *o);
280
281 /**
282 * Emitted whenever a change in the Surface (e.g. creation, movement, resize, unmapping)
283 * results in the Surface no longer being within the scanout region of the Output @p o.
284 *
285 * @param o The Output the Surface no longer intersects with
286 * @see outputEntered
287 * @see outputs
288 * @since 5.27
289 **/
290 void outputLeft(KWayland::Client::Output *o);
291
292private:
293 class Private;
294 QScopedPointer<Private> d;
295};
296
297}
298}
299
300#endif
301

source code of kwayland/src/client/surface.h