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