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