1 /*
2  * This an unstable interface of wlroots. No guarantees are made regarding the
3  * future consistency of this API.
4  */
5 #ifndef WLR_USE_UNSTABLE
6 #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
7 #endif
8 
9 #ifndef WLR_TYPES_WLR_SURFACE_H
10 #define WLR_TYPES_WLR_SURFACE_H
11 
12 #include <pixman.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <time.h>
16 #include <wayland-server-core.h>
17 #include <wlr/types/wlr_box.h>
18 #include <wlr/types/wlr_output.h>
19 
20 enum wlr_surface_state_field {
21 	WLR_SURFACE_STATE_BUFFER = 1 << 0,
22 	WLR_SURFACE_STATE_SURFACE_DAMAGE = 1 << 1,
23 	WLR_SURFACE_STATE_BUFFER_DAMAGE = 1 << 2,
24 	WLR_SURFACE_STATE_OPAQUE_REGION = 1 << 3,
25 	WLR_SURFACE_STATE_INPUT_REGION = 1 << 4,
26 	WLR_SURFACE_STATE_TRANSFORM = 1 << 5,
27 	WLR_SURFACE_STATE_SCALE = 1 << 6,
28 	WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7,
29 	WLR_SURFACE_STATE_VIEWPORT = 1 << 8,
30 };
31 
32 struct wlr_surface_state {
33 	uint32_t committed; // enum wlr_surface_state_field
34 
35 	struct wl_resource *buffer_resource;
36 	int32_t dx, dy; // relative to previous position
37 	pixman_region32_t surface_damage, buffer_damage; // clipped to bounds
38 	pixman_region32_t opaque, input;
39 	enum wl_output_transform transform;
40 	int32_t scale;
41 	struct wl_list frame_callback_list; // wl_resource
42 
43 	int width, height; // in surface-local coordinates
44 	int buffer_width, buffer_height;
45 
46 	/**
47 	 * The viewport is applied after the surface transform and scale.
48 	 *
49 	 * If has_src is true, the surface content is cropped to the provided
50 	 * rectangle. If has_dst is true, the surface content is scaled to the
51 	 * provided rectangle.
52 	 */
53 	struct {
54 		bool has_src, has_dst;
55 		// In coordinates after scale/transform are applied, but before the
56 		// destination rectangle is applied
57 		struct wlr_fbox src;
58 		int dst_width, dst_height; // in surface-local coordinates
59 	} viewport;
60 
61 	struct wl_listener buffer_destroy;
62 };
63 
64 struct wlr_surface_role {
65 	const char *name;
66 	void (*commit)(struct wlr_surface *surface);
67 	void (*precommit)(struct wlr_surface *surface);
68 };
69 
70 struct wlr_surface {
71 	struct wl_resource *resource;
72 	struct wlr_renderer *renderer;
73 	/**
74 	 * The surface's buffer, if any. A surface has an attached buffer when it
75 	 * commits with a non-null buffer in its pending state. A surface will not
76 	 * have a buffer if it has never committed one, has committed a null buffer,
77 	 * or something went wrong with uploading the buffer.
78 	 */
79 	struct wlr_client_buffer *buffer;
80 	/**
81 	 * The buffer position, in surface-local units.
82 	 */
83 	int sx, sy;
84 	/**
85 	 * The last commit's buffer damage, in buffer-local coordinates. This
86 	 * contains both the damage accumulated by the client via
87 	 * `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`.
88 	 * If the buffer has been resized, the whole buffer is damaged.
89 	 *
90 	 * This region needs to be scaled and transformed into output coordinates,
91 	 * just like the buffer's texture. In addition, if the buffer has shrunk the
92 	 * old size needs to be damaged and if the buffer has moved the old and new
93 	 * positions need to be damaged.
94 	 */
95 	pixman_region32_t buffer_damage;
96 	/**
97 	 * The current opaque region, in surface-local coordinates. It is clipped to
98 	 * the surface bounds. If the surface's buffer is using a fully opaque
99 	 * format, this is set to the whole surface.
100 	 */
101 	pixman_region32_t opaque_region;
102 	/**
103 	 * The current input region, in surface-local coordinates. It is clipped to
104 	 * the surface bounds.
105 	 */
106 	pixman_region32_t input_region;
107 	/**
108 	 * `current` contains the current, committed surface state. `pending`
109 	 * accumulates state changes from the client between commits and shouldn't
110 	 * be accessed by the compositor directly. `previous` contains the state of
111 	 * the previous commit.
112 	 */
113 	struct wlr_surface_state current, pending, previous;
114 
115 	const struct wlr_surface_role *role; // the lifetime-bound role or NULL
116 	void *role_data; // role-specific data
117 
118 	struct {
119 		struct wl_signal commit;
120 		struct wl_signal new_subsurface;
121 		struct wl_signal destroy;
122 	} events;
123 
124 	struct wl_list subsurfaces; // wlr_subsurface::parent_link
125 
126 	// wlr_subsurface::parent_pending_link
127 	struct wl_list subsurface_pending_list;
128 
129 	struct wl_listener renderer_destroy;
130 
131 	void *data;
132 };
133 
134 struct wlr_subsurface_state {
135 	int32_t x, y;
136 };
137 
138 struct wlr_subsurface {
139 	struct wl_resource *resource;
140 	struct wlr_surface *surface;
141 	struct wlr_surface *parent;
142 
143 	struct wlr_subsurface_state current, pending;
144 
145 	struct wlr_surface_state cached;
146 	bool has_cache;
147 
148 	bool synchronized;
149 	bool reordered;
150 	bool mapped;
151 
152 	struct wl_list parent_link;
153 	struct wl_list parent_pending_link;
154 
155 	struct wl_listener surface_destroy;
156 	struct wl_listener parent_destroy;
157 
158 	struct {
159 		struct wl_signal destroy;
160 		struct wl_signal map;
161 		struct wl_signal unmap;
162 	} events;
163 
164 	void *data;
165 };
166 
167 typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface,
168 	int sx, int sy, void *data);
169 
170 struct wlr_renderer;
171 
172 /**
173  * Create a new surface resource with the provided new ID. If `resource_list`
174  * is non-NULL, adds the surface's resource to the list.
175  */
176 struct wlr_surface *wlr_surface_create(struct wl_client *client,
177 		uint32_t version, uint32_t id, struct wlr_renderer *renderer,
178 		struct wl_list *resource_list);
179 
180 /**
181  * Set the lifetime role for this surface. Returns 0 on success or -1 if the
182  * role cannot be set.
183  */
184 bool wlr_surface_set_role(struct wlr_surface *surface,
185 		const struct wlr_surface_role *role, void *role_data,
186 		struct wl_resource *error_resource, uint32_t error_code);
187 
188 /**
189  * Whether or not this surface currently has an attached buffer. A surface has
190  * an attached buffer when it commits with a non-null buffer in its pending
191  * state. A surface will not have a buffer if it has never committed one, has
192  * committed a null buffer, or something went wrong with uploading the buffer.
193  */
194 bool wlr_surface_has_buffer(struct wlr_surface *surface);
195 
196 /**
197  * Get the texture of the buffer currently attached to this surface. Returns
198  * NULL if no buffer is currently attached or if something went wrong with
199  * uploading the buffer.
200  */
201 struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface);
202 
203 /**
204  * Create a new subsurface resource with the provided new ID. If `resource_list`
205  * is non-NULL, adds the subsurface's resource to the list.
206  */
207 struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface,
208 		struct wlr_surface *parent, uint32_t version, uint32_t id,
209 		struct wl_list *resource_list);
210 
211 /**
212  * Get the root of the subsurface tree for this surface.
213  */
214 struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface);
215 
216 /**
217  * Check if the surface accepts input events at the given surface-local
218  * coordinates. Does not check the surface's subsurfaces.
219  */
220 bool wlr_surface_point_accepts_input(struct wlr_surface *surface,
221 		double sx, double sy);
222 
223 /**
224  * Find a surface in this surface's tree that accepts input events at the given
225  * surface-local coordinates. Returns the surface and coordinates in the leaf
226  * surface coordinate system or NULL if no surface is found at that location.
227  */
228 struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface,
229 		double sx, double sy, double *sub_x, double *sub_y);
230 
231 void wlr_surface_send_enter(struct wlr_surface *surface,
232 		struct wlr_output *output);
233 
234 void wlr_surface_send_leave(struct wlr_surface *surface,
235 		struct wlr_output *output);
236 
237 void wlr_surface_send_frame_done(struct wlr_surface *surface,
238 		const struct timespec *when);
239 
240 /**
241  * Get the bounding box that contains the surface and all subsurfaces in
242  * surface coordinates.
243  * X and y may be negative, if there are subsurfaces with negative position.
244  */
245 void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box);
246 
247 struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource);
248 
249 /**
250  * Call `iterator` on each surface in the surface tree, with the surface's
251  * position relative to the root surface. The function is called from root to
252  * leaves (in rendering order).
253  */
254 void wlr_surface_for_each_surface(struct wlr_surface *surface,
255 	wlr_surface_iterator_func_t iterator, void *user_data);
256 
257 /**
258  * Get the effective damage to the surface in terms of surface local
259  * coordinates. This includes damage induced by resizing and moving the
260  * surface. The damage is not expected to be bounded by the surface itself.
261  */
262 void wlr_surface_get_effective_damage(struct wlr_surface *surface,
263 	pixman_region32_t *damage);
264 
265 /**
266  * Get the source rectangle describing the region of the buffer that needs to
267  * be sampled to render this surface's current state. The box is in
268  * buffer-local coordinates.
269  *
270  * If the viewport's source rectangle is unset, the position is zero and the
271  * size is the buffer's.
272  */
273 void wlr_surface_get_buffer_source_box(struct wlr_surface *surface,
274 	struct wlr_fbox *box);
275 
276 #endif
277