]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkwindow-wayland.c
wayland: attempt to determine the possible parent surface for popups
[~andy/gtk] / gdk / wayland / gdkwindow-wayland.c
1 /*
2  * Copyright © 2010 Intel Corporation
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 License
6  * as published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * 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 #include "config.h"
19
20 #include <netinet/in.h>
21 #include <unistd.h>
22
23 #include "gdk.h"
24 #include "gdkwayland.h"
25
26 #include "gdkwindow.h"
27 #include "gdkwindowimpl.h"
28 #include "gdkdisplay-wayland.h"
29 #include "gdkprivate-wayland.h"
30 #include "gdkinternals.h"
31 #include "gdkdeviceprivate.h"
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <sys/mman.h>
37 #include <errno.h>
38
39 #include <wayland-egl.h>
40
41 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
42   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
43    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
44
45 #define WINDOW_IS_TOPLEVEL(window)                   \
46   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
47    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
48    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
49
50 /* Return whether time1 is considered later than time2 as far as xserver
51  * time is concerned.  Accounts for wraparound.
52  */
53 #define XSERVER_TIME_IS_LATER(time1, time2)                        \
54   ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
55     (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
56   )
57
58 typedef struct _GdkWaylandWindow GdkWaylandWindow;
59 typedef struct _GdkWaylandWindowClass GdkWaylandWindowClass;
60
61 struct _GdkWaylandWindow {
62   GdkWindow parent;
63 };
64
65 struct _GdkWaylandWindowClass {
66   GdkWindowClass parent_class;
67 };
68
69 G_DEFINE_TYPE (GdkWaylandWindow, gdk_wayland_window, GDK_TYPE_WINDOW)
70
71 static void
72 gdk_wayland_window_class_init (GdkWaylandWindowClass *wayland_window_class)
73 {
74 }
75
76 static void
77 gdk_wayland_window_init (GdkWaylandWindow *wayland_window)
78 {
79 }
80
81 #define GDK_TYPE_WINDOW_IMPL_WAYLAND              (_gdk_window_impl_wayland_get_type ())
82 #define GDK_WINDOW_IMPL_WAYLAND(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWayland))
83 #define GDK_WINDOW_IMPL_WAYLAND_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass))
84 #define GDK_IS_WINDOW_IMPL_WAYLAND(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND))
85 #define GDK_IS_WINDOW_IMPL_WAYLAND_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND))
86 #define GDK_WINDOW_IMPL_WAYLAND_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass))
87
88 typedef struct _GdkWindowImplWayland GdkWindowImplWayland;
89 typedef struct _GdkWindowImplWaylandClass GdkWindowImplWaylandClass;
90
91 struct _GdkWindowImplWayland
92 {
93   GdkWindowImpl parent_instance;
94
95   GdkWindow *wrapper;
96
97   GdkCursor *cursor;
98
99   gint8 toplevel_window_type;
100
101   struct wl_surface *surface;
102   struct wl_shell_surface *shell_surface;
103   unsigned int mapped : 1;
104   GdkWindow *transient_for;
105   GdkWindowTypeHint hint;
106
107   /* The surface which is being "drawn to" to */
108   cairo_surface_t *cairo_surface;
109
110   /* The surface that was the last surface the Wayland buffer from which was attached
111    * to the Wayland surface. It will be the same as cairo_surface after a call
112    * to gdk_wayland_window_attach_image. But after a call to
113    * gdk_wayland_window_update_size and then
114    * gdk_wayland_window_ref_cairo_surface the above pointer will be different.
115    */
116   cairo_surface_t *server_surface;
117
118   uint32_t resize_edges;
119
120   int focus_count;
121
122   gulong map_serial;    /* Serial of last transition from unmapped */
123
124   cairo_surface_t *icon_pixmap;
125   cairo_surface_t *icon_mask;
126
127   /* Time of most recent user interaction. */
128   gulong user_time;
129
130   GdkGeometry geometry_hints;
131   GdkWindowHints geometry_mask;
132
133   GdkDevice *grab_device;
134   struct wl_seat *grab_input_seat;
135   guint32 grab_time;
136
137   gboolean fullscreen;
138   int saved_width, saved_height; /* before going fullscreen */
139 };
140
141 struct _GdkWindowImplWaylandClass
142 {
143   GdkWindowImplClass parent_class;
144 };
145
146 G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL)
147
148 static void
149 _gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
150 {
151   impl->toplevel_window_type = -1;
152 }
153
154 void
155 _gdk_wayland_window_add_focus (GdkWindow *window)
156 {
157   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
158
159   impl->focus_count++;
160   if (impl->focus_count == 1)
161     gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FOCUSED);
162 }
163
164 void
165 _gdk_wayland_window_remove_focus (GdkWindow *window)
166 {
167   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
168
169   impl->focus_count--;
170   if (impl->focus_count == 0)
171     gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FOCUSED, 0);
172 }
173
174 /**
175  * gdk_wayland_window_update_size:
176  * @drawable: a #GdkDrawableImplWayland.
177  * 
178  * Updates the state of the drawable (in particular the drawable's
179  * cairo surface) when its size has changed.
180  **/
181 static void
182 gdk_wayland_window_update_size (GdkWindow *window,
183                                 int32_t width, int32_t height, uint32_t edges)
184 {
185   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
186   GdkRectangle area;
187   cairo_region_t *region;
188
189   if (impl->cairo_surface)
190     {
191       cairo_surface_destroy (impl->cairo_surface);
192       impl->cairo_surface = NULL;
193     }
194
195   window->width = width;
196   window->height = height;
197   impl->resize_edges = edges;
198
199   area.x = 0;
200   area.y = 0;
201   area.width = window->width;
202   area.height = window->height;
203
204   region = cairo_region_create_rectangle (&area);
205   _gdk_window_invalidate_for_expose (window, region);
206   cairo_region_destroy (region);
207 }
208
209 GdkWindow *
210 _gdk_wayland_screen_create_root_window (GdkScreen *screen,
211                                         int width, int height)
212 {
213   GdkWindow *window;
214   GdkWindowImplWayland *impl;
215
216   window = _gdk_display_create_window (gdk_screen_get_display (screen));
217   window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
218   window->impl_window = window;
219   window->visual = gdk_screen_get_system_visual (screen);
220
221   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
222
223   impl->wrapper = GDK_WINDOW (window);
224
225   window->window_type = GDK_WINDOW_ROOT;
226   window->depth = 32;
227
228   window->x = 0;
229   window->y = 0;
230   window->abs_x = 0;
231   window->abs_y = 0;
232   window->width = width;
233   window->height = height;
234   window->viewable = TRUE;
235
236   /* see init_randr_support() in gdkscreen-wayland.c */
237   window->event_mask = GDK_STRUCTURE_MASK;
238
239   return window;
240 }
241
242 static const gchar *
243 get_default_title (void)
244 {
245   const char *title;
246
247   title = g_get_application_name ();
248   if (!title)
249     title = g_get_prgname ();
250   if (!title)
251     title = "";
252
253   return title;
254 }
255
256 void
257 _gdk_wayland_display_create_window_impl (GdkDisplay    *display,
258                                          GdkWindow     *window,
259                                          GdkWindow     *real_parent,
260                                          GdkScreen     *screen,
261                                          GdkEventMask   event_mask,
262                                          GdkWindowAttr *attributes,
263                                          gint           attributes_mask)
264 {
265   GdkWindowImplWayland *impl;
266   const char *title;
267
268   impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
269   window->impl = GDK_WINDOW_IMPL (impl);
270   impl->wrapper = GDK_WINDOW (window);
271
272   if (window->width > 65535 ||
273       window->height > 65535)
274     {
275       g_warning ("Native Windows wider or taller than 65535 pixels are not supported");
276
277       if (window->width > 65535)
278         window->width = 65535;
279       if (window->height > 65535)
280         window->height = 65535;
281     }
282
283   g_object_ref (window);
284
285   switch (GDK_WINDOW_TYPE (window))
286     {
287     case GDK_WINDOW_TOPLEVEL:
288     case GDK_WINDOW_TEMP:
289       if (attributes_mask & GDK_WA_TITLE)
290         title = attributes->title;
291       else
292         title = get_default_title ();
293
294       gdk_window_set_title (window, title);
295       break;
296
297     case GDK_WINDOW_CHILD:
298     default:
299       break;
300     }
301
302   if (attributes_mask & GDK_WA_TYPE_HINT)
303     gdk_window_set_type_hint (window, attributes->type_hint);
304 }
305
306 static const cairo_user_data_key_t gdk_wayland_cairo_key;
307
308 typedef struct _GdkWaylandCairoSurfaceData {
309   gpointer buf;
310   size_t buf_length;
311   struct wl_shm_pool *pool;
312   struct wl_buffer *buffer;
313   GdkWaylandDisplay *display;
314   int32_t width, height;
315 } GdkWaylandCairoSurfaceData;
316
317 static void
318 gdk_wayland_window_attach_image (GdkWindow *window)
319 {
320   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
321   GdkWaylandCairoSurfaceData *data;
322   int32_t server_width, server_height, dx, dy;
323
324   if (GDK_WINDOW_DESTROYED (window))
325     return;
326
327   /* The "drawn to" Cairo surface is the same as the Cairo surface from which
328    * we are driving the buffer for the Wayland surface. Therefore we don't
329    * need to do anything here
330    */
331   if (impl->server_surface == impl->cairo_surface)
332     return;
333
334   /* The wayland surface is attached to a buffer that is from the old "drawn
335    * to" surface. Unref the surface and restore the state.
336    */
337   if (impl->server_surface)
338     {
339       data = cairo_surface_get_user_data (impl->server_surface,
340                                           &gdk_wayland_cairo_key);
341
342       /* Save the old dimensions used for the surface */
343       server_width = data->width;
344       server_height = data->height;
345
346       cairo_surface_destroy (impl->server_surface);
347     }
348   else
349     {
350       server_width = 0;
351       server_height = 0;
352     }
353
354   /* Save the current "drawn to" surface for future calls into here */
355   impl->server_surface = cairo_surface_reference (impl->cairo_surface);
356
357   /* Get a Wayland buffer from this new surface */
358   data = cairo_surface_get_user_data (impl->cairo_surface,
359                                       &gdk_wayland_cairo_key);
360
361   if (impl->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT)
362     dx = server_width - data->width;
363   else
364     dx = 0;
365
366   if (impl->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP)
367     dy = server_height - data->height;
368   else
369     dy = 0;
370
371   /* Attach this new buffer to the surface */
372   wl_surface_attach (impl->surface, data->buffer, dx, dy);
373 }
374
375 static void
376 gdk_wayland_cairo_surface_destroy (void *p)
377 {
378   GdkWaylandCairoSurfaceData *data = p;
379
380   if (data->buffer)
381     wl_buffer_destroy (data->buffer);
382
383   if (data->pool)
384     wl_shm_pool_destroy (data->pool);
385
386   munmap (data->buf, data->buf_length);
387   g_free (data);
388 }
389
390
391 static struct wl_shm_pool *
392 _create_shm_pool (struct wl_shm  *shm,
393                   int             width,
394                   int             height,
395                   size_t         *buf_length,
396                   void          **data_out)
397 {
398   char filename[] = "/tmp/wayland-shm-XXXXXX";
399   struct wl_shm_pool *pool;
400   int fd, size, stride;
401   void *data;
402
403   fd = mkstemp (filename);
404   if (fd < 0) {
405       g_critical (G_STRLOC ": Unable to create temporary file (%s): %s",
406                   filename, g_strerror (errno));
407       return NULL;
408   }
409   stride = width * 4;
410   size = stride * height;
411   if (ftruncate (fd, size) < 0) {
412       g_critical (G_STRLOC ": Truncating temporary file failed: %s",
413                   g_strerror (errno));
414       close(fd);
415       return NULL;
416   }
417
418   data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
419   unlink (filename);
420
421   if (data == MAP_FAILED) {
422       g_critical (G_STRLOC ": mmap'ping temporary file failed: %s",
423                   g_strerror (errno));
424       close(fd);
425       return NULL;
426   }
427
428   pool = wl_shm_create_pool(shm, fd, size);
429
430   close (fd);
431
432   *data_out = data;
433   *buf_length = size;
434
435   return pool;
436 }
437
438 static cairo_surface_t *
439 gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
440                                   int width, int height)
441 {
442   GdkWaylandCairoSurfaceData *data;
443   cairo_surface_t *surface = NULL;
444   cairo_status_t status;
445   int stride;
446
447   data = g_new (GdkWaylandCairoSurfaceData, 1);
448   data->display = display;
449   data->buffer = NULL;
450   data->width = width;
451   data->height = height;
452
453   stride = width * 4;
454
455   data->pool = _create_shm_pool (display->shm,
456                                  width, height,
457                                  &data->buf_length,
458                                  &data->buf);
459
460   data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
461                                             width, height,
462                                             stride, WL_SHM_FORMAT_ARGB8888);
463
464   surface = cairo_image_surface_create_for_data (data->buf,
465                                                  CAIRO_FORMAT_ARGB32,
466                                                  width,
467                                                  height,
468                                                  stride);
469
470   cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
471                                data, gdk_wayland_cairo_surface_destroy);
472
473   status = cairo_surface_status (surface);
474   if (status != CAIRO_STATUS_SUCCESS)
475     {
476       g_critical (G_STRLOC ": Unable to create Cairo image surface: %s",
477                   cairo_status_to_string (status));
478     }
479
480   return surface;
481 }
482
483 /* On this first call this creates a double reference - the first reference
484  * is held by the GdkWindowImplWayland struct - since unlike other backends
485  * the Cairo surface is not just a cheap wrapper around some other backing.
486  * It is the buffer itself.
487  */
488 static cairo_surface_t *
489 gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
490 {
491   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
492   GdkWaylandDisplay *display_wayland =
493     GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper));
494
495   if (GDK_WINDOW_DESTROYED (impl->wrapper))
496     return NULL;
497
498   if (!impl->cairo_surface)
499     {
500       impl->cairo_surface =
501         gdk_wayland_create_cairo_surface (display_wayland,
502                                       impl->wrapper->width,
503                                       impl->wrapper->height);
504     }
505
506   cairo_surface_reference (impl->cairo_surface);
507
508   return impl->cairo_surface;
509 }
510
511
512 static void
513 gdk_window_impl_wayland_finalize (GObject *object)
514 {
515   GdkWindowImplWayland *impl;
516
517   g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (object));
518
519   impl = GDK_WINDOW_IMPL_WAYLAND (object);
520
521   if (impl->cursor)
522     g_object_unref (impl->cursor);
523   if (impl->server_surface)
524     cairo_surface_destroy (impl->server_surface);
525
526   G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
527 }
528
529 static void
530 gdk_wayland_window_configure (GdkWindow *window,
531                               int width, int height, int edges)
532 {
533   GdkDisplay *display;
534   GdkEvent *event;
535
536   display = gdk_window_get_display (window);
537
538   /* TODO: Only generate a configure event if width or height have actually
539    * changed?
540    */
541   event = gdk_event_new (GDK_CONFIGURE);
542   event->configure.window = window;
543   event->configure.send_event = FALSE;
544   event->configure.width = width;
545   event->configure.height = height;
546
547   _gdk_window_update_size (window);
548   gdk_wayland_window_update_size (window, width, height, edges);
549
550   g_object_ref(window);
551
552   _gdk_wayland_display_deliver_event (display, event);
553 }
554
555 static void
556 gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time)
557 {
558 }
559
560 static void
561 gdk_wayland_window_map (GdkWindow *window)
562 {
563   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
564   GdkWindowImplWayland *parent;
565   GdkWaylandDisplay *wayland_display =
566     GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
567   GdkWindow *transient_for;
568
569   if (!impl->mapped)
570     {
571       /* Popup menus can appear without a transient parent, which means they
572        * cannot be positioned properly on Wayland. This attempts to guess the
573        * surface they should be positioned with by finding the surface beneath
574        * the device that created the grab for the popup window */
575
576       if (!impl->transient_for && impl->hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU)
577         {
578           transient_for = gdk_device_get_window_at_position (impl->grab_device, NULL, NULL);
579           transient_for = gdk_window_get_toplevel (transient_for);
580
581           /* start the popup at the position of the device that holds the grab */
582           gdk_window_get_device_position (transient_for,
583                                           impl->grab_device,
584                                           &window->x, &window->y, NULL);
585         }
586       else
587         transient_for = impl->transient_for;
588
589       if (transient_for)
590         {
591           struct wl_seat *grab_input_seat = NULL;
592           GdkWindowImplWayland *tmp_impl;
593
594           parent = GDK_WINDOW_IMPL_WAYLAND (transient_for->impl);
595
596           /* Use the device that was used for the grab as the device for
597            * the popup window setup - so this relies on GTK+ taking the
598            * grab before showing the popup window.
599            */
600           grab_input_seat = impl->grab_input_seat;
601
602           tmp_impl = parent;
603           while (!grab_input_seat)
604             {
605               grab_input_seat = tmp_impl->grab_input_seat;
606
607               if (tmp_impl->transient_for)
608                 tmp_impl = GDK_WINDOW_IMPL_WAYLAND (tmp_impl->transient_for->impl);
609               else
610                 break;
611             }
612
613           if (grab_input_seat &&
614               (impl->hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU ||
615                impl->hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU ||
616                impl->hint == GDK_WINDOW_TYPE_HINT_COMBO))
617             {
618
619               wl_shell_surface_set_popup (impl->shell_surface,
620                                           grab_input_seat,
621                                           _gdk_wayland_display_get_serial (wayland_display),
622                                           parent->surface,
623                                           window->x, window->y, 0);
624             }
625           else
626             {
627               guint32 flags = 0;
628
629               if (impl->hint == GDK_WINDOW_TYPE_HINT_TOOLTIP)
630                 flags = WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
631
632               wl_shell_surface_set_transient (impl->shell_surface, parent->surface,
633                                               window->x, window->y, flags);
634             }
635         }
636       else
637         {
638           wl_shell_surface_set_toplevel (impl->shell_surface);
639         }
640       impl->mapped = TRUE;
641     }
642 }
643
644 static void
645 shell_surface_handle_configure(void *data,
646                                struct wl_shell_surface *shell_surface,
647                                uint32_t edges,
648                                int32_t width,
649                                int32_t height)
650 {
651   GdkWindow *window = GDK_WINDOW (data);
652   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
653
654   gdk_window_constrain_size (&impl->geometry_hints,
655                              impl->geometry_mask,
656                              width,
657                              height,
658                              &width,
659                              &height);
660
661   gdk_wayland_window_configure (window, width, height, edges);
662 }
663
664 static void
665 shell_surface_popup_done (void                    *data,
666                           struct wl_shell_surface *shell_surface)
667 {
668   GdkWindow *window = GDK_WINDOW (data);
669
670   /* When the popup is complete hide the window - this really relies on the
671    * fix in https://bugzilla.gnome.org/show_bug.cgi?id=670881 to work
672    * effectively.
673    */
674   gdk_window_hide (window);
675 }
676
677 static void
678 shell_surface_ping (void                    *data,
679                     struct wl_shell_surface *shell_surface,
680                     uint32_t                 serial)
681 {
682
683   GdkWindow *window = GDK_WINDOW (data);
684   GdkWaylandDisplay *wayland_display =
685     GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
686
687   _gdk_wayland_display_update_serial (wayland_display, serial);
688
689   wl_shell_surface_pong(shell_surface, serial);
690 }
691
692 static const struct wl_shell_surface_listener shell_surface_listener = {
693   shell_surface_ping,
694   shell_surface_handle_configure,
695   shell_surface_popup_done
696 };
697
698 static void
699 gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
700 {
701   GdkDisplay *display;
702   GdkWaylandDisplay *display_wayland;
703   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
704   GdkEvent *event;
705
706   display = gdk_window_get_display (window);
707   display_wayland = GDK_WAYLAND_DISPLAY (display);
708
709   if (impl->user_time != 0 &&
710       display_wayland->user_time != 0 &&
711       XSERVER_TIME_IS_LATER (display_wayland->user_time, impl->user_time))
712     gdk_wayland_window_set_user_time (window, impl->user_time);
713
714   impl->surface = wl_compositor_create_surface(display_wayland->compositor);
715   wl_surface_set_user_data(impl->surface, window);
716
717   impl->shell_surface = wl_shell_get_shell_surface (display_wayland->shell,
718                                                     impl->surface);
719   wl_shell_surface_add_listener(impl->shell_surface,
720                                 &shell_surface_listener, window);
721
722   gdk_window_set_type_hint (window, impl->hint);  
723
724   _gdk_make_event (window, GDK_MAP, NULL, FALSE);
725   event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY, NULL, FALSE);
726   event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
727
728   if (impl->cairo_surface)
729     gdk_wayland_window_attach_image (window);
730 }
731
732 static void
733 gdk_wayland_window_hide (GdkWindow *window)
734 {
735   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
736
737   if (impl->surface)
738     {
739       if (impl->shell_surface)
740         wl_shell_surface_destroy(impl->shell_surface);
741       if (impl->surface)
742         wl_surface_destroy(impl->surface);
743       impl->shell_surface = NULL;
744       impl->surface = NULL;
745       cairo_surface_destroy(impl->server_surface);
746       impl->server_surface = NULL;
747       impl->mapped = FALSE;
748     }
749
750   _gdk_window_clear_update_area (window);
751 }
752
753 static void
754 gdk_window_wayland_withdraw (GdkWindow *window)
755 {
756   GdkWindowImplWayland *impl;
757
758   if (!window->destroyed)
759     {
760       if (GDK_WINDOW_IS_MAPPED (window))
761         gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_WITHDRAWN);
762
763       g_assert (!GDK_WINDOW_IS_MAPPED (window));
764
765       impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
766       if (impl->surface)
767         {
768           if (impl->shell_surface)
769             wl_shell_surface_destroy(impl->shell_surface);
770           if (impl->surface)
771             wl_surface_destroy(impl->surface);
772           impl->shell_surface = NULL;
773           impl->surface = NULL;
774           cairo_surface_destroy(impl->server_surface);
775           impl->server_surface = NULL;
776           impl->mapped = FALSE;
777         }
778     }
779 }
780
781 static void
782 gdk_window_wayland_set_events (GdkWindow    *window,
783                                GdkEventMask  event_mask)
784 {
785   GDK_WINDOW (window)->event_mask = event_mask;
786 }
787
788 static GdkEventMask
789 gdk_window_wayland_get_events (GdkWindow *window)
790 {
791   if (GDK_WINDOW_DESTROYED (window))
792     return 0;
793   else
794     return GDK_WINDOW (window)->event_mask;
795 }
796
797 static void
798 gdk_window_wayland_raise (GdkWindow *window)
799 {
800   /* FIXME: wl_shell_raise() */
801 }
802
803 static void
804 gdk_window_wayland_lower (GdkWindow *window)
805 {
806   /* FIXME: wl_shell_lower() */
807 }
808
809 static void
810 gdk_window_wayland_restack_under (GdkWindow *window,
811                               GList *native_siblings)
812 {
813 }
814
815 static void
816 gdk_window_wayland_restack_toplevel (GdkWindow *window,
817                                  GdkWindow *sibling,
818                                  gboolean   above)
819 {
820 }
821
822 static void
823 gdk_window_wayland_move_resize (GdkWindow *window,
824                                 gboolean   with_move,
825                                 gint       x,
826                                 gint       y,
827                                 gint       width,
828                                 gint       height)
829 {
830   if (with_move)
831     {
832       window->x = x;
833       window->y = y;
834     }
835
836   /* If this function is called with width and height = -1 then that means
837    * just move the window - don't update its size
838    */
839   if (width > 0 && height > 0)
840     gdk_wayland_window_configure (window, width, height, 0);
841 }
842
843 static void
844 gdk_window_wayland_set_background (GdkWindow      *window,
845                                cairo_pattern_t *pattern)
846 {
847 }
848
849 static gboolean
850 gdk_window_wayland_reparent (GdkWindow *window,
851                              GdkWindow *new_parent,
852                              gint       x,
853                              gint       y)
854 {
855   return FALSE;
856 }
857
858 static void
859 gdk_window_wayland_set_device_cursor (GdkWindow *window,
860                                       GdkDevice *device,
861                                       GdkCursor *cursor)
862 {
863   g_return_if_fail (GDK_IS_WINDOW (window));
864   g_return_if_fail (GDK_IS_DEVICE (device));
865
866   if (!GDK_WINDOW_DESTROYED (window))
867     GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
868 }
869
870 static void
871 gdk_window_wayland_get_geometry (GdkWindow *window,
872                                  gint      *x,
873                                  gint      *y,
874                                  gint      *width,
875                                  gint      *height)
876 {
877   if (!GDK_WINDOW_DESTROYED (window))
878     {
879       if (x)
880         *x = window->x;
881       if (y)
882         *y = window->y;
883       if (width)
884         *width = window->width;
885       if (height)
886         *height = window->height;
887     }
888 }
889
890 void
891 _gdk_wayland_window_offset (GdkWindow *window,
892                             gint      *x_out,
893                             gint      *y_out)
894 {
895   GdkWindowImplWayland *impl, *parent_impl;
896   GdkWindow *parent_window;
897   gint x_offset = 0, y_offset = 0;
898
899   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
900
901   parent_window = impl->transient_for;
902   while (parent_window)
903     {
904       parent_impl = GDK_WINDOW_IMPL_WAYLAND (parent_window->impl);
905
906       x_offset += window->x;
907       y_offset += window->y;
908
909       parent_window = parent_impl->transient_for;
910     }
911
912   *x_out = x_offset;
913   *y_out = y_offset;
914 }
915
916 static gint
917 gdk_window_wayland_get_root_coords (GdkWindow *window,
918                                 gint       x,
919                                 gint       y,
920                                 gint      *root_x,
921                                 gint      *root_y)
922 {
923   gint x_offset, y_offset;
924
925   _gdk_wayland_window_offset (window, &x_offset, &y_offset);
926
927   *root_x = x_offset + x;
928   *root_y = y_offset + y;
929
930   return 1;
931 }
932
933 static gboolean
934 gdk_window_wayland_get_device_state (GdkWindow       *window,
935                                      GdkDevice       *device,
936                                      gint            *x,
937                                      gint            *y,
938                                      GdkModifierType *mask)
939 {
940   gboolean return_val;
941
942   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
943
944   return_val = TRUE;
945
946   if (!GDK_WINDOW_DESTROYED (window))
947     {
948       GdkWindow *child;
949
950       GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
951                                                   NULL, &child,
952                                                   NULL, NULL,
953                                                   x, y, mask);
954       return_val = (child != NULL);
955     }
956
957   return return_val;
958 }
959
960 static void
961 gdk_window_wayland_shape_combine_region (GdkWindow       *window,
962                                          const cairo_region_t *shape_region,
963                                          gint             offset_x,
964                                          gint             offset_y)
965 {
966 }
967
968 static void 
969 gdk_window_wayland_input_shape_combine_region (GdkWindow       *window,
970                                                const cairo_region_t *shape_region,
971                                                gint             offset_x,
972                                                gint             offset_y)
973 {
974 }
975
976 static gboolean
977 gdk_window_wayland_set_static_gravities (GdkWindow *window,
978                                          gboolean   use_static)
979 {
980   return TRUE;
981 }
982
983 static gboolean
984 gdk_wayland_window_queue_antiexpose (GdkWindow *window,
985                                      cairo_region_t *area)
986 {
987   return FALSE;
988 }
989
990 static void
991 gdk_wayland_window_translate (GdkWindow      *window,
992                               cairo_region_t *area,
993                               gint            dx,
994                               gint            dy)
995 {
996   _gdk_window_invalidate_for_expose (window, area);
997 }
998
999 static void
1000 gdk_wayland_window_destroy (GdkWindow *window,
1001                             gboolean   recursing,
1002                             gboolean   foreign_destroy)
1003 {
1004   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1005
1006   g_return_if_fail (GDK_IS_WINDOW (window));
1007
1008   if (impl->cairo_surface)
1009     {
1010       cairo_surface_finish (impl->cairo_surface);
1011       cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key,
1012                                    NULL, NULL);
1013     }
1014
1015   if (!recursing && !foreign_destroy)
1016     {
1017       if (impl->shell_surface)
1018         wl_shell_surface_destroy(impl->shell_surface);
1019       if (impl->surface)
1020         wl_surface_destroy(impl->surface);
1021       impl->shell_surface = NULL;
1022       impl->surface = NULL;
1023     }
1024 }
1025
1026 static void
1027 gdk_window_wayland_destroy_foreign (GdkWindow *window)
1028 {
1029 }
1030
1031 static cairo_surface_t *
1032 gdk_window_wayland_resize_cairo_surface (GdkWindow       *window,
1033                                          cairo_surface_t *surface,
1034                                          gint             width,
1035                                          gint             height)
1036 {
1037   return surface;
1038 }
1039
1040 static cairo_region_t *
1041 gdk_wayland_window_get_shape (GdkWindow *window)
1042 {
1043   return NULL;
1044 }
1045
1046 static cairo_region_t *
1047 gdk_wayland_window_get_input_shape (GdkWindow *window)
1048 {
1049   return NULL;
1050 }
1051
1052 static void
1053 gdk_wayland_window_focus (GdkWindow *window,
1054                           guint32    timestamp)
1055 {
1056   /* FIXME: wl_shell_focus() */
1057 }
1058
1059 static void
1060 gdk_wayland_window_set_type_hint (GdkWindow        *window,
1061                                   GdkWindowTypeHint hint)
1062 {
1063   GdkWindowImplWayland *impl;
1064
1065   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1066
1067   if (GDK_WINDOW_DESTROYED (window))
1068     return;
1069
1070   impl->hint = hint;
1071
1072   switch (hint)
1073     {
1074     case GDK_WINDOW_TYPE_HINT_MENU:
1075     case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1076     case GDK_WINDOW_TYPE_HINT_UTILITY:
1077     case GDK_WINDOW_TYPE_HINT_DOCK:
1078     case GDK_WINDOW_TYPE_HINT_DESKTOP:
1079     case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
1080     case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
1081     case GDK_WINDOW_TYPE_HINT_TOOLTIP:
1082     case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
1083     case GDK_WINDOW_TYPE_HINT_COMBO:
1084     case GDK_WINDOW_TYPE_HINT_DND:
1085       break;
1086     default:
1087       g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
1088       /* Fall thru */
1089     case GDK_WINDOW_TYPE_HINT_DIALOG:
1090     case GDK_WINDOW_TYPE_HINT_NORMAL:
1091     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1092       if (impl->shell_surface)
1093         wl_shell_surface_set_toplevel (impl->shell_surface);
1094       break;
1095     }
1096 }
1097
1098 static GdkWindowTypeHint
1099 gdk_wayland_window_get_type_hint (GdkWindow *window)
1100 {
1101   return GDK_WINDOW_TYPE_HINT_NORMAL;
1102 }
1103
1104 void
1105 gdk_wayland_window_set_modal_hint (GdkWindow *window,
1106                                    gboolean   modal)
1107 {
1108 }
1109
1110 static void
1111 gdk_wayland_window_set_skip_taskbar_hint (GdkWindow *window,
1112                                           gboolean   skips_taskbar)
1113 {
1114 }
1115
1116 static void
1117 gdk_wayland_window_set_skip_pager_hint (GdkWindow *window,
1118                                         gboolean   skips_pager)
1119 {
1120 }
1121
1122 static void
1123 gdk_wayland_window_set_urgency_hint (GdkWindow *window,
1124                                      gboolean   urgent)
1125 {
1126 }
1127
1128 static void
1129 gdk_wayland_window_set_geometry_hints (GdkWindow         *window,
1130                                        const GdkGeometry *geometry,
1131                                        GdkWindowHints     geom_mask)
1132 {
1133   GdkWindowImplWayland *impl;
1134
1135   if (GDK_WINDOW_DESTROYED (window) ||
1136       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1137     return;
1138
1139   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1140
1141   impl->geometry_hints = *geometry;
1142   impl->geometry_mask = geom_mask;
1143
1144   /*
1145    * GDK_HINT_POS
1146    * GDK_HINT_USER_POS
1147    * GDK_HINT_USER_SIZE
1148    * GDK_HINT_MIN_SIZE
1149    * GDK_HINT_MAX_SIZE
1150    * GDK_HINT_BASE_SIZE
1151    * GDK_HINT_RESIZE_INC
1152    * GDK_HINT_ASPECT
1153    * GDK_HINT_WIN_GRAVITY
1154    */
1155 }
1156
1157 static void
1158 gdk_wayland_window_set_title (GdkWindow   *window,
1159                               const gchar *title)
1160 {
1161   g_return_if_fail (title != NULL);
1162
1163   if (GDK_WINDOW_DESTROYED (window))
1164     return;
1165 }
1166
1167 static void
1168 gdk_wayland_window_set_role (GdkWindow   *window,
1169                              const gchar *role)
1170 {
1171 }
1172
1173 static void
1174 gdk_wayland_window_set_startup_id (GdkWindow   *window,
1175                                    const gchar *startup_id)
1176 {
1177 }
1178
1179 static void
1180 gdk_wayland_window_set_transient_for (GdkWindow *window,
1181                                       GdkWindow *parent)
1182 {
1183   GdkWindowImplWayland *impl;
1184
1185   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1186   impl->transient_for = parent;
1187 }
1188
1189 static void
1190 gdk_wayland_window_get_root_origin (GdkWindow *window,
1191                                    gint      *x,
1192                                    gint      *y)
1193 {
1194   if (x)
1195     *x = 0;
1196
1197   if (y)
1198     *y = 0;
1199 }
1200
1201 static void
1202 gdk_wayland_window_get_frame_extents (GdkWindow    *window,
1203                                       GdkRectangle *rect)
1204 {
1205   rect->x = window->x;
1206   rect->y = window->y;
1207   rect->width = window->width;
1208   rect->height = window->height;
1209 }
1210
1211 static void
1212 gdk_wayland_window_set_override_redirect (GdkWindow *window,
1213                                           gboolean override_redirect)
1214 {
1215 }
1216
1217 static void
1218 gdk_wayland_window_set_accept_focus (GdkWindow *window,
1219                                      gboolean accept_focus)
1220 {
1221 }
1222
1223 static void
1224 gdk_wayland_window_set_focus_on_map (GdkWindow *window,
1225                                      gboolean focus_on_map)
1226 {
1227   focus_on_map = focus_on_map != FALSE;
1228
1229   if (window->focus_on_map != focus_on_map)
1230     {
1231       window->focus_on_map = focus_on_map;
1232
1233       if ((!GDK_WINDOW_DESTROYED (window)) &&
1234           (!window->focus_on_map) &&
1235           WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1236         gdk_wayland_window_set_user_time (window, 0);
1237     }
1238 }
1239
1240 static void
1241 gdk_wayland_window_set_icon_list (GdkWindow *window,
1242                                   GList     *pixbufs)
1243 {
1244 }
1245
1246 static void
1247 gdk_wayland_window_set_icon_name (GdkWindow   *window,
1248                                   const gchar *name)
1249 {
1250   if (GDK_WINDOW_DESTROYED (window))
1251     return;
1252 }
1253
1254 static void
1255 gdk_wayland_window_iconify (GdkWindow *window)
1256 {
1257 }
1258
1259 static void
1260 gdk_wayland_window_deiconify (GdkWindow *window)
1261 {
1262   if (GDK_WINDOW_DESTROYED (window) ||
1263       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1264     return;
1265
1266   if (GDK_WINDOW_IS_MAPPED (window))
1267     {  
1268       gdk_window_show (window);
1269     }
1270   else
1271     {
1272       /* Flip our client side flag, the real work happens on map. */
1273       gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
1274     }
1275 }
1276
1277 static void
1278 gdk_wayland_window_stick (GdkWindow *window)
1279 {
1280   if (GDK_WINDOW_DESTROYED (window))
1281     return;
1282 }
1283
1284 static void
1285 gdk_wayland_window_unstick (GdkWindow *window)
1286 {
1287   if (GDK_WINDOW_DESTROYED (window))
1288     return;
1289 }
1290
1291 static void
1292 gdk_wayland_window_maximize (GdkWindow *window)
1293 {
1294   if (GDK_WINDOW_DESTROYED (window))
1295     return;
1296 }
1297
1298 static void
1299 gdk_wayland_window_unmaximize (GdkWindow *window)
1300 {
1301   if (GDK_WINDOW_DESTROYED (window))
1302     return;
1303 }
1304
1305 static void
1306 gdk_wayland_window_fullscreen (GdkWindow *window)
1307 {
1308   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1309
1310   if (GDK_WINDOW_DESTROYED (window))
1311     return;
1312
1313   if (impl->fullscreen)
1314     return;
1315
1316   impl->saved_width = gdk_window_get_width (window);
1317   impl->saved_height = gdk_window_get_height (window);
1318   wl_shell_surface_set_fullscreen (impl->shell_surface,
1319                                    WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
1320                                    0,
1321                                    NULL);
1322   impl->fullscreen = TRUE;
1323 }
1324
1325 static void
1326 gdk_wayland_window_unfullscreen (GdkWindow *window)
1327 {
1328   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1329
1330   if (GDK_WINDOW_DESTROYED (window))
1331     return;
1332
1333   if (!impl->fullscreen)
1334     return;
1335
1336   wl_shell_surface_set_toplevel (impl->shell_surface);
1337   gdk_wayland_window_configure (window, impl->saved_width, impl->saved_height,
1338                                 0);
1339   impl->fullscreen = FALSE;
1340 }
1341
1342 static void
1343 gdk_wayland_window_set_keep_above (GdkWindow *window,
1344                                    gboolean   setting)
1345 {
1346   g_return_if_fail (GDK_IS_WINDOW (window));
1347
1348   if (GDK_WINDOW_DESTROYED (window))
1349     return;
1350 }
1351
1352 static void
1353 gdk_wayland_window_set_keep_below (GdkWindow *window, gboolean setting)
1354 {
1355   g_return_if_fail (GDK_IS_WINDOW (window));
1356
1357   if (GDK_WINDOW_DESTROYED (window))
1358     return;
1359 }
1360
1361 static GdkWindow *
1362 gdk_wayland_window_get_group (GdkWindow *window)
1363 {
1364   if (GDK_WINDOW_DESTROYED (window) ||
1365       !WINDOW_IS_TOPLEVEL (window))
1366     return NULL;
1367
1368   return NULL;
1369 }
1370
1371 static void
1372 gdk_wayland_window_set_group (GdkWindow *window,
1373                               GdkWindow *leader)
1374 {
1375   g_return_if_fail (GDK_IS_WINDOW (window));
1376   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1377   g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
1378 }
1379
1380 static void
1381 gdk_wayland_window_set_decorations (GdkWindow      *window,
1382                                     GdkWMDecoration decorations)
1383 {
1384 }
1385
1386 static gboolean
1387 gdk_wayland_window_get_decorations (GdkWindow       *window,
1388                                     GdkWMDecoration *decorations)
1389 {
1390   return FALSE;
1391 }
1392
1393 static void
1394 gdk_wayland_window_set_functions (GdkWindow    *window,
1395                                   GdkWMFunction functions)
1396 {
1397 }
1398
1399 static void
1400 gdk_wayland_window_begin_resize_drag (GdkWindow     *window,
1401                                       GdkWindowEdge  edge,
1402                                       GdkDevice     *device,
1403                                       gint           button,
1404                                       gint           root_x,
1405                                       gint           root_y,
1406                                       guint32        timestamp)
1407 {
1408   GdkWindowImplWayland *impl;
1409   GdkWaylandDisplay *wayland_display =
1410     GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
1411
1412   uint32_t grab_type;
1413
1414   if (GDK_WINDOW_DESTROYED (window) ||
1415       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1416     return;
1417
1418   switch (edge)
1419     {
1420     case GDK_WINDOW_EDGE_NORTH_WEST:
1421       grab_type = WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
1422       break;
1423
1424     case GDK_WINDOW_EDGE_NORTH:
1425       grab_type = WL_SHELL_SURFACE_RESIZE_TOP;
1426       break;
1427
1428     case GDK_WINDOW_EDGE_NORTH_EAST:
1429       grab_type = WL_SHELL_SURFACE_RESIZE_RIGHT;
1430       break;
1431
1432     case GDK_WINDOW_EDGE_WEST:
1433       grab_type = WL_SHELL_SURFACE_RESIZE_LEFT;
1434       break;
1435
1436     case GDK_WINDOW_EDGE_EAST:
1437       grab_type = WL_SHELL_SURFACE_RESIZE_RIGHT;
1438       break;
1439
1440     case GDK_WINDOW_EDGE_SOUTH_WEST:
1441       grab_type = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
1442       break;
1443
1444     case GDK_WINDOW_EDGE_SOUTH:
1445       grab_type = WL_SHELL_SURFACE_RESIZE_BOTTOM;
1446       break;
1447
1448     case GDK_WINDOW_EDGE_SOUTH_EAST:
1449       grab_type = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
1450       break;
1451
1452     default:
1453       g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
1454                  edge);
1455       return;
1456     }
1457
1458   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1459
1460   wl_shell_surface_resize (impl->shell_surface,
1461                            gdk_wayland_device_get_wl_seat (device),
1462                            _gdk_wayland_display_get_serial (wayland_display),
1463                            grab_type);
1464
1465   /* This is needed since Wayland will absorb all the pointer events after the
1466    * above function - FIXME: Is this always safe..?
1467    */
1468   gdk_device_ungrab (device, timestamp);
1469 }
1470
1471 static void
1472 gdk_wayland_window_begin_move_drag (GdkWindow *window,
1473                                     GdkDevice *device,
1474                                     gint       button,
1475                                     gint       root_x,
1476                                     gint       root_y,
1477                                     guint32    timestamp)
1478 {
1479   GdkWindowImplWayland *impl;
1480   GdkWaylandDisplay *wayland_display =
1481     GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
1482
1483   if (GDK_WINDOW_DESTROYED (window) ||
1484       !WINDOW_IS_TOPLEVEL (window))
1485     return;
1486
1487   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1488
1489   wl_shell_surface_move (impl->shell_surface,
1490                          gdk_wayland_device_get_wl_seat (device),
1491                          _gdk_wayland_display_get_serial (wayland_display));
1492
1493   /* This is needed since Wayland will absorb all the pointer events after the
1494    * above function - FIXME: Is this always safe..?
1495    */
1496   gdk_device_ungrab (device, timestamp);
1497 }
1498
1499 static void
1500 gdk_wayland_window_set_opacity (GdkWindow *window,
1501                                 gdouble    opacity)
1502 {
1503 }
1504
1505 static void
1506 gdk_wayland_window_set_composited (GdkWindow *window,
1507                                    gboolean   composited)
1508 {
1509 }
1510
1511 static void
1512 gdk_wayland_window_destroy_notify (GdkWindow *window)
1513 {
1514   if (!GDK_WINDOW_DESTROYED (window))
1515     {
1516       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
1517         g_warning ("GdkWindow %p unexpectedly destroyed", window);
1518
1519       _gdk_window_destroy (window, TRUE);
1520     }
1521
1522   g_object_unref (window);
1523 }
1524
1525 static void
1526 gdk_wayland_window_process_updates_recurse (GdkWindow      *window,
1527                                             cairo_region_t *region)
1528 {
1529   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1530   cairo_rectangle_int_t rect;
1531   int i, n;
1532
1533   gdk_wayland_window_map (window);
1534
1535   if (impl->cairo_surface)
1536     gdk_wayland_window_attach_image (window);
1537
1538   n = cairo_region_num_rectangles(region);
1539   for (i = 0; i < n; i++)
1540     {
1541       cairo_region_get_rectangle (region, i, &rect);
1542       wl_surface_damage (impl->surface,
1543                          rect.x, rect.y, rect.width, rect.height);
1544       wl_surface_commit(impl->surface);
1545     }
1546
1547   _gdk_window_process_updates_recurse (window, region);
1548 }
1549
1550 static void
1551 gdk_wayland_window_sync_rendering (GdkWindow *window)
1552 {
1553 }
1554
1555 static gboolean
1556 gdk_wayland_window_simulate_key (GdkWindow      *window,
1557                                  gint            x,
1558                                  gint            y,
1559                                  guint           keyval,
1560                                  GdkModifierType modifiers,
1561                                  GdkEventType    key_pressrelease)
1562 {
1563   return FALSE;
1564 }
1565
1566 static gboolean
1567 gdk_wayland_window_simulate_button (GdkWindow      *window,
1568                                     gint            x,
1569                                     gint            y,
1570                                     guint           button, /*1..3*/
1571                                     GdkModifierType modifiers,
1572                                     GdkEventType    button_pressrelease)
1573 {
1574   return FALSE;
1575 }
1576
1577 static gboolean
1578 gdk_wayland_window_get_property (GdkWindow   *window,
1579                                  GdkAtom      property,
1580                                  GdkAtom      type,
1581                                  gulong       offset,
1582                                  gulong       length,
1583                                  gint         pdelete,
1584                                  GdkAtom     *actual_property_type,
1585                                  gint        *actual_format_type,
1586                                  gint        *actual_length,
1587                                  guchar     **data)
1588 {
1589   return FALSE;
1590 }
1591
1592 static void
1593 gdk_wayland_window_change_property (GdkWindow    *window,
1594                                     GdkAtom       property,
1595                                     GdkAtom       type,
1596                                     gint          format,
1597                                     GdkPropMode   mode,
1598                                     const guchar *data,
1599                                     gint          nelements)
1600 {
1601 }
1602
1603 static void
1604 gdk_wayland_window_delete_property (GdkWindow *window,
1605                                     GdkAtom    property)
1606 {
1607 }
1608
1609 static void
1610 _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
1611 {
1612   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1613   GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
1614
1615   object_class->finalize = gdk_window_impl_wayland_finalize;
1616
1617   impl_class->ref_cairo_surface = gdk_wayland_window_ref_cairo_surface;
1618   impl_class->show = gdk_wayland_window_show;
1619   impl_class->hide = gdk_wayland_window_hide;
1620   impl_class->withdraw = gdk_window_wayland_withdraw;
1621   impl_class->set_events = gdk_window_wayland_set_events;
1622   impl_class->get_events = gdk_window_wayland_get_events;
1623   impl_class->raise = gdk_window_wayland_raise;
1624   impl_class->lower = gdk_window_wayland_lower;
1625   impl_class->restack_under = gdk_window_wayland_restack_under;
1626   impl_class->restack_toplevel = gdk_window_wayland_restack_toplevel;
1627   impl_class->move_resize = gdk_window_wayland_move_resize;
1628   impl_class->set_background = gdk_window_wayland_set_background;
1629   impl_class->reparent = gdk_window_wayland_reparent;
1630   impl_class->set_device_cursor = gdk_window_wayland_set_device_cursor;
1631   impl_class->get_geometry = gdk_window_wayland_get_geometry;
1632   impl_class->get_root_coords = gdk_window_wayland_get_root_coords;
1633   impl_class->get_device_state = gdk_window_wayland_get_device_state;
1634   impl_class->shape_combine_region = gdk_window_wayland_shape_combine_region;
1635   impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region;
1636   impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities;
1637   impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose;
1638   impl_class->translate = gdk_wayland_window_translate;
1639   impl_class->destroy = gdk_wayland_window_destroy;
1640   impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign;
1641   impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
1642   impl_class->get_shape = gdk_wayland_window_get_shape;
1643   impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
1644   /* impl_class->beep */
1645
1646   impl_class->focus = gdk_wayland_window_focus;
1647   impl_class->set_type_hint = gdk_wayland_window_set_type_hint;
1648   impl_class->get_type_hint = gdk_wayland_window_get_type_hint;
1649   impl_class->set_modal_hint = gdk_wayland_window_set_modal_hint;
1650   impl_class->set_skip_taskbar_hint = gdk_wayland_window_set_skip_taskbar_hint;
1651   impl_class->set_skip_pager_hint = gdk_wayland_window_set_skip_pager_hint;
1652   impl_class->set_urgency_hint = gdk_wayland_window_set_urgency_hint;
1653   impl_class->set_geometry_hints = gdk_wayland_window_set_geometry_hints;
1654   impl_class->set_title = gdk_wayland_window_set_title;
1655   impl_class->set_role = gdk_wayland_window_set_role;
1656   impl_class->set_startup_id = gdk_wayland_window_set_startup_id;
1657   impl_class->set_transient_for = gdk_wayland_window_set_transient_for;
1658   impl_class->get_root_origin = gdk_wayland_window_get_root_origin;
1659   impl_class->get_frame_extents = gdk_wayland_window_get_frame_extents;
1660   impl_class->set_override_redirect = gdk_wayland_window_set_override_redirect;
1661   impl_class->set_accept_focus = gdk_wayland_window_set_accept_focus;
1662   impl_class->set_focus_on_map = gdk_wayland_window_set_focus_on_map;
1663   impl_class->set_icon_list = gdk_wayland_window_set_icon_list;
1664   impl_class->set_icon_name = gdk_wayland_window_set_icon_name;
1665   impl_class->iconify = gdk_wayland_window_iconify;
1666   impl_class->deiconify = gdk_wayland_window_deiconify;
1667   impl_class->stick = gdk_wayland_window_stick;
1668   impl_class->unstick = gdk_wayland_window_unstick;
1669   impl_class->maximize = gdk_wayland_window_maximize;
1670   impl_class->unmaximize = gdk_wayland_window_unmaximize;
1671   impl_class->fullscreen = gdk_wayland_window_fullscreen;
1672   impl_class->unfullscreen = gdk_wayland_window_unfullscreen;
1673   impl_class->set_keep_above = gdk_wayland_window_set_keep_above;
1674   impl_class->set_keep_below = gdk_wayland_window_set_keep_below;
1675   impl_class->get_group = gdk_wayland_window_get_group;
1676   impl_class->set_group = gdk_wayland_window_set_group;
1677   impl_class->set_decorations = gdk_wayland_window_set_decorations;
1678   impl_class->get_decorations = gdk_wayland_window_get_decorations;
1679   impl_class->set_functions = gdk_wayland_window_set_functions;
1680   impl_class->begin_resize_drag = gdk_wayland_window_begin_resize_drag;
1681   impl_class->begin_move_drag = gdk_wayland_window_begin_move_drag;
1682   impl_class->set_opacity = gdk_wayland_window_set_opacity;
1683   impl_class->set_composited = gdk_wayland_window_set_composited;
1684   impl_class->destroy_notify = gdk_wayland_window_destroy_notify;
1685   impl_class->get_drag_protocol = _gdk_wayland_window_get_drag_protocol;
1686   impl_class->register_dnd = _gdk_wayland_window_register_dnd;
1687   impl_class->drag_begin = _gdk_wayland_window_drag_begin;
1688   impl_class->process_updates_recurse = gdk_wayland_window_process_updates_recurse;
1689   impl_class->sync_rendering = gdk_wayland_window_sync_rendering;
1690   impl_class->simulate_key = gdk_wayland_window_simulate_key;
1691   impl_class->simulate_button = gdk_wayland_window_simulate_button;
1692   impl_class->get_property = gdk_wayland_window_get_property;
1693   impl_class->change_property = gdk_wayland_window_change_property;
1694   impl_class->delete_property = gdk_wayland_window_delete_property;
1695 }
1696
1697
1698 void
1699 _gdk_wayland_window_set_device_grabbed (GdkWindow      *window,
1700                                         GdkDevice      *device,
1701                                         struct wl_seat *seat,
1702                                         guint32         time_)
1703 {
1704   GdkWindowImplWayland *impl;
1705
1706   g_return_if_fail (window != NULL);
1707
1708   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1709
1710   impl->grab_device = device;
1711   impl->grab_input_seat = seat;
1712   impl->grab_time = time_;
1713 }
1714
1715 /**
1716  * gdk_wayland_window_get_wl_surface
1717  * @window: (type GdkWaylandWindow): a #GdkWindow
1718  *
1719  * Returns the Wayland surface of a #GdkWindow
1720  *
1721  * Returns: (transfer none): a Wayland wl_surface
1722  *
1723  * Since: 3.8
1724  */
1725 struct wl_surface *
1726 gdk_wayland_window_get_wl_surface (GdkWindow *window)
1727 {
1728   GdkWindowImplWayland *impl;
1729
1730   g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL);
1731
1732   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1733
1734   return impl->surface;
1735 }
1736
1737 /**
1738  * gdk_wayland_window_get_wl_shell_surface
1739  * @window: (type GdkWaylandWindow): a #GdkWindow
1740  *
1741  * Returns the Wayland shell surface of a #GdkWindow
1742  *
1743  * Returns: (transfer none): a Wayland wl_shell_surface
1744  *
1745  * Since: 3.8
1746  */
1747 struct wl_shell_surface *
1748 gdk_wayland_window_get_wl_shell_surface (GdkWindow *window)
1749 {
1750   GdkWindowImplWayland *impl;
1751
1752   g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL);
1753
1754   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1755
1756   return impl->shell_surface;
1757 }