1*4882a593SmuzhiyunFrom 75c7ee95b6d561ee0030cfe5d7680b1fb48041b1 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Thu, 5 May 2022 17:56:46 +0800
4*4882a593SmuzhiyunSubject: [PATCH 32/41] waylandsink: Support pointer and touch
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunBased on weston's client window and simple-egl.
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9*4882a593Smuzhiyun---
10*4882a593Smuzhiyun gst-libs/gst/wayland/gstwldisplay.c | 293 ++++++++++++++++++++++++++++
11*4882a593Smuzhiyun gst-libs/gst/wayland/gstwldisplay.h |   4 +
12*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlwindow.c  |  17 ++
13*4882a593Smuzhiyun gst-libs/gst/wayland/gstwlwindow.h  |   4 +
14*4882a593Smuzhiyun gst-libs/gst/wayland/meson.build    |   7 +-
15*4882a593Smuzhiyun 5 files changed, 322 insertions(+), 3 deletions(-)
16*4882a593Smuzhiyun
17*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwldisplay.c b/gst-libs/gst/wayland/gstwldisplay.c
18*4882a593Smuzhiyunindex 3e11211..b860a8c 100644
19*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwldisplay.c
20*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwldisplay.c
21*4882a593Smuzhiyun@@ -23,6 +23,7 @@
22*4882a593Smuzhiyun #endif
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #include "gstwldisplay.h"
25*4882a593Smuzhiyun+#include "gstwlwindow.h"
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun #include "fullscreen-shell-unstable-v1-client-protocol.h"
28*4882a593Smuzhiyun #include "linux-dmabuf-unstable-v1-client-protocol.h"
29*4882a593Smuzhiyun@@ -30,6 +31,9 @@
30*4882a593Smuzhiyun #include "xdg-shell-client-protocol.h"
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include <errno.h>
33*4882a593Smuzhiyun+#include <linux/input.h>
34*4882a593Smuzhiyun+
35*4882a593Smuzhiyun+#include <wayland-cursor.h>
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define GST_CAT_DEFAULT gst_wl_display_debug
38*4882a593Smuzhiyun GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
39*4882a593Smuzhiyun@@ -41,6 +45,13 @@ typedef struct _GstWlDisplayPrivate
40*4882a593Smuzhiyun   struct wl_display *display_wrapper;
41*4882a593Smuzhiyun   struct wl_event_queue *queue;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun+  struct wl_list input_list;
44*4882a593Smuzhiyun+
45*4882a593Smuzhiyun+  struct wl_cursor_theme *cursor_theme;
46*4882a593Smuzhiyun+  struct wl_cursor *default_cursor;
47*4882a593Smuzhiyun+  struct wl_surface *cursor_surface;
48*4882a593Smuzhiyun+  struct wl_surface *touch_surface;
49*4882a593Smuzhiyun+
50*4882a593Smuzhiyun   /* globals */
51*4882a593Smuzhiyun   struct wl_registry *registry;
52*4882a593Smuzhiyun   struct wl_compositor *compositor;
53*4882a593Smuzhiyun@@ -72,6 +83,14 @@ G_DEFINE_TYPE_WITH_CODE (GstWlDisplay, gst_wl_display, G_TYPE_OBJECT,
54*4882a593Smuzhiyun         "wldisplay", 0, "wldisplay library");
55*4882a593Smuzhiyun     );
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun+void
58*4882a593Smuzhiyun+gst_wl_display_set_touch_surface (GstWlDisplay * self,
59*4882a593Smuzhiyun+    struct wl_surface *touch_surface)
60*4882a593Smuzhiyun+{
61*4882a593Smuzhiyun+  GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
62*4882a593Smuzhiyun+  priv->touch_surface = touch_surface;
63*4882a593Smuzhiyun+}
64*4882a593Smuzhiyun+
65*4882a593Smuzhiyun gboolean
66*4882a593Smuzhiyun gst_wl_display_support_afbc (GstWlDisplay * self)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun@@ -88,6 +107,18 @@ gst_wl_display_support_nv12_10le40 (GstWlDisplay * self)
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun static void gst_wl_display_finalize (GObject * gobject);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun+struct input
73*4882a593Smuzhiyun+{
74*4882a593Smuzhiyun+  GstWlDisplay *display;
75*4882a593Smuzhiyun+  struct wl_seat *seat;
76*4882a593Smuzhiyun+  struct wl_pointer *pointer;
77*4882a593Smuzhiyun+  struct wl_touch *touch;
78*4882a593Smuzhiyun+
79*4882a593Smuzhiyun+  void *pointer_focus;
80*4882a593Smuzhiyun+
81*4882a593Smuzhiyun+  struct wl_list link;
82*4882a593Smuzhiyun+};
83*4882a593Smuzhiyun+
84*4882a593Smuzhiyun static void
85*4882a593Smuzhiyun gst_wl_display_class_init (GstWlDisplayClass * klass)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun@@ -117,6 +148,30 @@ gst_wl_ref_wl_buffer (gpointer key, gpointer value, gpointer user_data)
88*4882a593Smuzhiyun   g_object_ref (value);
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun+static void
92*4882a593Smuzhiyun+input_destroy (struct input *input)
93*4882a593Smuzhiyun+{
94*4882a593Smuzhiyun+  if (input->touch)
95*4882a593Smuzhiyun+    wl_touch_destroy (input->touch);
96*4882a593Smuzhiyun+  if (input->pointer)
97*4882a593Smuzhiyun+    wl_pointer_destroy (input->pointer);
98*4882a593Smuzhiyun+
99*4882a593Smuzhiyun+  wl_list_remove (&input->link);
100*4882a593Smuzhiyun+  wl_seat_destroy (input->seat);
101*4882a593Smuzhiyun+  free (input);
102*4882a593Smuzhiyun+}
103*4882a593Smuzhiyun+
104*4882a593Smuzhiyun+static void
105*4882a593Smuzhiyun+display_destroy_inputs (GstWlDisplay * self)
106*4882a593Smuzhiyun+{
107*4882a593Smuzhiyun+  GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
108*4882a593Smuzhiyun+  struct input *tmp;
109*4882a593Smuzhiyun+  struct input *input;
110*4882a593Smuzhiyun+
111*4882a593Smuzhiyun+  wl_list_for_each_safe (input, tmp, &priv->input_list, link)
112*4882a593Smuzhiyun+      input_destroy (input);
113*4882a593Smuzhiyun+}
114*4882a593Smuzhiyun+
115*4882a593Smuzhiyun static void
116*4882a593Smuzhiyun gst_wl_display_finalize (GObject * gobject)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun@@ -127,6 +182,14 @@ gst_wl_display_finalize (GObject * gobject)
119*4882a593Smuzhiyun   if (priv->thread)
120*4882a593Smuzhiyun     g_thread_join (priv->thread);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun+  display_destroy_inputs (self);
123*4882a593Smuzhiyun+
124*4882a593Smuzhiyun+  if (priv->cursor_surface)
125*4882a593Smuzhiyun+    wl_surface_destroy (priv->cursor_surface);
126*4882a593Smuzhiyun+
127*4882a593Smuzhiyun+  if (priv->cursor_theme)
128*4882a593Smuzhiyun+    wl_cursor_theme_destroy (priv->cursor_theme);
129*4882a593Smuzhiyun+
130*4882a593Smuzhiyun   /* to avoid buffers being unregistered from another thread
131*4882a593Smuzhiyun    * at the same time, take their ownership */
132*4882a593Smuzhiyun   g_mutex_lock (&priv->buffers_mutex);
133*4882a593Smuzhiyun@@ -284,6 +347,222 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
134*4882a593Smuzhiyun   handle_xdg_wm_base_ping
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun+static void
138*4882a593Smuzhiyun+display_set_cursor (GstWlDisplay *self, struct wl_pointer *pointer,
139*4882a593Smuzhiyun+    uint32_t serial)
140*4882a593Smuzhiyun+{
141*4882a593Smuzhiyun+  GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
142*4882a593Smuzhiyun+  struct wl_buffer *buffer;
143*4882a593Smuzhiyun+  struct wl_cursor_image *image;
144*4882a593Smuzhiyun+
145*4882a593Smuzhiyun+  if (!priv->default_cursor)
146*4882a593Smuzhiyun+    return;
147*4882a593Smuzhiyun+
148*4882a593Smuzhiyun+  if (!priv->cursor_surface) {
149*4882a593Smuzhiyun+      priv->cursor_surface =
150*4882a593Smuzhiyun+          wl_compositor_create_surface (priv->compositor);
151*4882a593Smuzhiyun+      if (!priv->cursor_surface)
152*4882a593Smuzhiyun+        return;
153*4882a593Smuzhiyun+  }
154*4882a593Smuzhiyun+
155*4882a593Smuzhiyun+  image = priv->default_cursor->images[0];
156*4882a593Smuzhiyun+  buffer = wl_cursor_image_get_buffer (image);
157*4882a593Smuzhiyun+  if (!buffer)
158*4882a593Smuzhiyun+    return;
159*4882a593Smuzhiyun+
160*4882a593Smuzhiyun+  wl_pointer_set_cursor (pointer, serial,
161*4882a593Smuzhiyun+      priv->cursor_surface, image->hotspot_x, image->hotspot_y);
162*4882a593Smuzhiyun+  wl_surface_attach (priv->cursor_surface, buffer, 0, 0);
163*4882a593Smuzhiyun+  wl_surface_damage (priv->cursor_surface, 0, 0,
164*4882a593Smuzhiyun+      image->width, image->height);
165*4882a593Smuzhiyun+  wl_surface_commit (priv->cursor_surface);
166*4882a593Smuzhiyun+}
167*4882a593Smuzhiyun+
168*4882a593Smuzhiyun+static void
169*4882a593Smuzhiyun+pointer_handle_enter (void *data, struct wl_pointer *pointer,
170*4882a593Smuzhiyun+    uint32_t serial, struct wl_surface *surface,
171*4882a593Smuzhiyun+    wl_fixed_t sx_w, wl_fixed_t sy_w)
172*4882a593Smuzhiyun+{
173*4882a593Smuzhiyun+  struct input *input = data;
174*4882a593Smuzhiyun+  GstWlDisplay *self = input->display;
175*4882a593Smuzhiyun+  GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
176*4882a593Smuzhiyun+  GstWlWindow *window;
177*4882a593Smuzhiyun+
178*4882a593Smuzhiyun+  if (!surface) {
179*4882a593Smuzhiyun+    /* enter event for a window we've just destroyed */
180*4882a593Smuzhiyun+    return;
181*4882a593Smuzhiyun+  }
182*4882a593Smuzhiyun+
183*4882a593Smuzhiyun+  if (surface != priv->touch_surface) {
184*4882a593Smuzhiyun+    /* Ignoring input event from other surfaces */
185*4882a593Smuzhiyun+    return;
186*4882a593Smuzhiyun+  }
187*4882a593Smuzhiyun+
188*4882a593Smuzhiyun+  window = wl_surface_get_user_data (surface);
189*4882a593Smuzhiyun+  if (!window || !gst_wl_window_is_toplevel (window)) {
190*4882a593Smuzhiyun+    /* Ignoring input event from subsurface */
191*4882a593Smuzhiyun+    return;
192*4882a593Smuzhiyun+  }
193*4882a593Smuzhiyun+
194*4882a593Smuzhiyun+  input->pointer_focus = window;
195*4882a593Smuzhiyun+  display_set_cursor (self, pointer, serial);
196*4882a593Smuzhiyun+}
197*4882a593Smuzhiyun+
198*4882a593Smuzhiyun+static void
199*4882a593Smuzhiyun+pointer_handle_leave (void *data, struct wl_pointer *pointer,
200*4882a593Smuzhiyun+    uint32_t serial, struct wl_surface *surface)
201*4882a593Smuzhiyun+{
202*4882a593Smuzhiyun+  struct input *input = data;
203*4882a593Smuzhiyun+
204*4882a593Smuzhiyun+  if (input->pointer_focus) {
205*4882a593Smuzhiyun+    input->pointer_focus = NULL;
206*4882a593Smuzhiyun+    wl_pointer_set_cursor (pointer, serial, NULL, 0, 0);
207*4882a593Smuzhiyun+  }
208*4882a593Smuzhiyun+}
209*4882a593Smuzhiyun+
210*4882a593Smuzhiyun+static void
211*4882a593Smuzhiyun+pointer_handle_motion (void *data, struct wl_pointer *pointer,
212*4882a593Smuzhiyun+    uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
213*4882a593Smuzhiyun+{
214*4882a593Smuzhiyun+}
215*4882a593Smuzhiyun+
216*4882a593Smuzhiyun+static void
217*4882a593Smuzhiyun+pointer_handle_button (void *data, struct wl_pointer *pointer, uint32_t serial,
218*4882a593Smuzhiyun+    uint32_t time, uint32_t button, uint32_t state)
219*4882a593Smuzhiyun+{
220*4882a593Smuzhiyun+  struct input *input = data;
221*4882a593Smuzhiyun+  GstWlWindow *window;
222*4882a593Smuzhiyun+
223*4882a593Smuzhiyun+  window = input->pointer_focus;
224*4882a593Smuzhiyun+  if (!window)
225*4882a593Smuzhiyun+    return;
226*4882a593Smuzhiyun+
227*4882a593Smuzhiyun+  if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED)
228*4882a593Smuzhiyun+    gst_wl_window_toplevel_move (window, input->seat, serial);
229*4882a593Smuzhiyun+}
230*4882a593Smuzhiyun+
231*4882a593Smuzhiyun+static void
232*4882a593Smuzhiyun+pointer_handle_axis (void *data, struct wl_pointer *wl_pointer,
233*4882a593Smuzhiyun+    uint32_t time, uint32_t axis, wl_fixed_t value)
234*4882a593Smuzhiyun+{
235*4882a593Smuzhiyun+}
236*4882a593Smuzhiyun+
237*4882a593Smuzhiyun+static const struct wl_pointer_listener pointer_listener = {
238*4882a593Smuzhiyun+  pointer_handle_enter,
239*4882a593Smuzhiyun+  pointer_handle_leave,
240*4882a593Smuzhiyun+  pointer_handle_motion,
241*4882a593Smuzhiyun+  pointer_handle_button,
242*4882a593Smuzhiyun+  pointer_handle_axis,
243*4882a593Smuzhiyun+};
244*4882a593Smuzhiyun+
245*4882a593Smuzhiyun+static void
246*4882a593Smuzhiyun+touch_handle_down (void *data, struct wl_touch *wl_touch,
247*4882a593Smuzhiyun+    uint32_t serial, uint32_t time, struct wl_surface *surface,
248*4882a593Smuzhiyun+    int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
249*4882a593Smuzhiyun+{
250*4882a593Smuzhiyun+  struct input *input = data;
251*4882a593Smuzhiyun+  GstWlDisplay *self = input->display;
252*4882a593Smuzhiyun+  GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
253*4882a593Smuzhiyun+  GstWlWindow *window;
254*4882a593Smuzhiyun+
255*4882a593Smuzhiyun+  if (!surface) {
256*4882a593Smuzhiyun+    /* enter event for a window we've just destroyed */
257*4882a593Smuzhiyun+    return;
258*4882a593Smuzhiyun+  }
259*4882a593Smuzhiyun+
260*4882a593Smuzhiyun+  if (surface != priv->touch_surface) {
261*4882a593Smuzhiyun+    /* Ignoring input event from other surfaces */
262*4882a593Smuzhiyun+    return;
263*4882a593Smuzhiyun+  }
264*4882a593Smuzhiyun+
265*4882a593Smuzhiyun+  window = wl_surface_get_user_data (surface);
266*4882a593Smuzhiyun+  if (!window || !gst_wl_window_is_toplevel (window)) {
267*4882a593Smuzhiyun+    /* Ignoring input event from subsurface */
268*4882a593Smuzhiyun+    return;
269*4882a593Smuzhiyun+  }
270*4882a593Smuzhiyun+
271*4882a593Smuzhiyun+  gst_wl_window_toplevel_move (window, input->seat, serial);
272*4882a593Smuzhiyun+}
273*4882a593Smuzhiyun+
274*4882a593Smuzhiyun+static void
275*4882a593Smuzhiyun+touch_handle_up (void *data, struct wl_touch *wl_touch,
276*4882a593Smuzhiyun+    uint32_t serial, uint32_t time, int32_t id)
277*4882a593Smuzhiyun+{
278*4882a593Smuzhiyun+}
279*4882a593Smuzhiyun+
280*4882a593Smuzhiyun+static void
281*4882a593Smuzhiyun+touch_handle_motion (void *data, struct wl_touch *wl_touch,
282*4882a593Smuzhiyun+    uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
283*4882a593Smuzhiyun+{
284*4882a593Smuzhiyun+}
285*4882a593Smuzhiyun+
286*4882a593Smuzhiyun+static void
287*4882a593Smuzhiyun+touch_handle_frame (void *data, struct wl_touch *wl_touch)
288*4882a593Smuzhiyun+{
289*4882a593Smuzhiyun+}
290*4882a593Smuzhiyun+
291*4882a593Smuzhiyun+static void
292*4882a593Smuzhiyun+touch_handle_cancel (void *data, struct wl_touch *wl_touch)
293*4882a593Smuzhiyun+{
294*4882a593Smuzhiyun+}
295*4882a593Smuzhiyun+
296*4882a593Smuzhiyun+static const struct wl_touch_listener touch_listener = {
297*4882a593Smuzhiyun+  touch_handle_down,
298*4882a593Smuzhiyun+  touch_handle_up,
299*4882a593Smuzhiyun+  touch_handle_motion,
300*4882a593Smuzhiyun+  touch_handle_frame,
301*4882a593Smuzhiyun+  touch_handle_cancel,
302*4882a593Smuzhiyun+};
303*4882a593Smuzhiyun+
304*4882a593Smuzhiyun+static void
305*4882a593Smuzhiyun+seat_handle_capabilities (void *data, struct wl_seat *seat,
306*4882a593Smuzhiyun+    enum wl_seat_capability caps)
307*4882a593Smuzhiyun+{
308*4882a593Smuzhiyun+  struct input *input = data;
309*4882a593Smuzhiyun+
310*4882a593Smuzhiyun+  if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
311*4882a593Smuzhiyun+    input->pointer = wl_seat_get_pointer (seat);
312*4882a593Smuzhiyun+    wl_pointer_add_listener (input->pointer, &pointer_listener, input);
313*4882a593Smuzhiyun+  } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
314*4882a593Smuzhiyun+    wl_pointer_destroy (input->pointer);
315*4882a593Smuzhiyun+    input->pointer = NULL;
316*4882a593Smuzhiyun+  }
317*4882a593Smuzhiyun+
318*4882a593Smuzhiyun+  if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
319*4882a593Smuzhiyun+    input->touch = wl_seat_get_touch (seat);
320*4882a593Smuzhiyun+    wl_touch_add_listener (input->touch, &touch_listener, input);
321*4882a593Smuzhiyun+  } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
322*4882a593Smuzhiyun+    wl_touch_destroy (input->touch);
323*4882a593Smuzhiyun+    input->touch = NULL;
324*4882a593Smuzhiyun+  }
325*4882a593Smuzhiyun+}
326*4882a593Smuzhiyun+
327*4882a593Smuzhiyun+static const struct wl_seat_listener seat_listener = {
328*4882a593Smuzhiyun+  seat_handle_capabilities,
329*4882a593Smuzhiyun+};
330*4882a593Smuzhiyun+
331*4882a593Smuzhiyun+static void
332*4882a593Smuzhiyun+display_add_input (GstWlDisplay *self, uint32_t id)
333*4882a593Smuzhiyun+{
334*4882a593Smuzhiyun+  GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
335*4882a593Smuzhiyun+  struct input *input;
336*4882a593Smuzhiyun+
337*4882a593Smuzhiyun+  input = calloc (1, sizeof (*input));
338*4882a593Smuzhiyun+  if (input == NULL) {
339*4882a593Smuzhiyun+    GST_ERROR ("Error out of memory");
340*4882a593Smuzhiyun+    return;
341*4882a593Smuzhiyun+  }
342*4882a593Smuzhiyun+
343*4882a593Smuzhiyun+  input->display = self;
344*4882a593Smuzhiyun+
345*4882a593Smuzhiyun+  input->seat = wl_registry_bind (priv->registry, id, &wl_seat_interface, 1);
346*4882a593Smuzhiyun+
347*4882a593Smuzhiyun+  wl_seat_add_listener (input->seat, &seat_listener, input);
348*4882a593Smuzhiyun+  wl_seat_set_user_data (input->seat, input);
349*4882a593Smuzhiyun+
350*4882a593Smuzhiyun+  wl_list_insert (priv->input_list.prev, &input->link);
351*4882a593Smuzhiyun+}
352*4882a593Smuzhiyun+
353*4882a593Smuzhiyun static void
354*4882a593Smuzhiyun registry_handle_global (void *data, struct wl_registry *registry,
355*4882a593Smuzhiyun     uint32_t id, const char *interface, uint32_t version)
356*4882a593Smuzhiyun@@ -307,6 +586,18 @@ registry_handle_global (void *data, struct wl_registry *registry,
357*4882a593Smuzhiyun   } else if (g_strcmp0 (interface, "wl_shm") == 0) {
358*4882a593Smuzhiyun     priv->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1);
359*4882a593Smuzhiyun     wl_shm_add_listener (priv->shm, &shm_listener, self);
360*4882a593Smuzhiyun+
361*4882a593Smuzhiyun+    priv->cursor_theme = wl_cursor_theme_load (NULL, 32, priv->shm);
362*4882a593Smuzhiyun+    if (!priv->cursor_theme) {
363*4882a593Smuzhiyun+      GST_ERROR ("Error loading default cursor theme");
364*4882a593Smuzhiyun+    } else {
365*4882a593Smuzhiyun+      priv->default_cursor =
366*4882a593Smuzhiyun+          wl_cursor_theme_get_cursor (priv->cursor_theme, "left_ptr");
367*4882a593Smuzhiyun+      if (!priv->default_cursor)
368*4882a593Smuzhiyun+        GST_ERROR ("Error loading default left cursor pointer");
369*4882a593Smuzhiyun+    }
370*4882a593Smuzhiyun+  } else if (g_strcmp0 (interface, "wl_seat") == 0) {
371*4882a593Smuzhiyun+    display_add_input (self, id);
372*4882a593Smuzhiyun   } else if (g_strcmp0 (interface, "wp_viewporter") == 0) {
373*4882a593Smuzhiyun     priv->viewporter =
374*4882a593Smuzhiyun         wl_registry_bind (registry, id, &wp_viewporter_interface, 1);
375*4882a593Smuzhiyun@@ -400,6 +691,8 @@ gst_wl_display_new_existing (struct wl_display * display,
376*4882a593Smuzhiyun   priv->display_wrapper = wl_proxy_create_wrapper (display);
377*4882a593Smuzhiyun   priv->own_display = take_ownership;
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun+  wl_list_init (&priv->input_list);
380*4882a593Smuzhiyun+
381*4882a593Smuzhiyun   priv->queue = wl_display_create_queue (priv->display);
382*4882a593Smuzhiyun   wl_proxy_set_queue ((struct wl_proxy *) priv->display_wrapper, priv->queue);
383*4882a593Smuzhiyun   priv->registry = wl_display_get_registry (priv->display_wrapper);
384*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwldisplay.h b/gst-libs/gst/wayland/gstwldisplay.h
385*4882a593Smuzhiyunindex c130b79..c6b4c8d 100644
386*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwldisplay.h
387*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwldisplay.h
388*4882a593Smuzhiyun@@ -35,6 +35,10 @@ struct _GstWlDisplay
389*4882a593Smuzhiyun   GObject parent_instance;
390*4882a593Smuzhiyun };
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun+GST_WL_API
393*4882a593Smuzhiyun+void gst_wl_display_set_touch_surface (GstWlDisplay * self,
394*4882a593Smuzhiyun+    struct wl_surface *touch_surface);
395*4882a593Smuzhiyun+
396*4882a593Smuzhiyun GST_WL_API
397*4882a593Smuzhiyun gboolean gst_wl_display_support_afbc (GstWlDisplay * self);
398*4882a593Smuzhiyun
399*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlwindow.c b/gst-libs/gst/wayland/gstwlwindow.c
400*4882a593Smuzhiyunindex df60a67..f55778d 100644
401*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlwindow.c
402*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlwindow.c
403*4882a593Smuzhiyun@@ -96,6 +96,19 @@ static void gst_wl_window_finalize (GObject * gobject);
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun static void gst_wl_window_update_borders (GstWlWindow * self);
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun+void
408*4882a593Smuzhiyun+gst_wl_window_toplevel_move (GstWlWindow * self,
409*4882a593Smuzhiyun+    struct wl_seat *seat, uint32_t serial)
410*4882a593Smuzhiyun+{
411*4882a593Smuzhiyun+  GstWlWindowPrivate *priv;
412*4882a593Smuzhiyun+
413*4882a593Smuzhiyun+  if (!gst_wl_window_is_toplevel (self))
414*4882a593Smuzhiyun+    return;
415*4882a593Smuzhiyun+
416*4882a593Smuzhiyun+  priv = gst_wl_window_get_instance_private (self);
417*4882a593Smuzhiyun+  xdg_toplevel_move (priv->xdg_toplevel, seat, serial);
418*4882a593Smuzhiyun+}
419*4882a593Smuzhiyun+
420*4882a593Smuzhiyun static void
421*4882a593Smuzhiyun handle_xdg_toplevel_close (void *data, struct xdg_toplevel *xdg_toplevel)
422*4882a593Smuzhiyun {
423*4882a593Smuzhiyun@@ -227,6 +240,8 @@ gst_wl_window_new_internal (GstWlDisplay * display, GMutex * render_lock)
424*4882a593Smuzhiyun   priv->area_surface = wl_compositor_create_surface (compositor);
425*4882a593Smuzhiyun   priv->video_surface = wl_compositor_create_surface (compositor);
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun+  gst_wl_display_set_touch_surface (display, priv->area_surface);
428*4882a593Smuzhiyun+
429*4882a593Smuzhiyun   priv->area_surface_wrapper = wl_proxy_create_wrapper (priv->area_surface);
430*4882a593Smuzhiyun   priv->video_surface_wrapper = wl_proxy_create_wrapper (priv->video_surface);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun@@ -368,6 +383,8 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info,
433*4882a593Smuzhiyun   self = gst_wl_window_new_internal (display, render_lock);
434*4882a593Smuzhiyun   priv = gst_wl_window_get_instance_private (self);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun+  wl_surface_set_user_data (priv->area_surface, self);
437*4882a593Smuzhiyun+
438*4882a593Smuzhiyun   xdg_wm_base = gst_wl_display_get_xdg_wm_base (display);
439*4882a593Smuzhiyun   fullscreen_shell = gst_wl_display_get_fullscreen_shell_v1 (display);
440*4882a593Smuzhiyun
441*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/gstwlwindow.h b/gst-libs/gst/wayland/gstwlwindow.h
442*4882a593Smuzhiyunindex 8f02f00..9425666 100644
443*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/gstwlwindow.h
444*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/gstwlwindow.h
445*4882a593Smuzhiyun@@ -47,6 +47,10 @@ struct _GstWlWindow
446*4882a593Smuzhiyun   GObject parent_instance;
447*4882a593Smuzhiyun };
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun+GST_WL_API
450*4882a593Smuzhiyun+void gst_wl_window_toplevel_move (GstWlWindow * self,
451*4882a593Smuzhiyun+        struct wl_seat *seat, uint32_t serial);
452*4882a593Smuzhiyun+
453*4882a593Smuzhiyun GST_WL_API
454*4882a593Smuzhiyun void gst_wl_window_ensure_crop (GstWlWindow * self,
455*4882a593Smuzhiyun         gint x, gint y, gint w, gint h);
456*4882a593Smuzhiyundiff --git a/gst-libs/gst/wayland/meson.build b/gst-libs/gst/wayland/meson.build
457*4882a593Smuzhiyunindex 3aa63cb..9c958d7 100644
458*4882a593Smuzhiyun--- a/gst-libs/gst/wayland/meson.build
459*4882a593Smuzhiyun+++ b/gst-libs/gst/wayland/meson.build
460*4882a593Smuzhiyun@@ -1,10 +1,11 @@
461*4882a593Smuzhiyun wl_req = '>= 1.15'
462*4882a593Smuzhiyun wl_client_dep = dependency('wayland-client', version: wl_req, required: get_option('wayland'))
463*4882a593Smuzhiyun+wl_cursor_dep = dependency('wayland-cursor', version: wl_req, required: get_option('wayland'))
464*4882a593Smuzhiyun libdrm_dep = dependency('libdrm', version: '>= 2.4.55', required: get_option('wayland'))
465*4882a593Smuzhiyun wl_protocol_dep = dependency('wayland-protocols', version: wl_req, required: get_option('wayland'))
466*4882a593Smuzhiyun wl_scanner = find_program('wayland-scanner', required: get_option('wayland'))
467*4882a593Smuzhiyun # Also used in ext/wayland
468*4882a593Smuzhiyun-use_wayland = wl_protocol_dep.found() and wl_client_dep.found() and wl_scanner.found() and libdrm_dep.found()
469*4882a593Smuzhiyun+use_wayland = wl_protocol_dep.found() and wl_client_dep.found() and wl_cursor_dep.found() and wl_scanner.found() and libdrm_dep.found()
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun if use_wayland
472*4882a593Smuzhiyun   wl_sources = [
473*4882a593Smuzhiyun@@ -74,7 +75,7 @@ if use_wayland
474*4882a593Smuzhiyun     darwin_versions : osxversion,
475*4882a593Smuzhiyun     install : true,
476*4882a593Smuzhiyun     dependencies : [gst_dep, gstallocators_dep, gstvideo_dep, libdrm_dep,
477*4882a593Smuzhiyun-                    wl_client_dep, wl_protocol_dep]
478*4882a593Smuzhiyun+                    wl_client_dep, wl_cursor_dep, wl_protocol_dep]
479*4882a593Smuzhiyun   )
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun   pkg_name = 'gstreamer-wayland-1.0'
482*4882a593Smuzhiyun@@ -90,7 +91,7 @@ if use_wayland
483*4882a593Smuzhiyun   gstwayland_dep = declare_dependency(link_with : gstwayland,
484*4882a593Smuzhiyun     include_directories : [libsinc],
485*4882a593Smuzhiyun     dependencies : [gst_dep, gstallocators_dep, gstvideo_dep, libdrm_dep,
486*4882a593Smuzhiyun-                    wl_client_dep, wl_protocol_dep])
487*4882a593Smuzhiyun+                    wl_client_dep, wl_cursor_dep, wl_protocol_dep])
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun   install_headers(wl_headers, subdir: 'gstreamer-1.0/gst/wayland')
490*4882a593Smuzhiyun   meson.override_dependency(pkg_name, gstwayland_dep)
491*4882a593Smuzhiyun--
492*4882a593Smuzhiyun2.20.1
493*4882a593Smuzhiyun
494