]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkdevice-wayland.c
wayland: data_device.data_offer now has a safe object wrapper
[~andy/gtk] / gdk / wayland / gdkdevice-wayland.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #define _GNU_SOURCE
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <errno.h>
22
23 #include "config.h"
24
25 #include <string.h>
26 #include <gdk/gdkwindow.h>
27 #include <gdk/gdktypes.h>
28 #include "gdkprivate-wayland.h"
29 #include "gdkwayland.h"
30 #include "gdkkeysyms.h"
31 #include "gdkdeviceprivate.h"
32 #include "gdkdevicemanagerprivate.h"
33 #include "gdkprivate-wayland.h"
34
35 #include <xkbcommon/xkbcommon.h>
36 #include <X11/keysym.h>
37
38 #include <sys/time.h>
39 #include <sys/mman.h>
40
41 #define GDK_TYPE_DEVICE_CORE         (gdk_device_core_get_type ())
42 #define GDK_DEVICE_CORE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore))
43 #define GDK_DEVICE_CORE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
44 #define GDK_IS_DEVICE_CORE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE))
45 #define GDK_IS_DEVICE_CORE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE))
46 #define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
47
48 typedef struct _GdkDeviceCore GdkDeviceCore;
49 typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass;
50 typedef struct _GdkWaylandDevice GdkWaylandDevice;
51
52 typedef struct _DataOffer DataOffer;
53
54 typedef struct _GdkWaylandSelectionOffer GdkWaylandSelectionOffer;
55
56 struct _GdkWaylandDevice
57 {
58   struct wl_seat *wl_seat;
59   struct wl_pointer *wl_pointer;
60   struct wl_keyboard *wl_keyboard;
61
62   GdkDisplay *display;
63   GdkDeviceManager *device_manager;
64
65   GdkDevice *pointer;
66   GdkDevice *keyboard;
67
68   GdkModifierType modifiers;
69   GdkWindow *pointer_focus;
70   GdkWindow *keyboard_focus;
71   struct wl_data_device *data_device;
72   double surface_x, surface_y;
73   uint32_t time;
74   GdkWindow *pointer_grab_window;
75   uint32_t pointer_grab_time;
76   guint32 repeat_timer;
77   guint32 repeat_key;
78   guint32 repeat_count;
79
80   DataOffer *drag_offer;
81   DataOffer *selection_offer;
82
83   GdkWaylandSelectionOffer *selection_offer_out;
84
85   struct wl_surface *pointer_surface;
86 };
87
88 struct _GdkDeviceCore
89 {
90   GdkDevice parent_instance;
91   GdkWaylandDevice *device;
92 };
93
94 struct _GdkDeviceCoreClass
95 {
96   GdkDeviceClass parent_class;
97 };
98
99 G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE)
100
101 #define GDK_TYPE_DEVICE_MANAGER_CORE         (gdk_device_manager_core_get_type ())
102 #define GDK_DEVICE_MANAGER_CORE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore))
103 #define GDK_DEVICE_MANAGER_CORE_CLASS(c)     (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
104 #define GDK_IS_DEVICE_MANAGER_CORE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE))
105 #define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c)  (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE))
106 #define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
107
108 typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore;
109 typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass;
110
111 struct _GdkDeviceManagerCore
112 {
113   GdkDeviceManager parent_object;
114   GdkDevice *core_pointer;
115   GdkDevice *core_keyboard;
116   GList *devices;
117 };
118
119 struct _GdkDeviceManagerCoreClass
120 {
121   GdkDeviceManagerClass parent_class;
122 };
123
124 G_DEFINE_TYPE (GdkDeviceManagerCore,
125                gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER)
126
127 static gboolean
128 gdk_device_core_get_history (GdkDevice      *device,
129                              GdkWindow      *window,
130                              guint32         start,
131                              guint32         stop,
132                              GdkTimeCoord ***events,
133                              gint           *n_events)
134 {
135   return FALSE;
136 }
137
138 static void
139 gdk_device_core_get_state (GdkDevice       *device,
140                            GdkWindow       *window,
141                            gdouble         *axes,
142                            GdkModifierType *mask)
143 {
144   gint x_int, y_int;
145
146   gdk_window_get_device_position (window, device, &x_int, &y_int, mask);
147
148   if (axes)
149     {
150       axes[0] = x_int;
151       axes[1] = y_int;
152     }
153 }
154
155 static void
156 gdk_device_core_set_window_cursor (GdkDevice *device,
157                                    GdkWindow *window,
158                                    GdkCursor *cursor)
159 {
160   GdkWaylandDevice *wd = GDK_DEVICE_CORE(device)->device;
161   GdkWaylandDisplay *wayland_display =
162     GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
163   struct wl_buffer *buffer;
164   int x, y, w, h;
165
166   if (cursor)
167     g_object_ref (cursor);
168
169   /* Setting the cursor to NULL means that we should use the default cursor */
170   if (!cursor)
171     {
172       /* FIXME: Is this the best sensible default ? */
173       cursor = _gdk_wayland_display_get_cursor_for_type (device->display,
174                                                          GDK_LEFT_PTR);
175     }
176
177   buffer = _gdk_wayland_cursor_get_buffer (cursor, &x, &y, &w, &h);
178   wl_pointer_set_cursor (wd->wl_pointer,
179                          _gdk_wayland_display_get_serial (wayland_display),
180                          wd->pointer_surface,
181                          x, y);
182   wl_surface_attach (wd->pointer_surface, buffer, 0, 0);
183   wl_surface_damage (wd->pointer_surface,  0, 0, w, h);
184
185   g_object_unref (cursor);
186 }
187
188 static void
189 gdk_device_core_warp (GdkDevice *device,
190                       GdkScreen *screen,
191                       gint       x,
192                       gint       y)
193 {
194 }
195
196 static void
197 gdk_device_core_query_state (GdkDevice        *device,
198                              GdkWindow        *window,
199                              GdkWindow       **root_window,
200                              GdkWindow       **child_window,
201                              gint             *root_x,
202                              gint             *root_y,
203                              gint             *win_x,
204                              gint             *win_y,
205                              GdkModifierType  *mask)
206 {
207   GdkWaylandDevice *wd;
208   GdkScreen *default_screen;
209
210   wd = GDK_DEVICE_CORE(device)->device;
211   default_screen = gdk_display_get_default_screen (wd->display);
212
213   if (root_window)
214     *root_window = gdk_screen_get_root_window (default_screen);
215   if (child_window)
216     *child_window = wd->pointer_focus;
217   /* Do something clever for relative here */
218 #if 0
219   if (root_x)
220     *root_x = wd->x;
221   if (root_y)
222     *root_y = wd->y;
223 #endif
224   if (win_x)
225     *win_x = wd->surface_x;
226   if (win_y)
227     *win_y = wd->surface_y;
228   if (mask)
229     *mask = wd->modifiers;
230 }
231
232 static GdkGrabStatus
233 gdk_device_core_grab (GdkDevice    *device,
234                       GdkWindow    *window,
235                       gboolean      owner_events,
236                       GdkEventMask  event_mask,
237                       GdkWindow    *confine_to,
238                       GdkCursor    *cursor,
239                       guint32       time_)
240 {
241   GdkWaylandDevice *wayland_device = GDK_DEVICE_CORE (device)->device;
242
243   if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
244     {
245       /* Device is a keyboard */
246       return GDK_GRAB_SUCCESS;
247     }
248   else
249     {
250       /* Device is a pointer */
251
252       if (wayland_device->pointer_grab_window != NULL &&
253           time_ != 0 && wayland_device->pointer_grab_time > time_)
254         {
255           return GDK_GRAB_ALREADY_GRABBED;
256         }
257
258       if (time_ == 0)
259         time_ = wayland_device->time;
260
261       wayland_device->pointer_grab_window = window;
262       wayland_device->pointer_grab_time = time_;
263
264       /* FIXME: This probably breaks if you end up with multiple grabs on the
265        * same window - but we need to know the input device for when we are
266        * asked to map a popup window so that the grab can be managed by the
267        * compositor.
268        */
269       _gdk_wayland_window_set_device_grabbed (window,
270                                               wayland_device->wl_seat,
271                                               time_);
272     }
273
274   return GDK_GRAB_SUCCESS;
275 }
276
277 static void
278 gdk_device_core_ungrab (GdkDevice *device,
279                         guint32    time_)
280 {
281   GdkWaylandDevice *wayland_device = GDK_DEVICE_CORE (device)->device;
282   GdkDisplay *display;
283   GdkDeviceGrabInfo *grab;
284
285   display = gdk_device_get_display (device);
286
287   if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
288     {
289       /* Device is a keyboard */
290     }
291   else
292     {
293       /* Device is a pointer */
294       grab = _gdk_display_get_last_device_grab (display, device);
295
296       if (grab)
297         grab->serial_end = grab->serial_start;
298
299       if (wayland_device->pointer_grab_window)
300         _gdk_wayland_window_set_device_grabbed (wayland_device->pointer_grab_window,
301                                                 NULL,
302                                                 0);
303     }
304 }
305
306 static GdkWindow *
307 gdk_device_core_window_at_position (GdkDevice       *device,
308                                     gint            *win_x,
309                                     gint            *win_y,
310                                     GdkModifierType *mask,
311                                     gboolean         get_toplevel)
312 {
313   GdkWaylandDevice *wd;
314
315   wd = GDK_DEVICE_CORE(device)->device;
316   if (win_x)
317     *win_x = wd->surface_x;
318   if (win_y)
319     *win_y = wd->surface_y;
320   if (mask)
321     *mask = wd->modifiers;
322
323   return wd->pointer_focus;
324 }
325
326 static void
327 gdk_device_core_select_window_events (GdkDevice    *device,
328                                       GdkWindow    *window,
329                                       GdkEventMask  event_mask)
330 {
331 }
332
333 static void
334 gdk_device_core_class_init (GdkDeviceCoreClass *klass)
335 {
336   GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
337
338   device_class->get_history = gdk_device_core_get_history;
339   device_class->get_state = gdk_device_core_get_state;
340   device_class->set_window_cursor = gdk_device_core_set_window_cursor;
341   device_class->warp = gdk_device_core_warp;
342   device_class->query_state = gdk_device_core_query_state;
343   device_class->grab = gdk_device_core_grab;
344   device_class->ungrab = gdk_device_core_ungrab;
345   device_class->window_at_position = gdk_device_core_window_at_position;
346   device_class->select_window_events = gdk_device_core_select_window_events;
347 }
348
349 static void
350 gdk_device_core_init (GdkDeviceCore *device_core)
351 {
352   GdkDevice *device;
353
354   device = GDK_DEVICE (device_core);
355
356   _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
357   _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
358 }
359
360 struct wl_seat *
361 _gdk_wayland_device_get_wl_seat (GdkDevice *device)
362 {
363   return GDK_DEVICE_CORE (device)->device->wl_seat;
364 }
365
366 struct wl_pointer *
367 _gdk_wayland_device_get_wl_pointer (GdkDevice *device)
368 {
369   return GDK_DEVICE_CORE (device)->device->wl_pointer;
370 }
371
372
373 struct wl_keyboard *
374 _gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
375 {
376   return GDK_DEVICE_CORE (device)->device->wl_keyboard;
377 }
378
379 #if 0
380 static void
381 input_handle_motion(void *data, struct wl_input_device *input_device,
382                     uint32_t time,
383                     int32_t x, int32_t y, int32_t sx, int32_t sy)
384 {
385   GdkWaylandDevice *device = data;
386   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
387   GdkEvent *event;
388
389   event = gdk_event_new (GDK_NOTHING);
390
391   device->time = time;
392   device->x = x;
393   device->y = y;
394   device->surface_x = sx;
395   device->surface_y = sy;
396
397   event->motion.type = GDK_MOTION_NOTIFY;
398   event->motion.window = g_object_ref (device->pointer_focus);
399   gdk_event_set_device (event, device->pointer);
400   event->motion.time = time;
401   event->motion.x = (gdouble) sx;
402   event->motion.y = (gdouble) sy;
403   event->motion.x_root = (gdouble) x;
404   event->motion.y_root = (gdouble) y;
405   event->motion.axes = NULL;
406   event->motion.state = device->modifiers;
407   event->motion.is_hint = 0;
408   gdk_event_set_screen (event, display->screen);
409
410   GDK_NOTE (EVENTS,
411             g_message ("motion %d %d, state %d",
412                        sx, sy, event->button.state));
413
414   _gdk_wayland_display_deliver_event (device->display, event);
415 }
416
417 static void
418 input_handle_button(void *data, struct wl_input_device *input_device,
419                      uint32_t time, uint32_t button, uint32_t state)
420 {
421   GdkWaylandDevice *device = data;
422   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
423   GdkEvent *event;
424   uint32_t modifier;
425   int gdk_button;
426
427   switch (button) {
428   case 273:
429     gdk_button = 3;
430     break;
431   case 274:
432     gdk_button = 2;
433     break;
434   default:
435     gdk_button = button - 271;
436     break;
437   }
438
439   device->time = time;
440   event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
441   event->button.window = g_object_ref (device->pointer_focus);
442   gdk_event_set_device (event, device->pointer);
443   event->button.time = time;
444   event->button.x = (gdouble) device->surface_x;
445   event->button.y = (gdouble) device->surface_y;
446   event->button.x_root = (gdouble) device->x;
447   event->button.y_root = (gdouble) device->y;
448   event->button.axes = NULL;
449   event->button.state = device->modifiers;
450   event->button.button = gdk_button;
451   gdk_event_set_screen (event, display->screen);
452
453   modifier = 1 << (8 + gdk_button - 1);
454   if (state)
455     device->modifiers |= modifier;
456   else
457     device->modifiers &= ~modifier;
458
459   GDK_NOTE (EVENTS,
460             g_message ("button %d %s, state %d",
461                        event->button.button,
462                        state ? "press" : "release", event->button.state));
463
464   _gdk_wayland_display_deliver_event (device->display, event);
465 }
466
467 static void
468 translate_keyboard_string (GdkEventKey *event)
469 {
470   gunichar c = 0;
471   gchar buf[7];
472
473   /* Fill in event->string crudely, since various programs
474    * depend on it.
475    */
476   event->string = NULL;
477
478   if (event->keyval != GDK_KEY_VoidSymbol)
479     c = gdk_keyval_to_unicode (event->keyval);
480
481   if (c)
482     {
483       gsize bytes_written;
484       gint len;
485
486       /* Apply the control key - Taken from Xlib
487        */
488       if (event->state & GDK_CONTROL_MASK)
489         {
490           if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
491           else if (c == '2')
492             {
493               event->string = g_memdup ("\0\0", 2);
494               event->length = 1;
495               buf[0] = '\0';
496               return;
497             }
498           else if (c >= '3' && c <= '7') c -= ('3' - '\033');
499           else if (c == '8') c = '\177';
500           else if (c == '/') c = '_' & 0x1F;
501         }
502
503       len = g_unichar_to_utf8 (c, buf);
504       buf[len] = '\0';
505
506       event->string = g_locale_from_utf8 (buf, len,
507                                           NULL, &bytes_written,
508                                           NULL);
509       if (event->string)
510         event->length = bytes_written;
511     }
512   else if (event->keyval == GDK_KEY_Escape)
513     {
514       event->length = 1;
515       event->string = g_strdup ("\033");
516     }
517   else if (event->keyval == GDK_KEY_Return ||
518           event->keyval == GDK_KEY_KP_Enter)
519     {
520       event->length = 1;
521       event->string = g_strdup ("\r");
522     }
523
524   if (!event->string)
525     {
526       event->length = 0;
527       event->string = g_strdup ("");
528     }
529 }
530
531 static gboolean
532 keyboard_repeat (gpointer data);
533
534 static gboolean
535 deliver_key_event(GdkWaylandDevice *device,
536                   uint32_t time, uint32_t key, uint32_t state)
537 {
538   GdkEvent *event;
539   uint32_t code, modifier, level;
540   struct xkb_desc *xkb;
541   GdkKeymap *keymap;
542
543   keymap = gdk_keymap_get_for_display (device->display);
544   xkb = _gdk_wayland_keymap_get_xkb_desc (keymap);
545
546   device->time = time;
547   event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
548   event->key.window = g_object_ref (device->keyboard_focus);
549   gdk_event_set_device (event, device->keyboard);
550   event->button.time = time;
551   event->key.state = device->modifiers;
552   event->key.group = 0;
553   code = key + xkb->min_key_code;
554   event->key.hardware_keycode = code;
555
556   level = 0;
557   if (device->modifiers & XKB_COMMON_SHIFT_MASK &&
558       XkbKeyGroupWidth(xkb, code, 0) > 1)
559     level = 1;
560
561   event->key.keyval = XkbKeySymEntry(xkb, code, level, 0);
562
563   modifier = xkb->map->modmap[code];
564   if (state)
565     device->modifiers |= modifier;
566   else
567     device->modifiers &= ~modifier;
568
569   event->key.is_modifier = modifier > 0;
570
571   translate_keyboard_string (&event->key);
572
573   _gdk_wayland_display_deliver_event (device->display, event);
574
575   GDK_NOTE (EVENTS,
576             g_message ("keyboard event, code %d, sym %d, "
577                        "string %s, mods 0x%x",
578                        code, event->key.keyval,
579                        event->key.string, event->key.state));
580
581   device->repeat_count++;
582   device->repeat_key = key;
583
584   if (state == 0)
585     {
586       if (device->repeat_timer)
587         {
588           g_source_remove (device->repeat_timer);
589           device->repeat_timer = 0;
590         }
591       return FALSE;
592     }
593   else if (modifier)
594     {
595       return FALSE;
596     }
597   else switch (device->repeat_count)
598     {
599     case 1:
600       if (device->repeat_timer)
601         {
602           g_source_remove (device->repeat_timer);
603           device->repeat_timer = 0;
604         }
605
606       device->repeat_timer =
607         gdk_threads_add_timeout (400, keyboard_repeat, device);
608       return TRUE;
609     case 2:
610       device->repeat_timer =
611         gdk_threads_add_timeout (80, keyboard_repeat, device);
612       return FALSE;
613     default:
614       return TRUE;
615     }
616 }
617
618 static gboolean
619 keyboard_repeat (gpointer data)
620 {
621   GdkWaylandDevice *device = data;
622
623   return deliver_key_event (device, device->time, device->repeat_key, 1);
624 }
625
626 static void
627 input_handle_key(void *data, struct wl_input_device *input_device,
628                  uint32_t time, uint32_t key, uint32_t state)
629 {
630   GdkWaylandDevice *device = data;
631
632   device->repeat_count = 0;
633   deliver_key_event (data, time, key, state);
634 }
635
636 static void
637 input_handle_pointer_focus(void *data,
638                            struct wl_input_device *input_device,
639                            uint32_t time, struct wl_surface *surface,
640                            int32_t x, int32_t y, int32_t sx, int32_t sy)
641 {
642   GdkWaylandDevice *device = data;
643   GdkEvent *event;
644
645   device->time = time;
646   if (device->pointer_focus)
647     {
648       event = gdk_event_new (GDK_LEAVE_NOTIFY);
649       event->crossing.window = g_object_ref (device->pointer_focus);
650       gdk_event_set_device (event, device->pointer);
651       event->crossing.subwindow = NULL;
652       event->crossing.time = time;
653       event->crossing.x = (gdouble) device->surface_x;
654       event->crossing.y = (gdouble) device->surface_y;
655       event->crossing.x_root = (gdouble) device->x;
656       event->crossing.y_root = (gdouble) device->y;
657
658       event->crossing.mode = GDK_CROSSING_NORMAL;
659       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
660       event->crossing.focus = TRUE;
661       event->crossing.state = 0;
662
663       _gdk_wayland_display_deliver_event (device->display, event);
664
665       GDK_NOTE (EVENTS,
666                 g_message ("leave, device %p surface %p",
667                            device, device->pointer_focus));
668
669       g_object_unref(device->pointer_focus);
670       device->pointer_focus = NULL;
671     }
672
673   if (surface)
674     {
675       device->pointer_focus = wl_surface_get_user_data(surface);
676       g_object_ref(device->pointer_focus);
677
678       event = gdk_event_new (GDK_ENTER_NOTIFY);
679       event->crossing.window = g_object_ref (device->pointer_focus);
680       gdk_event_set_device (event, device->pointer);
681       event->crossing.subwindow = NULL;
682       event->crossing.time = time;
683       event->crossing.x = (gdouble) sx;
684       event->crossing.y = (gdouble) sy;
685       event->crossing.x_root = (gdouble) x;
686       event->crossing.y_root = (gdouble) y;
687
688       event->crossing.mode = GDK_CROSSING_NORMAL;
689       event->crossing.detail = GDK_NOTIFY_ANCESTOR;
690       event->crossing.focus = TRUE;
691       event->crossing.state = 0;
692
693       device->surface_x = sx;
694       device->surface_y = sy;
695       device->x = x;
696       device->y = y;
697
698       _gdk_wayland_display_deliver_event (device->display, event);
699
700       GDK_NOTE (EVENTS,
701                 g_message ("enter, device %p surface %p",
702                            device, device->pointer_focus));
703     }
704 }
705
706 static void
707 update_modifiers(GdkWaylandDevice *device, struct wl_array *keys)
708 {
709   uint32_t *k, *end;
710   GdkKeymap *keymap;
711   struct xkb_desc *xkb;
712
713   keymap = gdk_keymap_get_for_display (device->display);
714   xkb = _gdk_wayland_keymap_get_xkb_desc (keymap);
715
716   end = keys->data + keys->size;
717   device->modifiers = 0;
718   for (k = keys->data; k < end; k++)
719     device->modifiers |= xkb->map->modmap[*k];
720 }
721
722 static void
723 input_handle_keyboard_focus(void *data,
724                             struct wl_input_device *input_device,
725                             uint32_t time,
726                             struct wl_surface *surface,
727                             struct wl_array *keys)
728 {
729   GdkWaylandDevice *device = data;
730   GdkEvent *event;
731
732   device->time = time;
733   if (device->keyboard_focus)
734     {
735       _gdk_wayland_window_remove_focus (device->keyboard_focus);
736       event = gdk_event_new (GDK_FOCUS_CHANGE);
737       event->focus_change.window = g_object_ref (device->keyboard_focus);
738       event->focus_change.send_event = FALSE;
739       event->focus_change.in = FALSE;
740       gdk_event_set_device (event, device->keyboard);
741
742       g_object_unref(device->keyboard_focus);
743       device->keyboard_focus = NULL;
744
745       GDK_NOTE (EVENTS,
746                 g_message ("focus out, device %p surface %p",
747                            device, device->keyboard_focus));
748
749       _gdk_wayland_display_deliver_event (device->display, event);
750     }
751
752   if (surface)
753     {
754       device->keyboard_focus = wl_surface_get_user_data(surface);
755       g_object_ref(device->keyboard_focus);
756
757       event = gdk_event_new (GDK_FOCUS_CHANGE);
758       event->focus_change.window = g_object_ref (device->keyboard_focus);
759       event->focus_change.send_event = FALSE;
760       event->focus_change.in = TRUE;
761       gdk_event_set_device (event, device->keyboard);
762
763       update_modifiers (device, keys);
764
765       GDK_NOTE (EVENTS,
766                 g_message ("focus int, device %p surface %p",
767                            device, device->keyboard_focus));
768
769       _gdk_wayland_display_deliver_event (device->display, event);
770
771       _gdk_wayland_window_add_focus (device->keyboard_focus);
772     }
773 }
774
775 static const struct wl_input_device_listener input_device_listener = {
776   input_handle_motion,
777   input_handle_button,
778   input_handle_key,
779   input_handle_pointer_focus,
780   input_handle_keyboard_focus,
781 };
782 #endif
783
784 struct _DataOffer {
785   struct wl_data_offer *offer;
786   gint ref_count;
787   GPtrArray *types;
788 };
789
790 static void
791 data_offer_offer (void                 *data,
792                   struct wl_data_offer *wl_data_offer,
793                   const char           *type)
794 {
795   DataOffer *offer = (DataOffer *)data;
796   g_debug (G_STRLOC ": %s wl_data_offer = %p type = %s",
797            G_STRFUNC, wl_data_offer, type);
798
799   g_ptr_array_add (offer->types, g_strdup (type));
800 }
801
802 static void
803 data_offer_unref (DataOffer *offer)
804 {
805   offer->ref_count--;
806
807   if (offer->ref_count == 0)
808     {
809       g_ptr_array_free (offer->types, TRUE);
810       g_free (offer);
811     }
812 }
813
814 static const struct wl_data_offer_listener data_offer_listener = {
815   data_offer_offer,
816 };
817
818 static void
819 data_device_data_offer (void                  *data,
820                         struct wl_data_device *data_device,
821                         struct wl_data_offer  *_offer)
822 {
823   DataOffer *offer;
824
825   /* This structure is reference counted to handle the case where you get a
826    * leave but are in the middle of transferring data
827    */
828   offer = g_new0 (DataOffer, 1);
829   offer->ref_count = 1;
830   offer->types = g_ptr_array_new_with_free_func (g_free);
831   offer->offer = _offer;
832
833   /* The DataOffer structure is then retrieved later since this sets the user
834    * data.
835    */
836   wl_data_offer_add_listener (offer->offer,
837                               &data_offer_listener,
838                               offer);
839 }
840
841 static void
842 data_device_enter (void                  *data,
843                    struct wl_data_device *data_device,
844                    uint32_t               time,
845                    struct wl_surface     *surface,
846                    int32_t                x,
847                    int32_t                y,
848                    struct wl_data_offer  *offer)
849 {
850   GdkWaylandDevice *device = (GdkWaylandDevice *)data;
851
852   g_debug (G_STRLOC ": %s data_device = %p time = %d, surface = %p, x = %d y = %d, offer = %p",
853            G_STRFUNC, data_device, time, surface, x, y, offer);
854
855   /* Retrieve the DataOffer associated with with the wl_data_offer - this
856    * association is made when the listener is attached.
857    */
858   g_assert (device->drag_offer == NULL);
859   device->drag_offer = wl_data_offer_get_user_data (offer);
860 }
861
862 static void
863 data_device_leave (void                  *data,
864                    struct wl_data_device *data_device)
865 {
866   GdkWaylandDevice *device = (GdkWaylandDevice *)data;
867
868   g_debug (G_STRLOC ": %s data_device = %p",
869            G_STRFUNC, data_device);
870
871   data_offer_unref (device->drag_offer);
872   device->drag_offer = NULL;
873 }
874
875 static void
876 data_device_motion (void                  *data,
877                     struct wl_data_device *data_device,
878                     uint32_t               time,
879                     int32_t                x,
880                     int32_t                y)
881 {
882   g_debug (G_STRLOC ": %s data_device = %p, time = %d, x = %d, y = %d",
883            G_STRFUNC, data_device, time, x, y);
884 }
885
886 static void
887 data_device_drop (void                  *data,
888                   struct wl_data_device *data_device)
889 {
890   g_debug (G_STRLOC ": %s data_device = %p",
891            G_STRFUNC, data_device);
892 }
893
894 static void
895 data_device_selection (void                  *data,
896                        struct wl_data_device *wl_data_device,
897                        struct wl_data_offer  *offer)
898 {
899   GdkWaylandDevice *device = (GdkWaylandDevice *)data;
900
901   g_debug (G_STRLOC ": %s wl_data_device = %p wl_data_offer = %p",
902            G_STRFUNC, wl_data_device, offer);
903
904   if (!offer)
905     {
906       if (device->selection_offer)
907         {
908           data_offer_unref (device->selection_offer);
909           device->selection_offer = NULL;
910         }
911
912       return;
913     }
914
915   if (device->selection_offer)
916     {
917       data_offer_unref (device->selection_offer);
918       device->selection_offer = NULL;
919     }
920
921   /* Retrieve the DataOffer associated with with the wl_data_offer - this
922    * association is made when the listener is attached.
923    */
924   g_assert (device->selection_offer == NULL);
925   device->selection_offer = wl_data_offer_get_user_data (offer);
926 }
927
928 static const struct wl_data_device_listener data_device_listener = {
929   data_device_data_offer,
930   data_device_enter,
931   data_device_leave,
932   data_device_motion,
933   data_device_drop,
934   data_device_selection
935 };
936
937
938
939 static void
940 pointer_handle_enter (void              *data,
941                       struct wl_pointer *pointer,
942                       uint32_t           serial,
943                       struct wl_surface *surface,
944                       wl_fixed_t         sx,
945                       wl_fixed_t         sy)
946 {
947   GdkWaylandDevice *device = data;
948   GdkEvent *event;
949   GdkWaylandDisplay *wayland_display =
950     GDK_WAYLAND_DISPLAY (device->display);
951
952   _gdk_wayland_display_update_serial (wayland_display, serial);
953
954   device->pointer_focus = wl_surface_get_user_data(surface);
955   g_object_ref(device->pointer_focus);
956
957   event = gdk_event_new (GDK_ENTER_NOTIFY);
958   event->crossing.window = g_object_ref (device->pointer_focus);
959   gdk_event_set_device (event, device->pointer);
960   event->crossing.subwindow = NULL;
961   event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
962   event->crossing.x = wl_fixed_to_double (sx);
963   event->crossing.y = wl_fixed_to_double (sy);
964
965   event->crossing.mode = GDK_CROSSING_NORMAL;
966   event->crossing.detail = GDK_NOTIFY_ANCESTOR;
967   event->crossing.focus = TRUE;
968   event->crossing.state = 0;
969
970   device->surface_x = wl_fixed_to_double (sx);
971   device->surface_y = wl_fixed_to_double (sy);
972
973   _gdk_wayland_display_deliver_event (device->display, event);
974
975   GDK_NOTE (EVENTS,
976             g_message ("enter, device %p surface %p",
977                        device, device->pointer_focus));
978 }
979
980 static void
981 pointer_handle_leave (void              *data,
982                       struct wl_pointer *pointer,
983                       uint32_t           serial,
984                       struct wl_surface *surface)
985 {
986   GdkWaylandDevice *device = data;
987   GdkEvent *event;
988   GdkWaylandDisplay *wayland_display =
989     GDK_WAYLAND_DISPLAY (device->display);
990
991   _gdk_wayland_display_update_serial (wayland_display, serial);
992
993   event = gdk_event_new (GDK_LEAVE_NOTIFY);
994   event->crossing.window = g_object_ref (device->pointer_focus);
995   gdk_event_set_device (event, device->pointer);
996   event->crossing.subwindow = NULL;
997   event->crossing.time = (guint32)(g_get_monotonic_time () / 1000);
998   event->crossing.x = device->surface_x;
999   event->crossing.y = device->surface_y;
1000
1001   event->crossing.mode = GDK_CROSSING_NORMAL;
1002   event->crossing.detail = GDK_NOTIFY_ANCESTOR;
1003   event->crossing.focus = TRUE;
1004   event->crossing.state = 0;
1005
1006   _gdk_wayland_display_deliver_event (device->display, event);
1007
1008   GDK_NOTE (EVENTS,
1009             g_message ("leave, device %p surface %p",
1010                        device, device->pointer_focus));
1011
1012   g_object_unref(device->pointer_focus);
1013   device->pointer_focus = NULL;
1014 }
1015
1016 static void
1017 pointer_handle_motion (void              *data,
1018                        struct wl_pointer *pointer,
1019                        uint32_t           time,
1020                        wl_fixed_t         sx,
1021                        wl_fixed_t         sy)
1022 {
1023   GdkWaylandDevice *device = data;
1024   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
1025   GdkEvent *event;
1026
1027   event = gdk_event_new (GDK_NOTHING);
1028
1029   device->time = time;
1030   device->surface_x = wl_fixed_to_double (sx);
1031   device->surface_y = wl_fixed_to_double (sy);
1032
1033   event->motion.type = GDK_MOTION_NOTIFY;
1034   event->motion.window = g_object_ref (device->pointer_focus);
1035   gdk_event_set_device (event, device->pointer);
1036   event->motion.time = time;
1037   event->motion.x = wl_fixed_to_double (sx);
1038   event->motion.y = wl_fixed_to_double (sy);
1039   event->motion.axes = NULL;
1040   event->motion.state = device->modifiers;
1041   event->motion.is_hint = 0;
1042   gdk_event_set_screen (event, display->screen);
1043
1044   GDK_NOTE (EVENTS,
1045             g_message ("motion %d %d, state %d",
1046                        sx, sy, event->button.state));
1047
1048   _gdk_wayland_display_deliver_event (device->display, event);
1049 }
1050
1051 static void
1052 pointer_handle_button (void              *data,
1053                        struct wl_pointer *pointer,
1054                        uint32_t           serial,
1055                        uint32_t           time,
1056                        uint32_t           button,
1057                        uint32_t           state)
1058 {
1059   GdkWaylandDevice *device = data;
1060   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
1061   GdkEvent *event;
1062   uint32_t modifier;
1063   int gdk_button;
1064   GdkWaylandDisplay *wayland_display =
1065     GDK_WAYLAND_DISPLAY (device->display);
1066
1067   _gdk_wayland_display_update_serial (wayland_display, serial);
1068
1069   switch (button) {
1070   case 273:
1071     gdk_button = 3;
1072     break;
1073   case 274:
1074     gdk_button = 2;
1075     break;
1076   default:
1077     gdk_button = button - 271;
1078     break;
1079   }
1080
1081   device->time = time;
1082
1083   event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
1084   event->button.window = g_object_ref (device->pointer_focus);
1085   gdk_event_set_device (event, device->pointer);
1086   event->button.time = time;
1087   event->button.x = device->surface_x;
1088   event->button.y = device->surface_y;
1089   event->button.axes = NULL;
1090   event->button.state = device->modifiers;
1091   event->button.button = gdk_button;
1092   gdk_event_set_screen (event, display->screen);
1093
1094   modifier = 1 << (8 + gdk_button - 1);
1095   if (state)
1096     device->modifiers |= modifier;
1097   else
1098     device->modifiers &= ~modifier;
1099
1100   GDK_NOTE (EVENTS,
1101             g_message ("button %d %s, state %d",
1102                        event->button.button,
1103                        state ? "press" : "release", event->button.state));
1104
1105   _gdk_wayland_display_deliver_event (device->display, event);
1106 }
1107
1108 static void
1109 pointer_handle_axis (void              *data,
1110                      struct wl_pointer *pointer,
1111                      uint32_t           time,
1112                      uint32_t           axis,
1113                      wl_fixed_t         value)
1114 {
1115 }
1116
1117 static void
1118 keyboard_handle_keymap (void               *data,
1119                        struct wl_keyboard *keyboard,
1120                        uint32_t            format,
1121                        int                 fd,
1122                        uint32_t            size)
1123 {
1124   GdkWaylandDevice *device = data;
1125   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
1126   GdkKeymap *gdk_keymap;
1127   gchar *keymap_data;
1128   struct xkb_keymap *keymap;
1129
1130   if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
1131     {
1132       g_critical (G_STRLOC ": Unknown keymap format");
1133       close (fd);
1134       return;
1135     }
1136
1137   keymap_data = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
1138   if (keymap_data == MAP_FAILED)
1139     {
1140       g_critical (G_STRLOC ": Unable to map fd for keymap %s", g_strerror (errno));
1141       close (fd);
1142       return;
1143     }
1144
1145   keymap = xkb_map_new_from_string (display->xkb_context,
1146                                     keymap_data,
1147                                     format,
1148                                     0);
1149
1150   munmap (keymap_data, size);
1151   close (fd);
1152
1153   gdk_keymap = _gdk_wayland_display_get_keymap (device->display);
1154   _gdk_wayland_keymap_update_keymap (gdk_keymap, keymap);
1155 }
1156
1157 static void
1158 keyboard_handle_enter (void               *data,
1159                        struct wl_keyboard *keyboard,
1160                        uint32_t            serial,
1161                        struct wl_surface  *surface,
1162                        struct wl_array    *keys)
1163 {
1164
1165 }
1166
1167 static void
1168 keyboard_handle_leave (void               *data,
1169                        struct wl_keyboard *keyboard,
1170                        uint32_t            serial,
1171                        struct wl_surface  *surface)
1172 {
1173 }
1174
1175 static void
1176 keyboard_handle_key (void               *data,
1177                      struct wl_keyboard *keyboard,
1178                      uint32_t            serial,
1179                      uint32_t            time,
1180                      uint32_t            key,
1181                      uint32_t            state_w)
1182 {
1183 }
1184
1185 static void
1186 keyboard_handle_modifiers (void               *data,
1187                            struct wl_keyboard *keyboard,
1188                            uint32_t            serial,
1189                            uint32_t            mods_depressed,
1190                            uint32_t            mods_latched,
1191                            uint32_t            mods_locked,
1192                            uint32_t            group)
1193 {
1194 }
1195
1196 static const struct wl_pointer_listener pointer_listener = {
1197     pointer_handle_enter,
1198     pointer_handle_leave,
1199     pointer_handle_motion,
1200     pointer_handle_button,
1201     pointer_handle_axis,
1202 };
1203
1204 static const struct wl_keyboard_listener keyboard_listener = {
1205     keyboard_handle_keymap,
1206     keyboard_handle_enter,
1207     keyboard_handle_leave,
1208     keyboard_handle_key,
1209     keyboard_handle_modifiers,
1210 };
1211
1212 static void
1213 seat_handle_capabilities(void *data, struct wl_seat *seat,
1214                          enum wl_seat_capability caps)
1215 {
1216   GdkWaylandDevice *device = data;
1217   GdkDeviceManagerCore *device_manager_core =
1218     GDK_DEVICE_MANAGER_CORE(device->device_manager);
1219
1220   if ((caps & WL_SEAT_CAPABILITY_POINTER) && !device->wl_pointer)
1221     {
1222       device->wl_pointer = wl_seat_get_pointer(seat);
1223       wl_pointer_set_user_data(device->wl_pointer, device);
1224       wl_pointer_add_listener(device->wl_pointer, &pointer_listener,
1225                               device);
1226
1227       device->pointer = g_object_new (GDK_TYPE_DEVICE_CORE,
1228                                       "name", "Core Pointer",
1229                                       "type", GDK_DEVICE_TYPE_MASTER,
1230                                       "input-source", GDK_SOURCE_MOUSE,
1231                                       "input-mode", GDK_MODE_SCREEN,
1232                                       "has-cursor", TRUE,
1233                                       "display", device->display,
1234                                       "device-manager", device->device_manager,
1235                                       NULL);
1236       GDK_DEVICE_CORE (device->pointer)->device = device;
1237
1238       device_manager_core->devices =
1239         g_list_prepend (device_manager_core->devices, device->pointer);
1240     }
1241   else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && device->wl_pointer)
1242     {
1243       wl_pointer_destroy(device->wl_pointer);
1244       device->wl_pointer = NULL;
1245
1246       device_manager_core->devices =
1247         g_list_remove (device_manager_core->devices, device->pointer);
1248
1249       g_object_unref (device->pointer);
1250       device->pointer = NULL;
1251     }
1252
1253   if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->wl_keyboard) 
1254     {
1255       device->wl_keyboard = wl_seat_get_keyboard(seat);
1256       wl_keyboard_set_user_data(device->wl_keyboard, device);
1257       wl_keyboard_add_listener(device->wl_keyboard, &keyboard_listener,
1258                                device);
1259
1260       device->keyboard = g_object_new (GDK_TYPE_DEVICE_CORE,
1261                                        "name", "Core Keyboard",
1262                                        "type", GDK_DEVICE_TYPE_MASTER,
1263                                        "input-source", GDK_SOURCE_KEYBOARD,
1264                                        "input-mode", GDK_MODE_SCREEN,
1265                                        "has-cursor", FALSE,
1266                                        "display", device->display,
1267                                        "device-manager", device->device_manager,
1268                                        NULL);
1269       GDK_DEVICE_CORE (device->keyboard)->device = device;
1270
1271       device_manager_core->devices =
1272         g_list_prepend (device_manager_core->devices, device->keyboard);
1273     }
1274   else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && device->wl_keyboard) 
1275     {
1276       wl_keyboard_destroy(device->wl_keyboard);
1277       device->wl_keyboard = NULL;
1278
1279       device_manager_core->devices =
1280         g_list_remove (device_manager_core->devices, device->keyboard);
1281
1282       g_object_unref (device->keyboard);
1283       device->keyboard = NULL;
1284     }
1285
1286   if (device->keyboard && device->pointer)
1287     {
1288       _gdk_device_set_associated_device (device->pointer, device->keyboard);
1289       _gdk_device_set_associated_device (device->keyboard, device->pointer);
1290     }
1291 }
1292
1293 static const struct wl_seat_listener seat_listener = {
1294     seat_handle_capabilities,
1295 };
1296
1297 void
1298 _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
1299                                         struct wl_seat *wl_seat)
1300 {
1301   GdkDisplay *display;
1302   GdkWaylandDisplay *display_wayland;
1303   GdkWaylandDevice *device;
1304
1305   display = gdk_device_manager_get_display (device_manager);
1306   display_wayland = GDK_WAYLAND_DISPLAY (display);
1307
1308   device = g_new0 (GdkWaylandDevice, 1);
1309   device->display = display;
1310   device->device_manager = device_manager;
1311
1312   device->wl_seat = wl_seat;
1313
1314   wl_seat_add_listener (device->wl_seat, &seat_listener, device);
1315   wl_seat_set_user_data (device->wl_seat, device);
1316
1317   device->data_device =
1318     wl_data_device_manager_get_data_device (display_wayland->data_device_manager,
1319                                             device->wl_seat);
1320   wl_data_device_add_listener (device->data_device,
1321                                &data_device_listener, device);
1322
1323   device->pointer_surface =
1324     wl_compositor_create_surface (display_wayland->compositor);
1325 }
1326
1327 static void
1328 free_device (gpointer data)
1329 {
1330   g_object_unref (data);
1331 }
1332
1333 static void
1334 gdk_device_manager_core_finalize (GObject *object)
1335 {
1336   GdkDeviceManagerCore *device_manager_core;
1337
1338   device_manager_core = GDK_DEVICE_MANAGER_CORE (object);
1339
1340   g_list_free_full (device_manager_core->devices, free_device);
1341
1342   G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object);
1343 }
1344
1345 static GList *
1346 gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
1347                                       GdkDeviceType     type)
1348 {
1349   GdkDeviceManagerCore *device_manager_core;
1350   GList *devices = NULL;
1351
1352   if (type == GDK_DEVICE_TYPE_MASTER)
1353     {
1354       device_manager_core = (GdkDeviceManagerCore *) device_manager;
1355       devices = g_list_copy(device_manager_core->devices);
1356     }
1357
1358   return devices;
1359 }
1360
1361 static GdkDevice *
1362 gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager)
1363 {
1364   GdkDeviceManagerCore *device_manager_core;
1365   GList *l;
1366
1367   device_manager_core = (GdkDeviceManagerCore *) device_manager;
1368
1369   /* Find the first pointer device */
1370   for (l = device_manager_core->devices; l != NULL; l = l->next)
1371     {
1372       GdkDevice *device = l->data;
1373
1374       if (gdk_device_get_source (device) == GDK_SOURCE_MOUSE)
1375         return device;
1376     }
1377
1378   return NULL;
1379 }
1380
1381 static void
1382 gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass)
1383 {
1384   GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
1385   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1386
1387   object_class->finalize = gdk_device_manager_core_finalize;
1388   device_manager_class->list_devices = gdk_device_manager_core_list_devices;
1389   device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer;
1390 }
1391
1392 static void
1393 gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager)
1394 {
1395 }
1396
1397 GdkDeviceManager *
1398 _gdk_wayland_device_manager_new (GdkDisplay *display)
1399 {
1400   return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
1401                        "display", display,
1402                        NULL);
1403 }
1404
1405 gint
1406 gdk_wayland_device_get_selection_type_atoms (GdkDevice  *gdk_device,
1407                                              GdkAtom   **atoms_out)
1408 {
1409   gint i;
1410   GdkAtom *atoms;
1411   GdkWaylandDevice *device;
1412
1413   g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), 0);
1414   g_return_val_if_fail (atoms_out != NULL, 0);
1415
1416   device = GDK_DEVICE_CORE (gdk_device)->device;
1417
1418   if (!device->selection_offer || device->selection_offer->types->len == 0)
1419     {
1420       *atoms_out = NULL;
1421       return 0;
1422     }
1423
1424   atoms = g_new0 (GdkAtom, device->selection_offer->types->len);
1425
1426   /* Convert list of targets to atoms */
1427   for (i = 0; i < device->selection_offer->types->len; i++)
1428     {
1429       atoms[i] = gdk_atom_intern (device->selection_offer->types->pdata[i],
1430                                   FALSE);
1431       GDK_NOTE (MISC,
1432                 g_message (G_STRLOC ": Adding atom for %s",
1433                            (char *)device->selection_offer->types->pdata[i]));
1434     }
1435
1436   *atoms_out = atoms;
1437   return device->selection_offer->types->len;
1438 }
1439
1440 typedef struct
1441 {
1442   GdkWaylandDevice *device;
1443   DataOffer *offer;
1444   GIOChannel *channel;
1445   GdkDeviceWaylandRequestContentCallback cb;
1446   gpointer userdata;
1447 } RequestContentClosure;
1448
1449 static gboolean
1450 _request_content_io_func (GIOChannel *channel,
1451                           GIOCondition condition,
1452                           gpointer userdata)
1453 {
1454   RequestContentClosure *closure = (RequestContentClosure *)userdata;
1455   gchar *data = NULL;
1456   gsize len = 0;
1457   GError *error = NULL;
1458
1459   /* FIXME: We probably want to do something better than this to avoid
1460    * blocking on the transfer of large pieces of data: call the callback
1461    * multiple times I should think.
1462    */
1463   if (g_io_channel_read_to_end (channel,
1464                                 &data,
1465                                 &len,
1466                                 &error) != G_IO_STATUS_NORMAL)
1467     {
1468       g_warning (G_STRLOC ": Error reading content from pipe: %s", error->message);
1469       g_clear_error (&error);
1470     }
1471
1472   /* Since we use _read_to_end we've got a guaranteed EOF and thus can go
1473    * ahead and close the fd
1474    */
1475   g_io_channel_shutdown (channel, TRUE, NULL);
1476
1477   closure->cb (closure->device->pointer, data, len, closure->userdata);
1478
1479   g_free (data);
1480   data_offer_unref (closure->offer);
1481   g_io_channel_unref (channel);
1482   g_free (closure);
1483
1484   return FALSE;
1485 }
1486
1487 gboolean
1488 gdk_wayland_device_request_selection_content (GdkDevice                              *gdk_device,
1489                                               const gchar                            *requested_mime_type,
1490                                               GdkDeviceWaylandRequestContentCallback  cb,
1491                                               gpointer                                userdata)
1492 {
1493   int pipe_fd[2];
1494   RequestContentClosure *closure;
1495   GdkWaylandDevice *device;
1496   GError *error = NULL;
1497
1498   g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), FALSE);
1499   g_return_val_if_fail (requested_mime_type != NULL, FALSE);
1500   g_return_val_if_fail (cb != NULL, FALSE);
1501
1502   device = GDK_DEVICE_CORE (gdk_device)->device;
1503
1504   if (!device->selection_offer)
1505       return FALSE;
1506
1507   /* TODO: Check mimetypes */
1508
1509   closure = g_new0 (RequestContentClosure, 1);
1510
1511   device->selection_offer->ref_count++;
1512
1513   pipe2 (pipe_fd, O_CLOEXEC);
1514   wl_data_offer_receive (device->selection_offer->offer,
1515                          requested_mime_type,
1516                          pipe_fd[1]);
1517   close (pipe_fd[1]);
1518
1519   closure->device = device;
1520   closure->offer = device->selection_offer;
1521   closure->channel = g_io_channel_unix_new (pipe_fd[0]);
1522   closure->cb = cb;
1523   closure->userdata = userdata;
1524
1525   if (!g_io_channel_set_encoding (closure->channel, NULL, &error))
1526     {
1527       g_warning (G_STRLOC ": Error setting encoding on channel: %s",
1528                  error->message);
1529       g_clear_error (&error);
1530       goto error;
1531     }
1532
1533   g_io_add_watch (closure->channel,
1534                   G_IO_IN,
1535                   _request_content_io_func,
1536                   closure);
1537
1538   return TRUE;
1539
1540 error:
1541   data_offer_unref (closure->offer);
1542   g_io_channel_unref (closure->channel);
1543   close (pipe_fd[1]);
1544   g_free (closure);
1545
1546   return FALSE;
1547 }
1548
1549 struct _GdkWaylandSelectionOffer {
1550   GdkDeviceWaylandOfferContentCallback cb;
1551   gpointer userdata;
1552   struct wl_data_source *source;
1553   GdkWaylandDevice *device;
1554 };
1555
1556 static void
1557 data_source_target (void                  *data,
1558                     struct wl_data_source *source,
1559                     const char            *mime_type)
1560 {
1561   g_debug (G_STRLOC ": %s source = %p, mime_type = %s",
1562            G_STRFUNC, source, mime_type);
1563 }
1564
1565 static void
1566 data_source_send (void                  *data,
1567                   struct wl_data_source *source,
1568                   const char            *mime_type,
1569                   int32_t                fd)
1570 {
1571   GdkWaylandSelectionOffer *offer = (GdkWaylandSelectionOffer *)data;;
1572   gchar *buf;
1573   gssize len, bytes_written = 0;
1574
1575   g_debug (G_STRLOC ": %s source = %p, mime_type = %s fd = %d",
1576            G_STRFUNC, source, mime_type, fd);
1577
1578   buf = offer->cb (offer->device->pointer, mime_type, &len, offer->userdata);
1579
1580   while (len > 0)
1581     {
1582       bytes_written += write (fd, buf + bytes_written, len);
1583       if (bytes_written == -1)
1584         goto error;
1585       len -= bytes_written;
1586     }
1587
1588   close (fd);
1589   g_free (buf);
1590
1591   return;
1592 error:
1593
1594   g_warning (G_STRLOC ": Error writing data to client: %s",
1595              g_strerror (errno));
1596
1597   close (fd);
1598   g_free (buf);
1599 }
1600
1601 static void
1602 data_source_cancelled (void                  *data,
1603                        struct wl_data_source *source)
1604 {
1605   g_debug (G_STRLOC ": %s source = %p",
1606            G_STRFUNC, source);
1607 }
1608
1609 static const struct wl_data_source_listener data_source_listener = {
1610     data_source_target,
1611     data_source_send,
1612     data_source_cancelled
1613 };
1614
1615 static guint32
1616 _wl_time_now (void)
1617 {
1618   struct timeval tv;
1619
1620   gettimeofday(&tv, NULL);
1621
1622   return tv.tv_sec * 1000 + tv.tv_usec / 1000;
1623 }
1624
1625 gboolean
1626 gdk_wayland_device_offer_selection_content (GdkDevice                             *gdk_device,
1627                                             const gchar                          **mime_types,
1628                                             gint                                   nr_mime_types,
1629                                             GdkDeviceWaylandOfferContentCallback   cb,
1630                                             gpointer                               userdata)
1631 {
1632   GdkDisplay *display;
1633   GdkWaylandDisplay *display_wayland;
1634   GdkWaylandSelectionOffer *offer;
1635   GdkWaylandDevice *device;
1636   gint i;
1637
1638   g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), 0);
1639   device = GDK_DEVICE_CORE (gdk_device)->device;
1640
1641   display = device->display;
1642   display_wayland = GDK_WAYLAND_DISPLAY (display);
1643
1644   offer = g_new0 (GdkWaylandSelectionOffer, 1);
1645   offer->cb = cb;
1646   offer->userdata = userdata;
1647   offer->source =
1648     wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
1649   offer->device = device;
1650
1651   for (i = 0; i < nr_mime_types; i++)
1652     {
1653       wl_data_source_offer (offer->source,
1654                             mime_types[i]);
1655     }
1656
1657   wl_data_source_add_listener (offer->source,
1658                                &data_source_listener,
1659                                offer);
1660
1661   wl_data_device_set_selection (device->data_device,
1662                                 offer->source,
1663                                 _wl_time_now ());
1664
1665   device->selection_offer_out = offer;
1666
1667   return TRUE;
1668 }
1669
1670 gboolean
1671 gdk_wayland_device_clear_selection_content (GdkDevice *gdk_device)
1672 {
1673   GdkWaylandDevice *device;
1674
1675   g_return_val_if_fail (GDK_IS_DEVICE_CORE (gdk_device), 0);
1676   device = GDK_DEVICE_CORE (gdk_device)->device;
1677
1678   if (!device->selection_offer_out)
1679     return FALSE;
1680
1681   wl_data_device_set_selection (device->data_device,
1682                                 NULL,
1683                                 _wl_time_now ());
1684
1685   wl_data_source_destroy (device->selection_offer_out->source);
1686   g_free (device->selection_offer_out);
1687   device->selection_offer_out = NULL;
1688
1689   return TRUE;
1690 }