1 /*
2  * Copyright © 2014-2015 David FORT <contact@hardening-consulting.com>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22 
23 #ifndef UWAC_H_
24 #define UWAC_H_
25 
26 #include <wayland-client.h>
27 #include <stdbool.h>
28 
29 #if __GNUC__ >= 4
30 #define UWAC_API __attribute__((visibility("default")))
31 #else
32 #define UWAC_API
33 #endif
34 
35 typedef struct uwac_position UwacPosition;
36 typedef struct uwac_size UwacSize;
37 typedef struct uwac_display UwacDisplay;
38 typedef struct uwac_output UwacOutput;
39 typedef struct uwac_window UwacWindow;
40 typedef struct uwac_seat UwacSeat;
41 typedef uint32_t UwacSeatId;
42 
43 /** @brief error codes */
44 typedef enum
45 {
46 	UWAC_SUCCESS = 0,
47 	UWAC_ERROR_NOMEMORY,
48 	UWAC_ERROR_UNABLE_TO_CONNECT,
49 	UWAC_ERROR_INVALID_DISPLAY,
50 	UWAC_NOT_ENOUGH_RESOURCES,
51 	UWAC_TIMEDOUT,
52 	UWAC_NOT_FOUND,
53 	UWAC_ERROR_CLOSED,
54 	UWAC_ERROR_INTERNAL,
55 
56 	UWAC_ERROR_LAST,
57 } UwacReturnCode;
58 
59 /** @brief input modifiers */
60 enum
61 {
62 	UWAC_MOD_SHIFT_MASK = 0x01,
63 	UWAC_MOD_ALT_MASK = 0x02,
64 	UWAC_MOD_CONTROL_MASK = 0x04,
65 	UWAC_MOD_CAPS_MASK = 0x08,
66 	UWAC_MOD_NUM_MASK = 0x10,
67 };
68 
69 /** @brief a position */
70 struct uwac_position
71 {
72 	int x;
73 	int y;
74 };
75 
76 /** @brief a rectangle size measure */
77 struct uwac_size
78 {
79 	int width;
80 	int height;
81 };
82 
83 /** @brief event types */
84 enum
85 {
86 	UWAC_EVENT_NEW_SEAT = 0,
87 	UWAC_EVENT_REMOVED_SEAT,
88 	UWAC_EVENT_NEW_OUTPUT,
89 	UWAC_EVENT_CONFIGURE,
90 	UWAC_EVENT_POINTER_ENTER,
91 	UWAC_EVENT_POINTER_LEAVE,
92 	UWAC_EVENT_POINTER_MOTION,
93 	UWAC_EVENT_POINTER_BUTTONS,
94 	UWAC_EVENT_POINTER_AXIS,
95 	UWAC_EVENT_KEYBOARD_ENTER,
96 	UWAC_EVENT_KEY,
97 	UWAC_EVENT_TOUCH_FRAME_BEGIN,
98 	UWAC_EVENT_TOUCH_UP,
99 	UWAC_EVENT_TOUCH_DOWN,
100 	UWAC_EVENT_TOUCH_MOTION,
101 	UWAC_EVENT_TOUCH_CANCEL,
102 	UWAC_EVENT_TOUCH_FRAME_END,
103 	UWAC_EVENT_FRAME_DONE,
104 	UWAC_EVENT_CLOSE,
105 	UWAC_EVENT_CLIPBOARD_AVAILABLE,
106 	UWAC_EVENT_CLIPBOARD_SELECT,
107 	UWAC_EVENT_CLIPBOARD_OFFER,
108 	UWAC_EVENT_OUTPUT_GEOMETRY,
109 	UWAC_EVENT_KEYBOARD_MODIFIERS,
110 	UWAC_EVENT_POINTER_AXIS_DISCRETE
111 };
112 
113 /** @brief window states */
114 enum
115 {
116 	UWAC_WINDOW_MAXIMIZED = 0x1,
117 	UWAC_WINDOW_RESIZING = 0x2,
118 	UWAC_WINDOW_FULLSCREEN = 0x4,
119 	UWAC_WINDOW_ACTIVATED = 0x8,
120 };
121 
122 struct uwac_new_output_event
123 {
124 	int type;
125 	UwacOutput* output;
126 };
127 typedef struct uwac_new_output_event UwacOutputNewEvent;
128 
129 struct uwac_new_seat_event
130 {
131 	int type;
132 	UwacSeat* seat;
133 };
134 typedef struct uwac_new_seat_event UwacSeatNewEvent;
135 
136 struct uwac_removed_seat_event
137 {
138 	int type;
139 	UwacSeatId id;
140 };
141 typedef struct uwac_removed_seat_event UwacSeatRemovedEvent;
142 
143 struct uwac_keyboard_enter_event
144 {
145 	int type;
146 	UwacWindow* window;
147 	UwacSeat* seat;
148 };
149 typedef struct uwac_keyboard_enter_event UwacKeyboardEnterLeaveEvent;
150 
151 struct uwac_keyboard_modifiers_event
152 {
153 	int type;
154 	uint32_t modifiers;
155 };
156 typedef struct uwac_keyboard_modifiers_event UwacKeyboardModifiersEvent;
157 
158 struct uwac_pointer_enter_event
159 {
160 	int type;
161 	UwacWindow* window;
162 	UwacSeat* seat;
163 	uint32_t x, y;
164 };
165 typedef struct uwac_pointer_enter_event UwacPointerEnterLeaveEvent;
166 
167 struct uwac_pointer_motion_event
168 {
169 	int type;
170 	UwacWindow* window;
171 	UwacSeat* seat;
172 	uint32_t x, y;
173 };
174 typedef struct uwac_pointer_motion_event UwacPointerMotionEvent;
175 
176 struct uwac_pointer_button_event
177 {
178 	int type;
179 	UwacWindow* window;
180 	UwacSeat* seat;
181 	uint32_t x, y;
182 	uint32_t button;
183 	enum wl_pointer_button_state state;
184 };
185 typedef struct uwac_pointer_button_event UwacPointerButtonEvent;
186 
187 struct uwac_pointer_axis_event
188 {
189 	int type;
190 	UwacWindow* window;
191 	UwacSeat* seat;
192 	uint32_t x, y;
193 	uint32_t axis;
194 	wl_fixed_t value;
195 };
196 typedef struct uwac_pointer_axis_event UwacPointerAxisEvent;
197 
198 struct uwac_touch_frame_event
199 {
200 	int type;
201 	UwacWindow* window;
202 	UwacSeat* seat;
203 };
204 typedef struct uwac_touch_frame_event UwacTouchFrameBegin;
205 typedef struct uwac_touch_frame_event UwacTouchFrameEnd;
206 typedef struct uwac_touch_frame_event UwacTouchCancel;
207 
208 struct uwac_touch_data
209 {
210 	int type;
211 	UwacWindow* window;
212 	UwacSeat* seat;
213 	int32_t id;
214 	wl_fixed_t x;
215 	wl_fixed_t y;
216 };
217 typedef struct uwac_touch_data UwacTouchUp;
218 typedef struct uwac_touch_data UwacTouchDown;
219 typedef struct uwac_touch_data UwacTouchMotion;
220 
221 struct uwac_frame_done_event
222 {
223 	int type;
224 	UwacWindow* window;
225 };
226 typedef struct uwac_frame_done_event UwacFrameDoneEvent;
227 
228 struct uwac_configure_event
229 {
230 	int type;
231 	UwacWindow* window;
232 	int32_t width;
233 	int32_t height;
234 	int states;
235 };
236 typedef struct uwac_configure_event UwacConfigureEvent;
237 
238 struct uwac_key_event
239 {
240 	int type;
241 	UwacWindow* window;
242 	uint32_t raw_key;
243 	uint32_t sym;
244 	bool pressed;
245 };
246 typedef struct uwac_key_event UwacKeyEvent;
247 
248 struct uwac_close_event
249 {
250 	int type;
251 	UwacWindow* window;
252 };
253 typedef struct uwac_close_event UwacCloseEvent;
254 
255 struct uwac_clipboard_event
256 {
257 	int type;
258 	UwacSeat* seat;
259 	char mime[64];
260 };
261 typedef struct uwac_clipboard_event UwacClipboardEvent;
262 
263 struct uwac_output_geometry_event
264 {
265 	int type;
266 	UwacOutput* output;
267 	int x;
268 	int y;
269 	int physical_width;
270 	int physical_height;
271 	int subpixel;
272 	const char* make;
273 	const char* model;
274 	int transform;
275 };
276 typedef struct uwac_output_geometry_event UwacOutputGeometryEvent;
277 
278 /** @brief */
279 union uwac_event {
280 	int type;
281 	UwacOutputNewEvent output_new;
282 	UwacOutputGeometryEvent output_geometry;
283 	UwacSeatNewEvent seat_new;
284 	UwacSeatRemovedEvent seat_removed;
285 	UwacPointerEnterLeaveEvent mouse_enter_leave;
286 	UwacPointerMotionEvent mouse_motion;
287 	UwacPointerButtonEvent mouse_button;
288 	UwacPointerAxisEvent mouse_axis;
289 	UwacKeyboardEnterLeaveEvent keyboard_enter_leave;
290 	UwacKeyboardModifiersEvent keyboard_modifiers;
291 	UwacClipboardEvent clipboard;
292 	UwacKeyEvent key;
293 	UwacTouchFrameBegin touchFrameBegin;
294 	UwacTouchUp touchUp;
295 	UwacTouchDown touchDown;
296 	UwacTouchMotion touchMotion;
297 	UwacTouchFrameEnd touchFrameEnd;
298 	UwacTouchCancel touchCancel;
299 	UwacFrameDoneEvent frame_done;
300 	UwacConfigureEvent configure;
301 	UwacCloseEvent close;
302 };
303 typedef union uwac_event UwacEvent;
304 
305 typedef bool (*UwacErrorHandler)(UwacDisplay* d, UwacReturnCode code, const char* msg, ...);
306 typedef void (*UwacDataTransferHandler)(UwacSeat* seat, void* context, const char* mime, int fd);
307 typedef void (*UwacCancelDataTransferHandler)(UwacSeat* seat, void* context);
308 
309 #ifdef __cplusplus
310 extern "C"
311 {
312 #endif
313 
314 	/**
315 	 *	install a handler that will be called when UWAC encounter internal errors. The
316 	 *	handler is supposed to answer if the execution can continue. I can also be used
317 	 *	to log things.
318 	 *
319 	 * @param handler
320 	 */
321 	UWAC_API void UwacInstallErrorHandler(UwacErrorHandler handler);
322 
323 	/**
324 	 *	Opens the corresponding wayland display, using NULL you will open the default
325 	 *	display.
326 	 *
327 	 * @param name the name of the display to open
328 	 * @return the created UwacDisplay object
329 	 */
330 	UWAC_API UwacDisplay* UwacOpenDisplay(const char* name, UwacReturnCode* err);
331 
332 	/**
333 	 *	closes the corresponding UwacDisplay
334 	 *
335 	 * @param pdisplay a pointer on the display to close
336 	 * @return UWAC_SUCCESS if the operation was successful, the corresponding error otherwise
337 	 */
338 	UWAC_API UwacReturnCode UwacCloseDisplay(UwacDisplay** pdisplay);
339 
340 	/**
341 	 * Returns the file descriptor associated with the UwacDisplay, this is useful when
342 	 * you want to poll that file descriptor for activity.
343 	 *
344 	 * @param display an opened UwacDisplay
345 	 * @return the corresponding descriptor
346 	 */
347 	UWAC_API int UwacDisplayGetFd(UwacDisplay* display);
348 
349 	/**
350 	 *	Returns a human readable form of a Uwac error code
351 	 *
352 	 * @param error the error number
353 	 * @return the associated string
354 	 */
355 	UWAC_API const char* UwacErrorString(UwacReturnCode error);
356 
357 	/**
358 	 * returns the last error that occurred on a display
359 	 *
360 	 * @param display the display
361 	 * @return the last error that have been set for this display
362 	 */
363 	UWAC_API UwacReturnCode UwacDisplayGetLastError(const UwacDisplay* display);
364 
365 	/**
366 	 * retrieves the version of a given interface
367 	 *
368 	 * @param display the display connection
369 	 * @param name the name of the interface
370 	 * @param version the output variable for the version
371 	 * @return UWAC_SUCCESS if the interface was found, UWAC_NOT_FOUND otherwise
372 	 */
373 	UWAC_API UwacReturnCode UwacDisplayQueryInterfaceVersion(const UwacDisplay* display,
374 	                                                         const char* name, uint32_t* version);
375 
376 	/**
377 	 *	returns the number SHM formats that have been reported by the compositor
378 	 *
379 	 * @param display a connected UwacDisplay
380 	 * @return the number of SHM formats supported
381 	 */
382 	UWAC_API uint32_t UwacDisplayQueryGetNbShmFormats(UwacDisplay* display);
383 
384 	/**
385 	 *	returns the supported ShmFormats
386 	 *
387 	 * @param display a connected UwacDisplay
388 	 * @param formats a pointer on an array of wl_shm_format with enough place for formats_size
389 	 *items
390 	 * @param formats_size the size of the formats array
391 	 * @param filled the number of filled entries in the formats array
392 	 * @return UWAC_SUCCESS on success, an error otherwise
393 	 */
394 	UWAC_API UwacReturnCode UwacDisplayQueryShmFormats(const UwacDisplay* display,
395 	                                                   enum wl_shm_format* formats,
396 	                                                   int formats_size, int* filled);
397 
398 	/**
399 	 *	returns the number of registered outputs
400 	 *
401 	 * @param display the display to query
402 	 * @return the number of outputs
403 	 */
404 	UWAC_API uint32_t UwacDisplayGetNbOutputs(const UwacDisplay* display);
405 
406 	/**
407 	 *	retrieve a particular UwacOutput object
408 	 *
409 	 * @param display the display to query
410 	 * @param index index of the output
411 	 * @return the given UwacOutput, NULL if something failed (so you should query
412 	 *UwacDisplayGetLastError() to have the reason)
413 	 */
414 	UWAC_API const UwacOutput* UwacDisplayGetOutput(UwacDisplay* display, int index);
415 
416 	/**
417 	 * retrieve the resolution of a given UwacOutput
418 	 *
419 	 * @param output the UwacOutput
420 	 * @param resolution a pointer on the
421 	 * @return UWAC_SUCCESS on success
422 	 */
423 	UWAC_API UwacReturnCode UwacOutputGetResolution(const UwacOutput* output, UwacSize* resolution);
424 
425 	/**
426 	 * retrieve the position of a given UwacOutput
427 	 *
428 	 * @param output the UwacOutput
429 	 * @param pos a pointer on the target position
430 	 * @return UWAC_SUCCESS on success
431 	 */
432 	UWAC_API UwacReturnCode UwacOutputGetPosition(const UwacOutput* output, UwacPosition* pos);
433 
434 	/**
435 	 *	creates a window using a SHM surface
436 	 *
437 	 * @param display the display to attach the window to
438 	 * @param width the width of the window
439 	 * @param height the heigh of the window
440 	 * @param format format to use for the SHM surface
441 	 * @return the created UwacWindow, NULL if something failed (use UwacDisplayGetLastError() to
442 	 *know more about this)
443 	 */
444 	UWAC_API UwacWindow* UwacCreateWindowShm(UwacDisplay* display, uint32_t width, uint32_t height,
445 	                                         enum wl_shm_format format);
446 
447 	/**
448 	 *	destroys the corresponding UwacWindow
449 	 *
450 	 * @param window a pointer on the UwacWindow to destroy
451 	 * @return if the operation completed successfully
452 	 */
453 	UWAC_API UwacReturnCode UwacDestroyWindow(UwacWindow** window);
454 
455 	/**
456 	 *	Sets the region that should be considered opaque to the compositor.
457 	 *
458 	 * @param window the UwacWindow
459 	 * @param x
460 	 * @param y
461 	 * @param width
462 	 * @param height
463 	 * @return UWAC_SUCCESS on success, an error otherwise
464 	 */
465 	UWAC_API UwacReturnCode UwacWindowSetOpaqueRegion(UwacWindow* window, uint32_t x, uint32_t y,
466 	                                                  uint32_t width, uint32_t height);
467 
468 	/**
469 	 *	Sets the region of the window that can trigger input events
470 	 *
471 	 * @param window the UwacWindow
472 	 * @param x
473 	 * @param y
474 	 * @param width
475 	 * @param height
476 	 * @return
477 	 */
478 	UWAC_API UwacReturnCode UwacWindowSetInputRegion(UwacWindow* window, uint32_t x, uint32_t y,
479 	                                                 uint32_t width, uint32_t height);
480 
481 	/**
482 	 *	retrieves a pointer on the current window content to draw a frame
483 	 * @param window the UwacWindow
484 	 * @return a pointer on the current window content
485 	 */
486 	UWAC_API void* UwacWindowGetDrawingBuffer(UwacWindow* window);
487 
488 	/**
489 	 *	sets a rectangle as dirty for the next frame of a window
490 	 *
491 	 * @param window the UwacWindow
492 	 * @param x left coordinate
493 	 * @param y top coordinate
494 	 * @param width the width of the dirty rectangle
495 	 * @param height the height of the dirty rectangle
496 	 * @return UWAC_SUCCESS on success, an Uwac error otherwise
497 	 */
498 	UWAC_API UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y,
499 	                                            uint32_t width, uint32_t height);
500 
501 	/**
502 	 *	returns the geometry of the given UwacWindow buffer
503 	 *
504 	 * @param window   the UwacWindow
505 	 * @param geometry the geometry to fill
506 	 * @param stride   the length of a buffer line in bytes
507 	 * @return UWAC_SUCCESS on success, an Uwac error otherwise
508 	 */
509 	UWAC_API UwacReturnCode UwacWindowGetDrawingBufferGeometry(UwacWindow* window,
510 	                                                           UwacSize* geometry, size_t* stride);
511 
512 	/**
513 	 *	Sends a frame to the compositor with the content of the drawing buffer
514 	 *
515 	 * @param window the UwacWindow to refresh
516 	 * @param copyContentForNextFrame if true the content to display is copied in the next drawing
517 	 *buffer
518 	 * @return UWAC_SUCCESS if the operation was successful
519 	 */
520 	UWAC_API UwacReturnCode UwacWindowSubmitBuffer(UwacWindow* window,
521 	                                               bool copyContentForNextFrame);
522 
523 	/**
524 	 *	returns the geometry of the given UwacWindows
525 	 *
526 	 * @param window the UwacWindow
527 	 * @param geometry the geometry to fill
528 	 * @return UWAC_SUCCESS on success, an Uwac error otherwise
529 	 */
530 	UWAC_API UwacReturnCode UwacWindowGetGeometry(UwacWindow* window, UwacSize* geometry);
531 
532 	/**
533 	 *	Sets or unset the fact that the window is set fullscreen. After this call the
534 	 *	application should get prepared to receive a configure event. The output is used
535 	 *	only when going fullscreen, it is optional and not used when exiting fullscreen.
536 	 *
537 	 * @param window the UwacWindow
538 	 * @param output an optional UwacOutput to put the window fullscreen on
539 	 * @param isFullscreen set or unset fullscreen
540 	 * @return UWAC_SUCCESS if the operation was a success
541 	 */
542 	UWAC_API UwacReturnCode UwacWindowSetFullscreenState(UwacWindow* window, UwacOutput* output,
543 	                                                     bool isFullscreen);
544 
545 	/**
546 	 *	When possible (depending on the shell) sets the title of the UwacWindow
547 	 *
548 	 * @param window the UwacWindow
549 	 * @param name title
550 	 */
551 	UWAC_API void UwacWindowSetTitle(UwacWindow* window, const char* name);
552 
553 	/**
554 	 *
555 	 * @param display
556 	 * @param timeout
557 	 * @return
558 	 */
559 	UWAC_API int UwacDisplayDispatch(UwacDisplay* display, int timeout);
560 
561 	/**
562 	 *	Returns if you have some pending events, and you can UwacNextEvent() without blocking
563 	 *
564 	 * @param display the UwacDisplay
565 	 * @return if there's some pending events
566 	 */
567 	UWAC_API bool UwacHasEvent(UwacDisplay* display);
568 
569 	/** Waits until an event occurs, and when it's there copy the event from the queue to
570 	 * event.
571 	 *
572 	 * @param display the Uwac display
573 	 * @param event the event to fill
574 	 * @return if the operation completed successfully
575 	 */
576 	UWAC_API UwacReturnCode UwacNextEvent(UwacDisplay* display, UwacEvent* event);
577 
578 	/**
579 	 * returns the name of the given UwacSeat
580 	 *
581 	 * @param seat the UwacSeat
582 	 * @return the name of the seat
583 	 */
584 	UWAC_API const char* UwacSeatGetName(const UwacSeat* seat);
585 
586 	/**
587 	 * returns the id of the given UwacSeat
588 	 *
589 	 * @param seat the UwacSeat
590 	 * @return the id of the seat
591 	 */
592 	UWAC_API UwacSeatId UwacSeatGetId(const UwacSeat* seat);
593 
594 	/**
595 	 *
596 	 */
597 	UWAC_API UwacReturnCode UwacClipboardOfferDestroy(UwacSeat* seat);
598 	UWAC_API UwacReturnCode UwacClipboardOfferCreate(UwacSeat* seat, const char* mime);
599 	UWAC_API UwacReturnCode UwacClipboardOfferAnnounce(UwacSeat* seat, void* context,
600 	                                                   UwacDataTransferHandler transfer,
601 	                                                   UwacCancelDataTransferHandler cancel);
602 	UWAC_API void* UwacClipboardDataGet(UwacSeat* seat, const char* mime, size_t* size);
603 
604 	/**
605 	 * Inhibits or restores keyboard shortcuts.
606 	 *
607 	 * @param seat    The UwacSeat to inhibit the shortcuts for
608 	 * @param inhibit Inhibit or restore keyboard shortcuts
609 	 *
610 	 * @return UWAC_SUCCESS or an appropriate error code.
611 	 */
612 	UWAC_API UwacReturnCode UwacSeatInhibitShortcuts(UwacSeat* seat, bool inhibit);
613 
614 	/**
615 	 * @brief UwacSeatSetMouseCursor Sets the specified image as the new mouse cursor.
616 	 *                               Special values: If data == NULL && lenght == 0
617 	 *                               the cursor is hidden, if data == NULL && length != 0
618 	 *                               the default system cursor is used.
619 	 *
620 	 * @param seat   The UwacSeat to apply the cursor image to
621 	 * @param data   A pointer to the image data
622 	 * @param length The size of the image data
623 	 * @param width  The image width in pixel
624 	 * @param height The image height in pixel
625 	 * @param hot_x  The hotspot horizontal offset in pixel
626 	 * @param hot_y  The hotspot vertical offset in pixel
627 	 *
628 	 * @return UWAC_SUCCESS if successful, an appropriate error otherwise.
629 	 */
630 	UWAC_API UwacReturnCode UwacSeatSetMouseCursor(UwacSeat* seat, const void* data, size_t length,
631 	                                               size_t width, size_t height, size_t hot_x,
632 	                                               size_t hot_y);
633 
634 #ifdef __cplusplus
635 }
636 #endif
637 
638 #endif /* UWAC_H_ */
639