1 /*
2  * Copyright © 2014 Intel Corporation
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without
6  * fee, provided that the above copyright notice appear in all copies
7  * and that both that copyright notice and this permission notice
8  * appear in supporting documentation, and that the name of the
9  * copyright holders not be used in advertising or publicity
10  * pertaining to distribution of the software without specific,
11  * written prior permission.  The copyright holders make no
12  * representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied
14  * warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
21  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
22  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23  * SOFTWARE.
24  */
25 
26 #ifndef XWAYLAND_H
27 #define XWAYLAND_H
28 
29 #include <xwayland-config.h>
30 
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <errno.h>
34 
35 #include <wayland-client.h>
36 
37 #include <X11/X.h>
38 
39 #include <fb.h>
40 #include <input.h>
41 #include <dix.h>
42 #include <randrstr.h>
43 #include <exevents.h>
44 
45 #include "relative-pointer-unstable-v1-client-protocol.h"
46 #include "pointer-constraints-unstable-v1-client-protocol.h"
47 #include "tablet-unstable-v2-client-protocol.h"
48 #include "xwayland-keyboard-grab-unstable-v1-client-protocol.h"
49 #include "xdg-output-unstable-v1-client-protocol.h"
50 #include "linux-dmabuf-unstable-v1-client-protocol.h"
51 
52 struct xwl_format {
53     uint32_t format;
54     int num_modifiers;
55     uint64_t *modifiers;
56 };
57 
58 struct xwl_pixmap;
59 struct xwl_window;
60 struct xwl_screen;
61 
62 struct xwl_egl_backend {
63     /* Set by the backend if available */
64     Bool is_available;
65 
66     /* Called once for each interface in the global registry. Backends
67      * should use this to bind to any wayland interfaces they need.
68      */
69     Bool (*init_wl_registry)(struct xwl_screen *xwl_screen,
70                              struct wl_registry *wl_registry,
71                              uint32_t id, const char *name,
72                              uint32_t version);
73 
74     /* Check that the required Wayland interfaces are available.
75      */
76     Bool (*has_wl_interfaces)(struct xwl_screen *xwl_screen);
77 
78     /* Called before glamor has been initialized. Backends should setup a
79      * valid, glamor compatible EGL context in this hook.
80      */
81     Bool (*init_egl)(struct xwl_screen *xwl_screen);
82 
83     /* Called after glamor has been initialized, and after all of the
84      * common Xwayland DDX hooks have been connected. Backends should use
85      * this to setup any required wraps around X server callbacks like
86      * CreatePixmap.
87      */
88      Bool (*init_screen)(struct xwl_screen *xwl_screen);
89 
90      /* Called by Xwayland to retrieve a pointer to a valid wl_buffer for
91       * the given window/pixmap combo so that damage to the pixmap may be
92       * displayed on-screen. Backends should use this to create a new
93       * wl_buffer for a currently buffer-less pixmap, or simply return the
94       * pixmap they've prepared beforehand.
95       */
96      struct wl_buffer *(*get_wl_buffer_for_pixmap)(PixmapPtr pixmap,
97                                                    Bool *created);
98 
99      /* Called by Xwayland to perform any pre-wl_surface damage routines
100       * that are required by the backend. If your backend is poorly
101       * designed and lacks the ability to render directly to a surface,
102       * you should implement blitting from the glamor pixmap to the wayland
103       * pixmap here. Otherwise, this callback is optional.
104       */
105      void (*post_damage)(struct xwl_window *xwl_window,
106                          PixmapPtr pixmap, RegionPtr region);
107 
108      /* Called by Xwayland to confirm with the egl backend that the given
109       * pixmap is completely setup and ready for display on-screen. This
110       * callback is optional.
111       */
112      Bool (*allow_commits)(struct xwl_window *xwl_window);
113 };
114 
115 struct xwl_screen {
116     int width;
117     int height;
118     int depth;
119     ScreenPtr screen;
120     int expecting_event;
121     enum RootClipMode root_clip_mode;
122 
123     int wm_fd;
124     int listen_fds[5];
125     int listen_fd_count;
126     int rootless;
127     int glamor;
128     int present;
129 
130     CreateScreenResourcesProcPtr CreateScreenResources;
131     CloseScreenProcPtr CloseScreen;
132     RealizeWindowProcPtr RealizeWindow;
133     UnrealizeWindowProcPtr UnrealizeWindow;
134     DestroyWindowProcPtr DestroyWindow;
135     XYToWindowProcPtr XYToWindow;
136     SetWindowPixmapProcPtr SetWindowPixmap;
137 
138     struct xorg_list output_list;
139     struct xorg_list seat_list;
140     struct xorg_list damage_window_list;
141 
142     int wayland_fd;
143     struct wl_display *display;
144     struct wl_registry *registry;
145     struct wl_registry *input_registry;
146     struct wl_compositor *compositor;
147     struct zwp_tablet_manager_v2 *tablet_manager;
148     struct wl_shm *shm;
149     struct wl_shell *shell;
150     struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
151     struct zwp_pointer_constraints_v1 *pointer_constraints;
152     struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
153     struct zxdg_output_manager_v1 *xdg_output_manager;
154     uint32_t serial;
155 
156 #define XWL_FORMAT_ARGB8888 (1 << 0)
157 #define XWL_FORMAT_XRGB8888 (1 << 1)
158 #define XWL_FORMAT_RGB565   (1 << 2)
159 
160     int prepare_read;
161     int wait_flush;
162 
163     uint32_t num_formats;
164     struct xwl_format *formats;
165     void *egl_display, *egl_context;
166 
167     struct xwl_egl_backend gbm_backend;
168     struct xwl_egl_backend eglstream_backend;
169     /* pointer to the current backend for creating pixmaps on wayland */
170     struct xwl_egl_backend *egl_backend;
171 
172     struct glamor_context *glamor_ctx;
173 
174     Atom allow_commits_prop;
175 };
176 
177 struct xwl_window {
178     struct xwl_screen *xwl_screen;
179     struct wl_surface *surface;
180     struct wl_shell_surface *shell_surface;
181     WindowPtr window;
182     struct xorg_list link_damage;
183     struct wl_callback *frame_callback;
184     Bool allow_commits;
185 #ifdef GLAMOR_HAS_GBM
186     struct xorg_list frame_callback_list;
187     Bool present_flipped;
188 #endif
189 };
190 
191 #ifdef GLAMOR_HAS_GBM
192 struct xwl_present_window {
193     struct xwl_screen *xwl_screen;
194     struct xwl_present_event *sync_flip;
195     WindowPtr window;
196     struct xorg_list frame_callback_list;
197 
198     uint64_t msc;
199     uint64_t ust;
200 
201     OsTimerPtr frame_timer;
202 
203     struct wl_callback *sync_callback;
204 
205     struct xorg_list event_list;
206     struct xorg_list release_queue;
207 };
208 
209 struct xwl_present_event {
210     uint64_t event_id;
211     uint64_t target_msc;
212 
213     Bool abort;
214     Bool pending;
215     Bool buffer_released;
216 
217     struct xwl_present_window *xwl_present_window;
218     PixmapPtr pixmap;
219 
220     struct xorg_list list;
221 };
222 #endif
223 
224 #define MODIFIER_META 0x01
225 
226 struct xwl_touch {
227     struct xwl_window *window;
228     int32_t id;
229     int x, y;
230     struct xorg_list link_touch;
231 };
232 
233 struct xwl_pointer_warp_emulator {
234     struct xwl_seat *xwl_seat;
235     struct xwl_window *locked_window;
236     struct zwp_locked_pointer_v1 *locked_pointer;
237 };
238 
239 struct xwl_cursor {
240     void (* update_proc) (struct xwl_cursor *);
241     struct wl_surface *surface;
242     struct wl_callback *frame_cb;
243     Bool needs_update;
244 };
245 
246 struct xwl_seat {
247     DeviceIntPtr pointer;
248     DeviceIntPtr relative_pointer;
249     DeviceIntPtr keyboard;
250     DeviceIntPtr touch;
251     DeviceIntPtr stylus;
252     DeviceIntPtr eraser;
253     DeviceIntPtr puck;
254     struct xwl_screen *xwl_screen;
255     struct wl_seat *seat;
256     struct wl_pointer *wl_pointer;
257     struct zwp_relative_pointer_v1 *wp_relative_pointer;
258     struct wl_keyboard *wl_keyboard;
259     struct wl_touch *wl_touch;
260     struct zwp_tablet_seat_v2 *tablet_seat;
261     struct wl_array keys;
262     struct xwl_window *focus_window;
263     struct xwl_window *tablet_focus_window;
264     uint32_t id;
265     uint32_t pointer_enter_serial;
266     struct xorg_list link;
267     CursorPtr x_cursor;
268     struct xwl_cursor cursor;
269     WindowPtr last_xwindow;
270 
271     struct xorg_list touches;
272 
273     size_t keymap_size;
274     char *keymap;
275     struct wl_surface *keyboard_focus;
276 
277     struct xorg_list axis_discrete_pending;
278     struct xorg_list sync_pending;
279 
280     struct xwl_pointer_warp_emulator *pointer_warp_emulator;
281 
282     struct xwl_window *cursor_confinement_window;
283     struct zwp_confined_pointer_v1 *confined_pointer;
284 
285     struct {
286         Bool has_absolute;
287         wl_fixed_t x;
288         wl_fixed_t y;
289 
290         Bool has_relative;
291         double dx;
292         double dy;
293         double dx_unaccel;
294         double dy_unaccel;
295     } pending_pointer_event;
296 
297     struct xorg_list tablets;
298     struct xorg_list tablet_tools;
299     struct xorg_list tablet_pads;
300     struct zwp_xwayland_keyboard_grab_v1 *keyboard_grab;
301 };
302 
303 struct xwl_tablet {
304     struct xorg_list link;
305     struct zwp_tablet_v2 *tablet;
306     struct xwl_seat *seat;
307 };
308 
309 struct xwl_tablet_tool {
310     struct xorg_list link;
311     struct zwp_tablet_tool_v2 *tool;
312     struct xwl_seat *seat;
313 
314     DeviceIntPtr xdevice;
315     uint32_t proximity_in_serial;
316     double x;
317     double y;
318     uint32_t pressure;
319     double tilt_x;
320     double tilt_y;
321     double rotation;
322     double slider;
323 
324     uint32_t buttons_now,
325              buttons_prev;
326 
327     int32_t wheel_clicks;
328 
329     struct xwl_cursor cursor;
330 };
331 
332 struct xwl_tablet_pad_ring {
333     unsigned int index;
334     struct xorg_list link;
335     struct xwl_tablet_pad_group *group;
336     struct zwp_tablet_pad_ring_v2 *ring;
337 };
338 
339 struct xwl_tablet_pad_strip {
340     unsigned int index;
341     struct xorg_list link;
342     struct xwl_tablet_pad_group *group;
343     struct zwp_tablet_pad_strip_v2 *strip;
344 };
345 
346 struct xwl_tablet_pad_group {
347     struct xorg_list link;
348     struct xwl_tablet_pad *pad;
349     struct zwp_tablet_pad_group_v2 *group;
350 
351     struct xorg_list pad_group_ring_list;
352     struct xorg_list pad_group_strip_list;
353 };
354 
355 struct xwl_tablet_pad {
356     struct xorg_list link;
357     struct zwp_tablet_pad_v2 *pad;
358     struct xwl_seat *seat;
359 
360     DeviceIntPtr xdevice;
361 
362     unsigned int nbuttons;
363     struct xorg_list pad_group_list;
364 };
365 
366 struct xwl_output {
367     struct xorg_list link;
368     struct wl_output *output;
369     struct zxdg_output_v1 *xdg_output;
370     uint32_t server_output_id;
371     struct xwl_screen *xwl_screen;
372     RROutputPtr randr_output;
373     RRCrtcPtr randr_crtc;
374     int32_t x, y, width, height, refresh;
375     Rotation rotation;
376     Bool wl_output_done;
377     Bool xdg_output_done;
378 };
379 
380 void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
381 
382 void xwl_sync_events (struct xwl_screen *xwl_screen);
383 
384 void xwl_screen_roundtrip (struct xwl_screen *xwl_screen);
385 
386 Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);
387 
388 struct xwl_screen *xwl_screen_get(ScreenPtr screen);
389 
390 void xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *tool);
391 void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
392 
393 void xwl_seat_destroy(struct xwl_seat *xwl_seat);
394 
395 void xwl_seat_clear_touch(struct xwl_seat *xwl_seat, WindowPtr window);
396 
397 void xwl_seat_emulate_pointer_warp(struct xwl_seat *xwl_seat,
398                                    struct xwl_window *xwl_window,
399                                    SpritePtr sprite,
400                                    int x, int y);
401 
402 void xwl_seat_destroy_pointer_warp_emulator(struct xwl_seat *xwl_seat);
403 
404 void xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat);
405 
406 void xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
407                               struct xwl_window *xwl_window);
408 void xwl_seat_unconfine_pointer(struct xwl_seat *xwl_seat);
409 
410 Bool xwl_screen_init_output(struct xwl_screen *xwl_screen);
411 
412 struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen,
413                                      uint32_t id);
414 
415 void xwl_output_destroy(struct xwl_output *xwl_output);
416 
417 void xwl_output_remove(struct xwl_output *xwl_output);
418 
419 RRModePtr xwayland_cvt(int HDisplay, int VDisplay,
420                        float VRefresh, Bool Reduced, Bool Interlaced);
421 
422 void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap);
423 struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap);
424 
425 struct xwl_window *xwl_window_from_window(WindowPtr window);
426 
427 Bool xwl_shm_create_screen_resources(ScreenPtr screen);
428 PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height,
429                                 int depth, unsigned int hint);
430 Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap);
431 struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap);
432 
433 #ifdef XWL_HAS_GLAMOR
434 void xwl_glamor_init_backends(struct xwl_screen *xwl_screen,
435                               Bool use_eglstream);
436 void xwl_glamor_select_backend(struct xwl_screen *xwl_screen,
437                                Bool use_eglstream);
438 Bool xwl_glamor_init(struct xwl_screen *xwl_screen);
439 
440 Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen,
441                                   uint32_t id, uint32_t version);
442 Bool xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen,
443                                      uint32_t id, uint32_t version);
444 struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap,
445                                                   Bool *created);
446 void xwl_glamor_init_wl_registry(struct xwl_screen *xwl_screen,
447                                  struct wl_registry *registry,
448                                  uint32_t id, const char *interface,
449                                  uint32_t version);
450 Bool xwl_glamor_has_wl_interfaces(struct xwl_screen *xwl_screen,
451                                  struct xwl_egl_backend *xwl_egl_backend);
452 void xwl_glamor_post_damage(struct xwl_window *xwl_window,
453                             PixmapPtr pixmap, RegionPtr region);
454 Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
455 void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
456 
457 #ifdef GLAMOR_HAS_GBM
458 void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
459 Bool xwl_present_init(ScreenPtr screen);
460 void xwl_present_cleanup(WindowPtr window);
461 void xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window);
462 #endif /* GLAMOR_HAS_GBM */
463 
464 #ifdef XV
465 /* glamor Xv Adaptor */
466 Bool xwl_glamor_xv_init(ScreenPtr pScreen);
467 #endif /* XV */
468 
469 #endif /* XWL_HAS_GLAMOR */
470 
471 void xwl_screen_release_tablet_manager(struct xwl_screen *xwl_screen);
472 
473 void xwl_screen_init_xdg_output(struct xwl_screen *xwl_screen);
474 
475 #ifdef XF86VIDMODE
476 void xwlVidModeExtensionInit(void);
477 #endif
478 
479 #ifdef GLAMOR_HAS_GBM
480 void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen);
481 #else
xwl_glamor_init_gbm(struct xwl_screen * xwl_screen)482 static inline void xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
483 {
484 }
485 #endif
486 
487 #ifdef XWL_HAS_EGLSTREAM
488 void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen);
489 #else
xwl_glamor_init_eglstream(struct xwl_screen * xwl_screen)490 static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
491 {
492 }
493 #endif
494 
495 #endif
496