1 /*
2  * Copyright © 2017-2018 Red Hat Inc.
3  * Copyright © 2018 Jonas Ådahl
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial
15  * portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef LIBDECOR_H
28 #define LIBDECOR_H
29 
30 #include <stdbool.h>
31 #include <wayland-client.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 #if defined(__GNUC__) && __GNUC__ >= 4
38 #define LIBDECOR_EXPORT __attribute__ ((visibility("default")))
39 #else
40 #define LIBDECOR_EXPORT
41 #endif
42 
43 struct xdg_toplevel;
44 
45 /** \class libdecor
46  *
47  * \brief A libdecor context instance.
48  */
49 struct libdecor;
50 
51 /** \class libdecor_frame
52  *
53  * \brief A frame used for decorating a Wayland surface.
54  */
55 struct libdecor_frame;
56 
57 /** \class libdecor_configuration
58  *
59  * \brief An object representing a toplevel window configuration.
60  */
61 struct libdecor_configuration;
62 
63 /** \class libdecor_state
64  *
65  * \brief An object corresponding to a configured content state.
66  */
67 struct libdecor_state;
68 
69 enum libdecor_error {
70 	LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
71 	LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
72 };
73 
74 enum libdecor_window_state {
75 	LIBDECOR_WINDOW_STATE_NONE = 0,
76 	LIBDECOR_WINDOW_STATE_ACTIVE = 1 << 0,
77 	LIBDECOR_WINDOW_STATE_MAXIMIZED = 1 << 1,
78 	LIBDECOR_WINDOW_STATE_FULLSCREEN = 1 << 2,
79 	LIBDECOR_WINDOW_STATE_TILED_LEFT = 1 << 3,
80 	LIBDECOR_WINDOW_STATE_TILED_RIGHT = 1 << 4,
81 	LIBDECOR_WINDOW_STATE_TILED_TOP = 1 << 5,
82 	LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 1 << 6,
83 };
84 
85 enum libdecor_resize_edge {
86 	LIBDECOR_RESIZE_EDGE_NONE,
87 	LIBDECOR_RESIZE_EDGE_TOP,
88 	LIBDECOR_RESIZE_EDGE_BOTTOM,
89 	LIBDECOR_RESIZE_EDGE_LEFT,
90 	LIBDECOR_RESIZE_EDGE_TOP_LEFT,
91 	LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT,
92 	LIBDECOR_RESIZE_EDGE_RIGHT,
93 	LIBDECOR_RESIZE_EDGE_TOP_RIGHT,
94 	LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT,
95 };
96 
97 enum libdecor_capabilities {
98 	LIBDECOR_ACTION_MOVE = 1 << 0,
99 	LIBDECOR_ACTION_RESIZE = 1 << 1,
100 	LIBDECOR_ACTION_MINIMIZE = 1 << 2,
101 	LIBDECOR_ACTION_FULLSCREEN = 1 << 3,
102 	LIBDECOR_ACTION_CLOSE = 1 << 4,
103 };
104 
105 struct libdecor_interface {
106 	/**
107 	 * An error event
108 	 */
109 	void (* error)(struct libdecor *context,
110 		       enum libdecor_error error,
111 		       const char *message);
112 
113 	/* Reserved */
114 	void (* reserved0)(void);
115 	void (* reserved1)(void);
116 	void (* reserved2)(void);
117 	void (* reserved3)(void);
118 	void (* reserved4)(void);
119 	void (* reserved5)(void);
120 	void (* reserved6)(void);
121 	void (* reserved7)(void);
122 	void (* reserved8)(void);
123 	void (* reserved9)(void);
124 };
125 
126 /**
127  * Interface for integrating a Wayland surface with libdecor.
128  */
129 struct libdecor_frame_interface {
130 	/**
131 	 * A new configuration was received. An application should respond to
132 	 * this by creating a suitable libdecor_state, and apply it using
133 	 * libdecor_frame_commit.
134 	 */
135 	void (* configure)(struct libdecor_frame *frame,
136 			   struct libdecor_configuration *configuration,
137 			   void *user_data);
138 
139 	/**
140 	 * The window was requested to be closed by the compositor.
141 	 */
142 	void (* close)(struct libdecor_frame *frame,
143 		       void *user_data);
144 
145 	/**
146 	 * The window decoration asked to have the main surface to be
147 	 * committed. This is required when the decoration is implemented using
148 	 * synchronous subsurfaces.
149 	 */
150 	void (* commit)(struct libdecor_frame *frame,
151 			void *user_data);
152 
153 	/**
154 	 * Any mapped popup that has a grab on the given seat should be
155 	 * dismissed.
156 	 */
157 	void (* dismiss_popup)(struct libdecor_frame *frame,
158 			       const char *seat_name,
159 			       void *user_data);
160 
161 	/* Reserved */
162 	void (* reserved0)(void);
163 	void (* reserved1)(void);
164 	void (* reserved2)(void);
165 	void (* reserved3)(void);
166 	void (* reserved4)(void);
167 	void (* reserved5)(void);
168 	void (* reserved6)(void);
169 	void (* reserved7)(void);
170 	void (* reserved8)(void);
171 	void (* reserved9)(void);
172 };
173 
174 /**
175  * Remove a reference to the libdecor instance. When the reference count
176  * reaches zero, it is freed.
177  */
178 void
179 libdecor_unref(struct libdecor *context);
180 
181 /**
182  * Create a new libdecor context for the given wl_display.
183  */
184 struct libdecor *
185 libdecor_new(struct wl_display *display,
186 	     struct libdecor_interface *iface);
187 
188 /**
189  * Get the file descriptor used by libdecor. This is similar to
190  * wl_display_get_fd(), thus should be polled, and when data is available,
191  * libdecor_dispatch() should be called.
192  */
193 int
194 libdecor_get_fd(struct libdecor *context);
195 
196 /**
197  * Dispatch events. This function should be called when data is available on
198  * the file descriptor returned by libdecor_get_fd(). If timeout is zero, this
199  * function will never block.
200  */
201 int
202 libdecor_dispatch(struct libdecor *context,
203 		  int timeout);
204 
205 /**
206  * Decorate the given content wl_surface.
207  *
208  * This will create an xdg_surface and an xdg_toplevel, and integrate it
209  * properly with the windowing system, including creating appropriate
210  * decorations when needed, as well as handle windowing integration events such
211  * as resizing, moving, maximizing, etc.
212  *
213  * The passed wl_surface should only contain actual application content,
214  * without any window decoration.
215  */
216 struct libdecor_frame *
217 libdecor_decorate(struct libdecor *context,
218 		  struct wl_surface *surface,
219 		  struct libdecor_frame_interface *iface,
220 		  void *user_data);
221 
222 /**
223  * Add a reference to the frame object.
224  */
225 void
226 libdecor_frame_ref(struct libdecor_frame *frame);
227 
228 /**
229  * Remove a reference to the frame object. When the reference count reaches
230  * zero, the frame object is destroyed.
231  */
232 void
233 libdecor_frame_unref(struct libdecor_frame *frame);
234 
235 /**
236  * Set the visibility of the frame.
237  *
238  * If an application wants to be borderless, it can set the frame visibility to
239  * false.
240  */
241 void
242 libdecor_frame_set_visibility(struct libdecor_frame *frame,
243 			      bool visible);
244 
245 /**
246  * Get the visibility of the frame.
247  */
248 bool
249 libdecor_frame_is_visible(struct libdecor_frame *frame);
250 
251 
252 /**
253  * Set the parent of the window.
254  *
255  * This can be used to stack multiple toplevel windows above or under each
256  * other.
257  */
258 void
259 libdecor_frame_set_parent(struct libdecor_frame *frame,
260 			  struct libdecor_frame *parent);
261 
262 /**
263  * Set the title of the window.
264  */
265 void
266 libdecor_frame_set_title(struct libdecor_frame *frame,
267 			 const char *title);
268 
269 /**
270  * Get the title of the window.
271  */
272 const char *
273 libdecor_frame_get_title(struct libdecor_frame *frame);
274 
275 /**
276  * Set the application ID of the window.
277  */
278 void
279 libdecor_frame_set_app_id(struct libdecor_frame *frame,
280 			  const char *app_id);
281 
282 /**
283  * Set new capabilities of the window.
284  *
285  * This determines whether e.g. a window decoration should show a maximize
286  * button, etc.
287  *
288  * Setting a capability does not implicitly unset any other.
289  */
290 void
291 libdecor_frame_set_capabilities(struct libdecor_frame *frame,
292 				enum libdecor_capabilities capabilities);
293 
294 /**
295  * Unset capabilities of the window.
296  *
297  * The opposite of libdecor_frame_set_capabilities.
298  */
299 void
300 libdecor_frame_unset_capabilities(struct libdecor_frame *frame,
301 				  enum libdecor_capabilities capabilities);
302 
303 /**
304  * Check whether the window has any of the given capabilities.
305  */
306 bool
307 libdecor_frame_has_capability(struct libdecor_frame *frame,
308 			      enum libdecor_capabilities capability);
309 
310 /**
311  * Show the window menu.
312  */
313 void
314 libdecor_frame_show_window_menu(struct libdecor_frame *frame,
315 				struct wl_seat *wl_seat,
316 				uint32_t serial,
317 				int x,
318 				int y);
319 
320 /**
321  * Issue a popup grab on the window. Call this when a xdg_popup is mapped, so
322  * that it can be properly dismissed by the decorations.
323  */
324 void
325 libdecor_frame_popup_grab(struct libdecor_frame *frame,
326 			  const char *seat_name);
327 
328 /**
329  * Release the popup grab. Call this when you unmap a popup.
330  */
331 void
332 libdecor_frame_popup_ungrab(struct libdecor_frame *frame,
333 			    const char *seat_name);
334 
335 /**
336  * Translate content surface local coordinates to toplevel window local
337  * coordinates.
338  *
339  * This can be used to translate surface coordinates to coordinates useful for
340  * e.g. showing the window menu, or positioning a popup.
341  */
342 void
343 libdecor_frame_translate_coordinate(struct libdecor_frame *frame,
344 				    int surface_x,
345 				    int surface_y,
346 				    int *frame_x,
347 				    int *frame_y);
348 
349 /**
350  * Set the max content size.
351  *
352  * This translates roughly to xdg_toplevel_set_max_size().
353  */
354 void
355 libdecor_frame_set_max_content_size(struct libdecor_frame *frame,
356 				    int content_width,
357 				    int content_height);
358 
359 /**
360  * Set the min content size.
361  *
362  * This translates roughly to xdg_toplevel_set_min_size().
363  */
364 void
365 libdecor_frame_set_min_content_size(struct libdecor_frame *frame,
366 				    int content_width,
367 				    int content_height);
368 
369 /**
370  * Initiate an interactive resize.
371  *
372  * This roughly translates to xdg_toplevel_resize().
373  */
374 void
375 libdecor_frame_resize(struct libdecor_frame *frame,
376 		      struct wl_seat *wl_seat,
377 		      uint32_t serial,
378 		      enum libdecor_resize_edge edge);
379 
380 /**
381  * Initiate an interactive move.
382  *
383  * This roughly translates to xdg_toplevel_move().
384  */
385 void
386 libdecor_frame_move(struct libdecor_frame *frame,
387 		    struct wl_seat *wl_seat,
388 		    uint32_t serial);
389 
390 /**
391  * Commit a new window state. This can be called on application driven resizes
392  * when the window is floating, or in response to received configurations, i.e.
393  * from e.g. interactive resizes or state changes.
394  */
395 void
396 libdecor_frame_commit(struct libdecor_frame *frame,
397 		      struct libdecor_state *state,
398 		      struct libdecor_configuration *configuration);
399 
400 /**
401  * Minimize the window.
402  *
403  * Roughly translates to xdg_toplevel_set_minimized().
404  */
405 void
406 libdecor_frame_set_minimized(struct libdecor_frame *frame);
407 
408 /**
409  * Maximize the window.
410  *
411  * Roughly translates to xdg_toplevel_set_maximized().
412  */
413 void
414 libdecor_frame_set_maximized(struct libdecor_frame *frame);
415 
416 /**
417  * Unmaximize the window.
418  *
419  * Roughly translates to xdg_toplevel_unset_maximized().
420  */
421 void
422 libdecor_frame_unset_maximized(struct libdecor_frame *frame);
423 
424 /**
425  * Fullscreen the window.
426  *
427  * Roughly translates to xdg_toplevel_set_fullscreen().
428  */
429 void
430 libdecor_frame_set_fullscreen(struct libdecor_frame *frame,
431 			      struct wl_output *output);
432 
433 /**
434  * Unfullscreen the window.
435  *
436  * Roughly translates to xdg_toplevel_unset_unfullscreen().
437  */
438 void
439 libdecor_frame_unset_fullscreen(struct libdecor_frame *frame);
440 
441 /**
442  * Return true if the window is floating.
443  *
444  * A window is floating when it's not maximized, tiled, fullscreen, or in any
445  * similar way with a fixed size and state.
446  */
447 bool
448 libdecor_frame_is_floating(struct libdecor_frame *frame);
449 
450 /**
451  * Close the window.
452  *
453  * Roughly translates to xdg_toplevel_close().
454  */
455 void
456 libdecor_frame_close(struct libdecor_frame *frame);
457 
458 /**
459  * Map the window.
460  *
461  * This will eventually result in the initial configure event.
462  */
463 void
464 libdecor_frame_map(struct libdecor_frame *frame);
465 
466 /**
467  * Get the associated xdg_surface for content wl_surface.
468  */
469 struct xdg_surface *
470 libdecor_frame_get_xdg_surface(struct libdecor_frame *frame);
471 
472 /**
473  * Get the associated xdg_toplevel for the content wl_surface.
474  */
475 struct xdg_toplevel *
476 libdecor_frame_get_xdg_toplevel(struct libdecor_frame *frame);
477 
478 /**
479  * Create a new content surface state.
480  */
481 struct libdecor_state *
482 libdecor_state_new(int width,
483 		   int height);
484 
485 /**
486  * Free a content surface state.
487  */
488 void
489 libdecor_state_free(struct libdecor_state *state);
490 
491 /**
492  * Get the expected size of the content for this configuration.
493  *
494  * If the configuration doesn't contain a size, false is returned.
495  */
496 bool
497 libdecor_configuration_get_content_size(struct libdecor_configuration *configuration,
498 					struct libdecor_frame *frame,
499 					int *width,
500 					int *height);
501 
502 /**
503  * Get the window state for this configuration.
504  *
505  * If the configuration doesn't contain any associated window state, false is
506  * returned, and the application should assume the window state remains
507  * unchanged.
508  */
509 bool
510 libdecor_configuration_get_window_state(struct libdecor_configuration *configuration,
511 					enum libdecor_window_state *window_state);
512 
513 #ifdef __cplusplus
514 }
515 #endif
516 
517 #endif /* LIBDECOR_H */
518