1 From 79db7e4cab226515f0e4d40afdb5a5b478755396 Mon Sep 17 00:00:00 2001
2 From: Pooja Prajod <a0132412@ti.com>
3 Date: Wed, 14 Sep 2016 16:03:17 -0400
4 Subject: [PATCH] gstwaylandsink: Add mouse drag and drop support
6 This patch adds mouse input listeners to WlDisplay instance.
8 Signed-off-by: Pooja Prajod <a0132412@ti.com>
9 Signed-off-by: Eric Ruei <e-ruei1@ti.com>
11 ext/wayland/wldisplay.c | 305 +++++++++++++++++++++++++++++++++++++++++++++++-
12 ext/wayland/wldisplay.h | 4 +
13 ext/wayland/wlwindow.c | 2 +
14 3 files changed, 310 insertions(+), 1 deletion(-)
16 diff --git a/ext/wayland/wldisplay.c b/ext/wayland/wldisplay.c
17 index 8c5eeaf..c647f34 100644
18 --- a/ext/wayland/wldisplay.c
19 +++ b/ext/wayland/wldisplay.c
27 #include "wldisplay.h"
29 +#include "wlwindow.h"
31 +#include <wayland-client-protocol.h>
35 +#include <linux/input.h>
37 GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
38 #define GST_CAT_DEFAULT gstwayland_debug
40 G_DEFINE_TYPE (GstWlDisplay, gst_wl_display, G_TYPE_OBJECT);
45 + struct wl_list link;
50 + GstWlDisplay *display;
51 + struct wl_seat *seat;
52 + struct wl_pointer *pointer;
53 + struct wl_touch *touch;
54 + struct wl_list touch_point_list;
55 + GstWlWindow *pointer_focus;
56 + GstWlWindow *touch_focus;
57 + struct wl_list link;
61 static void gst_wl_display_finalize (GObject * gobject);
62 +static void input_grab (struct input *input, GstWlWindow *window);
63 +static void input_ungrab (struct input *input);
66 gst_wl_display_class_init (GstWlDisplayClass * klass)
67 @@ -51,6 +78,54 @@ gst_wl_display_init (GstWlDisplay * self)
71 +input_grab (struct input *input, GstWlWindow *window)
73 + input->grab = window;
77 +input_ungrab (struct input *input)
83 +input_remove_pointer_focus (struct input *input)
85 + GstWlWindow *window = input->pointer_focus;
90 + input->pointer_focus = NULL;
94 +input_destroy (struct input *input)
96 + input_remove_pointer_focus (input);
98 + if (input->display->seat_version >= 3) {
100 + wl_pointer_release (input->pointer);
103 + wl_list_remove (&input->link);
104 + wl_seat_destroy (input->seat);
109 +display_destroy_inputs (GstWlDisplay *display)
112 + struct input *input;
114 + wl_list_for_each_safe (input, tmp, &display->input_list, link)
115 + input_destroy (input);
119 gst_wl_display_finalize (GObject * gobject)
121 GstWlDisplay *self = GST_WL_DISPLAY (gobject);
122 @@ -74,6 +149,8 @@ gst_wl_display_finalize (GObject * gobject)
123 g_hash_table_unref (self->buffers);
124 g_mutex_clear (&self->buffers_mutex);
126 + display_destroy_inputs (self);
129 wl_shm_destroy (self->shm);
131 @@ -143,6 +220,228 @@ static const struct wl_shm_listener shm_listener = {
137 +pointer_handle_enter (void *data, struct wl_pointer *pointer,
138 + uint32_t serial, struct wl_surface *surface,
139 + wl_fixed_t sx_w, wl_fixed_t sy_w)
141 + struct input *input = data;
144 + /* enter event for a window we've just destroyed */
148 + input->display->serial = serial;
149 + input->pointer_focus = wl_surface_get_user_data (surface);
153 +pointer_handle_leave (void *data, struct wl_pointer *pointer,
154 + uint32_t serial, struct wl_surface *surface)
156 + struct input *input = data;
158 + input_remove_pointer_focus (input);
162 +pointer_handle_motion (void *data, struct wl_pointer *pointer,
163 + uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
165 + struct input *input = data;
166 + GstWlWindow *window = input->pointer_focus;
172 + wl_shell_surface_move (input->grab->shell_surface, input->seat,
173 + input->display->serial);
178 +pointer_handle_button (void *data, struct wl_pointer *pointer, uint32_t serial,
179 + uint32_t time, uint32_t button, uint32_t state_w)
181 + struct input *input = data;
182 + enum wl_pointer_button_state state = state_w;
183 + input->display->serial = serial;
185 + if (button == BTN_LEFT) {
186 + if (state == WL_POINTER_BUTTON_STATE_PRESSED)
187 + input_grab (input, input->pointer_focus);
189 + if (input->grab && state == WL_POINTER_BUTTON_STATE_RELEASED)
190 + input_ungrab (input);
194 + wl_shell_surface_move (input->grab->shell_surface, input->seat,
195 + input->display->serial);
199 +pointer_handle_axis (void *data, struct wl_pointer *pointer,
200 + uint32_t time, uint32_t axis, wl_fixed_t value)
204 +static const struct wl_pointer_listener pointer_listener = {
205 + pointer_handle_enter,
206 + pointer_handle_leave,
207 + pointer_handle_motion,
208 + pointer_handle_button,
209 + pointer_handle_axis,
213 +touch_handle_down (void *data, struct wl_touch *wl_touch,
214 + uint32_t serial, uint32_t time, struct wl_surface *surface,
215 + int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
217 + struct input *input = data;
218 + struct touch_point *tp;
220 + input->display->serial = serial;
221 + input->touch_focus = wl_surface_get_user_data (surface);
222 + if (!input->touch_focus) {
226 + tp = malloc (sizeof *tp);
229 + wl_list_insert (&input->touch_point_list, &tp->link);
230 + wl_shell_surface_move (input->touch_focus->shell_surface, input->seat,
236 +touch_handle_motion (void *data, struct wl_touch *wl_touch,
237 + uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
239 + struct input *input = data;
240 + struct touch_point *tp;
243 + if (!input->touch_focus) {
246 + wl_list_for_each (tp, &input->touch_point_list, link) {
250 + wl_shell_surface_move (input->touch_focus->shell_surface, input->seat,
251 + input->display->serial);
258 +touch_handle_frame (void *data, struct wl_touch *wl_touch)
263 +touch_handle_cancel (void *data, struct wl_touch *wl_touch)
268 +touch_handle_up (void *data, struct wl_touch *wl_touch,
269 + uint32_t serial, uint32_t time, int32_t id)
271 + struct input *input = data;
272 + struct touch_point *tp, *tmp;
274 + if (!input->touch_focus) {
278 + wl_list_for_each_safe (tp, tmp, &input->touch_point_list, link) {
282 + wl_list_remove (&tp->link);
289 +static const struct wl_touch_listener touch_listener = {
292 + touch_handle_motion,
293 + touch_handle_frame,
294 + touch_handle_cancel,
299 +seat_handle_capabilities (void *data, struct wl_seat *seat,
300 + enum wl_seat_capability caps)
302 + struct input *input = data;
304 + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
305 + input->pointer = wl_seat_get_pointer (seat);
306 + wl_pointer_set_user_data (input->pointer, input);
307 + wl_pointer_add_listener (input->pointer, &pointer_listener, input);
308 + } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
309 + wl_pointer_destroy (input->pointer);
310 + input->pointer = NULL;
313 + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
314 + input->touch = wl_seat_get_touch (seat);
315 + wl_touch_set_user_data (input->touch, input);
316 + wl_touch_add_listener (input->touch, &touch_listener, input);
317 + } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
318 + wl_touch_destroy (input->touch);
319 + input->touch = NULL;
324 +seat_handle_name (void *data, struct wl_seat *seat, const char *name)
329 +static const struct wl_seat_listener seat_listener = {
330 + seat_handle_capabilities,
335 +display_add_input (GstWlDisplay *d, uint32_t id)
337 + struct input *input;
339 + input = calloc (1, sizeof (*input));
340 + if (input == NULL) {
341 + fprintf (stderr, "%s: out of memory\n", "gst-wayland-sink");
342 + exit (EXIT_FAILURE);
344 + input->display = d;
345 + input->seat = wl_registry_bind (d->registry, id, &wl_seat_interface,
346 + MAX (d->seat_version, 3));
347 + input->touch_focus = NULL;
348 + input->pointer_focus = NULL;
349 + wl_list_init (&input->touch_point_list);
350 + wl_list_insert (d->input_list.prev, &input->link);
352 + wl_seat_add_listener (input->seat, &seat_listener, input);
353 + wl_seat_set_user_data (input->seat, input);
358 registry_handle_global (void *data, struct wl_registry *registry,
359 uint32_t id, const char *interface, uint32_t version)
360 @@ -160,6 +459,9 @@ registry_handle_global (void *data, struct wl_registry *registry,
361 } else if (g_strcmp0 (interface, "wl_shm") == 0) {
362 self->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1);
363 wl_shm_add_listener (self->shm, &shm_listener, self);
364 + } else if (g_strcmp0 (interface, "wl_seat") == 0) {
365 + self->seat_version = version;
366 + display_add_input (self, id);
367 } else if (g_strcmp0 (interface, "wl_scaler") == 0) {
368 self->scaler = wl_registry_bind (registry, id, &wl_scaler_interface, 2);
370 @@ -237,6 +539,7 @@ gst_wl_display_new_existing (struct wl_display * display,
371 self->own_display = take_ownership;
373 self->queue = wl_display_create_queue (self->display);
374 + wl_list_init (&self->input_list);
375 self->registry = wl_display_get_registry (self->display);
376 wl_proxy_set_queue ((struct wl_proxy *) self->registry, self->queue);
377 wl_registry_add_listener (self->registry, ®istry_listener, self);
378 diff --git a/ext/wayland/wldisplay.h b/ext/wayland/wldisplay.h
379 index 5505d60..d8c2cef 100644
380 --- a/ext/wayland/wldisplay.h
381 +++ b/ext/wayland/wldisplay.h
382 @@ -62,6 +62,10 @@ struct _GstWlDisplay
383 GMutex buffers_mutex;
385 gboolean shutting_down;
387 + struct wl_list input_list;
392 struct _GstWlDisplayClass
393 diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c
394 index a964335..34ae385 100644
395 --- a/ext/wayland/wlwindow.c
396 +++ b/ext/wayland/wlwindow.c
397 @@ -111,6 +111,8 @@ gst_wl_window_new_internal (GstWlDisplay * display)
399 window->area_surface = wl_compositor_create_surface (display->compositor);
400 window->video_surface = wl_compositor_create_surface (display->compositor);
401 + wl_surface_set_user_data (window->area_surface, window);
402 + wl_surface_set_user_data (window->video_surface, window);
404 wl_proxy_set_queue ((struct wl_proxy *) window->area_surface, display->queue);
405 wl_proxy_set_queue ((struct wl_proxy *) window->video_surface,