]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkwindow-wayland.c
wayland: Support setting cursors
[~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, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19
20 #include "config.h"
21
22 #include <netinet/in.h>
23 #include <unistd.h>
24
25 #include "gdk.h"
26 #include "gdkwayland.h"
27
28 #include "gdkwindow.h"
29 #include "gdkwindowimpl.h"
30 #include "gdkdisplay-wayland.h"
31 #include "gdkscreen-wayland.h"
32 #include "gdkprivate-wayland.h"
33 #include "gdkinternals.h"
34 #include "gdkwindow-wayland.h"
35 #include "gdkdeviceprivate.h"
36 #include "gdkdevice-wayland.h"
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41
42 #include <wayland-egl.h>
43
44 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
45   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
46    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
47
48 #define WINDOW_IS_TOPLEVEL(window)                   \
49   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
50    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
51    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
52
53 /* Return whether time1 is considered later than time2 as far as xserver
54  * time is concerned.  Accounts for wraparound.
55  */
56 #define XSERVER_TIME_IS_LATER(time1, time2)                        \
57   ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
58     (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
59   )
60
61 typedef struct _GdkWaylandWindow GdkWaylandWindow;
62 typedef struct _GdkWaylandWindowClass GdkWaylandWindowClass;
63
64 struct _GdkWaylandWindow {
65   GdkWindow parent;
66 };
67
68 struct _GdkWaylandWindowClass {
69   GdkWindowClass parent_class;
70 };
71
72 G_DEFINE_TYPE (GdkWaylandWindow, _gdk_wayland_window, GDK_TYPE_WINDOW)
73
74 static void
75 _gdk_wayland_window_class_init (GdkWaylandWindowClass *wayland_window_class)
76 {
77 }
78
79 static void
80 _gdk_wayland_window_init (GdkWaylandWindow *wayland_window)
81 {
82 }
83
84 #define GDK_TYPE_WINDOW_IMPL_WAYLAND              (_gdk_window_impl_wayland_get_type ())
85 #define GDK_WINDOW_IMPL_WAYLAND(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWayland))
86 #define GDK_WINDOW_IMPL_WAYLAND_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass))
87 #define GDK_IS_WINDOW_IMPL_WAYLAND(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_WAYLAND))
88 #define GDK_IS_WINDOW_IMPL_WAYLAND_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_WAYLAND))
89 #define GDK_WINDOW_IMPL_WAYLAND_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_WAYLAND, GdkWindowImplWaylandClass))
90
91 typedef struct _GdkWindowImplWayland GdkWindowImplWayland;
92 typedef struct _GdkWindowImplWaylandClass GdkWindowImplWaylandClass;
93
94 struct _GdkWindowImplWayland
95 {
96   GdkWindowImpl parent_instance;
97
98   GdkWindow *wrapper;
99
100   GdkToplevelWayland *toplevel; /* Toplevel-specific information */
101   GdkCursor *cursor;
102   GHashTable *device_cursor;
103
104   gint8 toplevel_window_type;
105
106   struct wl_surface *surface;
107   unsigned int mapped : 1;
108
109   cairo_surface_t *cairo_surface;
110   cairo_surface_t *server_surface;
111   GLuint texture;
112 };
113
114 struct _GdkWindowImplWaylandClass
115 {
116   GdkWindowImplClass parent_class;
117 };
118
119 G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL)
120
121 static void
122 _gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
123 {
124   impl->toplevel_window_type = -1;
125   impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
126                                                (GDestroyNotify) gdk_cursor_unref);
127 }
128
129 GdkToplevelWayland *
130 _gdk_wayland_window_get_toplevel (GdkWindow *window)
131 {
132   GdkWindowImplWayland *impl;
133
134   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
135
136   if (!WINDOW_IS_TOPLEVEL (window))
137     return NULL;
138
139   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
140
141   if (!impl->toplevel)
142     impl->toplevel = g_new0 (GdkToplevelWayland, 1);
143
144   return impl->toplevel;
145 }
146
147 /**
148  * _gdk_wayland_window_update_size:
149  * @drawable: a #GdkDrawableImplWayland.
150  * 
151  * Updates the state of the drawable (in particular the drawable's
152  * cairo surface) when its size has changed.
153  **/
154 void
155 _gdk_wayland_window_update_size (GdkWindow *window)
156 {
157   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
158   GdkRectangle area;
159   cairo_region_t *region;
160
161   fprintf(stderr, "update size, window %p\n", impl->wrapper);
162
163   if (impl->cairo_surface)
164     {
165       cairo_surface_destroy (impl->cairo_surface);
166       impl->cairo_surface = NULL;
167     }
168
169   area.x = 0;
170   area.y = 0;
171   area.width = window->width;
172   area.height = window->height;
173
174   region = cairo_region_create_rectangle (&area);
175   _gdk_window_invalidate_for_expose (window, region);
176   cairo_region_destroy (region);
177 }
178
179 GdkWindow *
180 _gdk_wayland_screen_create_root_window (GdkScreen *screen,
181                                         int width, int height)
182 {
183   GdkWindow *window;
184   GdkWindowImplWayland *impl;
185
186   window = _gdk_display_create_window (gdk_screen_get_display (screen));
187   window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
188   window->impl_window = window;
189   window->visual = gdk_screen_get_system_visual (screen);
190
191   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
192
193   impl->wrapper = GDK_WINDOW (window);
194
195   window->window_type = GDK_WINDOW_ROOT;
196   window->depth = 32;
197
198   window->x = 0;
199   window->y = 0;
200   window->abs_x = 0;
201   window->abs_y = 0;
202   window->width = width;
203   window->height = height;
204   window->viewable = TRUE;
205
206   /* see init_randr_support() in gdkscreen-wayland.c */
207   window->event_mask = GDK_STRUCTURE_MASK;
208
209   return window;
210 }
211
212 static const gchar *
213 get_default_title (void)
214 {
215   const char *title;
216
217   title = g_get_application_name ();
218   if (!title)
219     title = g_get_prgname ();
220   if (!title)
221     title = "";
222
223   return title;
224 }
225
226 void
227 _gdk_wayland_display_create_window_impl (GdkDisplay    *display,
228                                          GdkWindow     *window,
229                                          GdkWindow     *real_parent,
230                                          GdkScreen     *screen,
231                                          GdkEventMask   event_mask,
232                                          GdkWindowAttr *attributes,
233                                          gint           attributes_mask)
234 {
235   GdkWindowImplWayland *impl;
236   const char *title;
237
238   impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
239   window->impl = GDK_WINDOW_IMPL (impl);
240   impl->wrapper = GDK_WINDOW (window);
241
242   printf("impl_new for window %p: %p\n", window, impl);
243
244   if (window->width > 65535 ||
245       window->height > 65535)
246     {
247       g_warning ("Native Windows wider or taller than 65535 pixels are not supported");
248
249       if (window->width > 65535)
250         window->width = 65535;
251       if (window->height > 65535)
252         window->height = 65535;
253     }
254
255   g_object_ref (window);
256
257   switch (GDK_WINDOW_TYPE (window))
258     {
259     case GDK_WINDOW_TOPLEVEL:
260     case GDK_WINDOW_TEMP:
261       if (attributes_mask & GDK_WA_TITLE)
262         title = attributes->title;
263       else
264         title = get_default_title ();
265
266       gdk_window_set_title (window, title);
267       break;
268
269     case GDK_WINDOW_CHILD:
270     default:
271       break;
272     }
273
274   if (attributes_mask & GDK_WA_TYPE_HINT)
275     gdk_window_set_type_hint (window, attributes->type_hint);
276 }
277
278 static void
279 gdk_toplevel_wayland_free_contents (GdkDisplay *display,
280                                 GdkToplevelWayland *toplevel)
281 {
282   if (toplevel->icon_pixmap)
283     {
284       cairo_surface_destroy (toplevel->icon_pixmap);
285       toplevel->icon_pixmap = NULL;
286     }
287   if (toplevel->icon_mask)
288     {
289       cairo_surface_destroy (toplevel->icon_mask);
290       toplevel->icon_mask = NULL;
291     }
292 }
293
294 static const cairo_user_data_key_t gdk_wayland_cairo_key;
295
296 typedef struct _GdkWaylandCairoSurfaceData {
297   EGLImageKHR image;
298   GLuint texture;
299   struct wl_egl_pixmap *pixmap;
300   struct wl_buffer *buffer;
301   GdkDisplayWayland *display;
302 } GdkWaylandCairoSurfaceData;
303
304 struct wl_buffer *
305 _gdk_wayland_surface_get_buffer (GdkDisplayWayland *display,
306                                  cairo_surface_t *surface)
307 {
308   GdkWaylandCairoSurfaceData *data;
309
310   data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
311
312   if (!data->buffer)
313     data->buffer =
314       wl_egl_pixmap_create_buffer(display->native_display, data->pixmap);
315
316   return data->buffer;
317 }
318
319 static void
320 gdk_wayland_window_attach_image (GdkWindow *window)
321 {
322   GdkDisplayWayland *display_wayland =
323     GDK_DISPLAY_WAYLAND (gdk_window_get_display (window));
324   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
325   struct wl_buffer *buffer;
326
327   if (GDK_WINDOW_DESTROYED (window))
328     return;
329
330   if (impl->server_surface == impl->cairo_surface)
331     return;
332
333   impl->server_surface = impl->cairo_surface;
334   buffer = _gdk_wayland_surface_get_buffer (display_wayland,
335                                             impl->cairo_surface);
336   wl_surface_attach (impl->surface, buffer, 0, 0);
337
338   fprintf(stderr, "attach %p %dx%d\n", window, window->width, window->height);
339 }
340
341 static void
342 gdk_window_impl_wayland_finalize (GObject *object)
343 {
344   GdkWindowImplWayland *impl;
345
346   g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (object));
347
348   impl = GDK_WINDOW_IMPL_WAYLAND (object);
349
350   g_free (impl->toplevel);
351
352   if (impl->cursor)
353     gdk_cursor_unref (impl->cursor);
354
355   g_hash_table_destroy (impl->device_cursor);
356
357   G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
358 }
359
360 static void
361 gdk_wayland_cairo_surface_destroy (void *p)
362 {
363   GdkWaylandCairoSurfaceData *data = p;
364
365   data->display->destroy_image (data->display->egl_display, data->image);
366   cairo_device_acquire(data->display->cairo_device);
367   glDeleteTextures(1, &data->texture);
368   cairo_device_release(data->display->cairo_device);
369   if (data->buffer)
370     wl_buffer_destroy(data->buffer);
371   g_free(data);
372 }
373
374 static cairo_surface_t *
375 gdk_wayland_create_cairo_surface (GdkDisplayWayland *display,
376                                   int width, int height)
377 {
378   GdkWaylandCairoSurfaceData *data;
379   cairo_surface_t *surface;
380   struct wl_visual *visual;
381
382   data = g_new (GdkWaylandCairoSurfaceData, 1);
383   data->display = display;
384   data->buffer = NULL;
385   visual = wl_display_get_premultiplied_argb_visual(display->wl_display);
386   data->pixmap =
387     wl_egl_pixmap_create(display->native_display, width, height, visual, 0);
388   data->image =
389     display->create_image(display->egl_display, NULL, EGL_NATIVE_PIXMAP_KHR,
390                           (EGLClientBuffer) data->pixmap, NULL);
391
392   glGenTextures(1, &data->texture);
393   glBindTexture(GL_TEXTURE_2D, data->texture);
394   display->image_target_texture_2d(GL_TEXTURE_2D, data->image);
395
396   printf("allocate image %dx%d (image %p)\n", width, height, data->image);
397
398   surface = cairo_gl_surface_create_for_texture(display->cairo_device,
399                                                 CAIRO_CONTENT_COLOR_ALPHA,
400                                                 data->texture, width, height);
401
402   cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
403                                data, gdk_wayland_cairo_surface_destroy);
404
405   if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
406     fprintf (stderr, "create gl surface failed\n");
407
408   return surface;
409 }
410
411 static cairo_surface_t *
412 gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
413 {
414   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
415   GdkDisplayWayland *display_wayland =
416     GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper));
417
418   if (GDK_WINDOW_DESTROYED (impl->wrapper))
419     return NULL;
420
421   if (!impl->cairo_surface)
422     {
423       impl->cairo_surface =
424         gdk_wayland_create_cairo_surface (display_wayland,
425                                       impl->wrapper->width,
426                                       impl->wrapper->height);
427     }
428
429   cairo_surface_reference (impl->cairo_surface);
430
431   return impl->cairo_surface;
432 }
433
434 static void
435 gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time)
436 {
437 }
438
439 static void
440 gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
441 {
442   GdkDisplay *display;
443   GdkDisplayWayland *display_wayland;
444   GdkToplevelWayland *toplevel;
445   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
446
447   display = gdk_window_get_display (window);
448   display_wayland = GDK_DISPLAY_WAYLAND (display);
449
450   if (WINDOW_IS_TOPLEVEL (window))
451     {
452       toplevel = _gdk_wayland_window_get_toplevel (window);
453
454       if (toplevel->user_time != 0 &&
455               display_wayland->user_time != 0 &&
456           XSERVER_TIME_IS_LATER (display_wayland->user_time, toplevel->user_time))
457         gdk_wayland_window_set_user_time (window, display_wayland->user_time);
458     }
459
460   impl->surface = wl_compositor_create_surface(display_wayland->compositor);
461   wl_surface_set_user_data(impl->surface, window);
462
463   _gdk_make_event (window, GDK_MAP, NULL, FALSE);
464
465   fprintf(stderr, "window show, faked map event\n");
466 }
467
468 static void
469 gdk_wayland_window_hide (GdkWindow *window)
470 {
471   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
472
473   if (impl->surface)
474     {
475       fprintf (stderr, "hide surface %p\n", impl->surface);
476
477       wl_surface_destroy(impl->surface);
478       impl->surface = NULL;
479     }
480
481   _gdk_window_clear_update_area (window);
482 }
483
484 static void
485 gdk_window_wayland_withdraw (GdkWindow *window)
486 {
487   GdkWindowImplWayland *impl;
488
489   if (!window->destroyed)
490     {
491       if (GDK_WINDOW_IS_MAPPED (window))
492         gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_WITHDRAWN);
493
494       g_assert (!GDK_WINDOW_IS_MAPPED (window));
495
496       impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
497       if (impl->surface)
498         {
499           fprintf (stderr, "hide surface %p\n", impl->surface);
500
501           wl_surface_destroy(impl->surface);
502           impl->surface = NULL;
503           cairo_surface_destroy(GDK_WINDOW_IMPL_WAYLAND(impl)->cairo_surface);
504         }
505     }
506 }
507
508 static void
509 gdk_window_wayland_set_events (GdkWindow    *window,
510                                GdkEventMask  event_mask)
511 {
512   GDK_WINDOW (window)->event_mask = event_mask;
513 }
514
515 static GdkEventMask
516 gdk_window_wayland_get_events (GdkWindow *window)
517 {
518   if (GDK_WINDOW_DESTROYED (window))
519     return 0;
520   else
521     return GDK_WINDOW (window)->event_mask;
522 }
523
524 static void
525 gdk_window_wayland_raise (GdkWindow *window)
526 {
527   /* FIXME: wl_shell_raise() */
528 }
529
530 static void
531 gdk_window_wayland_lower (GdkWindow *window)
532 {
533   /* FIXME: wl_shell_lower() */
534 }
535
536 static void
537 gdk_window_wayland_restack_under (GdkWindow *window,
538                               GList *native_siblings)
539 {
540 }
541
542 static void
543 gdk_window_wayland_restack_toplevel (GdkWindow *window,
544                                  GdkWindow *sibling,
545                                  gboolean   above)
546 {
547 }
548
549 static void
550 gdk_window_wayland_move_resize (GdkWindow *window,
551                                 gboolean   with_move,
552                                 gint       x,
553                                 gint       y,
554                                 gint       width,
555                                 gint       height)
556 {
557   window->x = x;
558   window->y = y;
559   if (width > 0)
560     window->width = width;
561   if (height > 0)
562     window->height = height;
563
564   _gdk_wayland_window_update_size (window);
565 }
566
567 static void
568 gdk_window_wayland_set_background (GdkWindow      *window,
569                                cairo_pattern_t *pattern)
570 {
571 }
572
573 static gboolean
574 gdk_window_wayland_reparent (GdkWindow *window,
575                              GdkWindow *new_parent,
576                              gint       x,
577                              gint       y)
578 {
579   return FALSE;
580 }
581
582 static void
583 gdk_window_wayland_set_device_cursor (GdkWindow *window,
584                                       GdkDevice *device,
585                                       GdkCursor *cursor)
586 {
587   GdkWindowImplWayland *impl;
588
589   g_return_if_fail (GDK_IS_WINDOW (window));
590   g_return_if_fail (GDK_IS_DEVICE (device));
591
592   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
593
594   if (!cursor)
595     g_hash_table_remove (impl->device_cursor, device);
596   else
597     {
598       g_hash_table_replace (impl->device_cursor,
599                             device, gdk_cursor_ref (cursor));
600     }
601
602   if (!GDK_WINDOW_DESTROYED (window))
603     GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
604 }
605
606 static void
607 gdk_window_wayland_get_geometry (GdkWindow *window,
608                                  gint      *x,
609                                  gint      *y,
610                                  gint      *width,
611                                  gint      *height)
612 {
613   if (!GDK_WINDOW_DESTROYED (window))
614     {
615       if (x)
616         *x = window->x;
617       if (y)
618         *y = window->y;
619       if (width)
620         *width = window->width;
621       if (height)
622         *height = window->height;
623     }
624 }
625
626 static gint
627 gdk_window_wayland_get_root_coords (GdkWindow *window,
628                                 gint       x,
629                                 gint       y,
630                                 gint      *root_x,
631                                 gint      *root_y)
632 {
633   /* We can't do this. */
634   if (root_x)
635     *root_x = 0;
636   if (root_y)
637     *root_y = 0;
638
639   return 1;
640 }
641
642 static gboolean
643 gdk_window_wayland_get_device_state (GdkWindow       *window,
644                                      GdkDevice       *device,
645                                      gint            *x,
646                                      gint            *y,
647                                      GdkModifierType *mask)
648 {
649   gboolean return_val;
650
651   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
652
653   return_val = TRUE;
654
655   if (!GDK_WINDOW_DESTROYED (window))
656     {
657       GdkWindow *child;
658
659       GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
660                                                   NULL, &child,
661                                                   NULL, NULL,
662                                                   x, y, mask);
663       return_val = (child != NULL);
664     }
665
666   return return_val;
667 }
668
669 static void
670 gdk_window_wayland_shape_combine_region (GdkWindow       *window,
671                                          const cairo_region_t *shape_region,
672                                          gint             offset_x,
673                                          gint             offset_y)
674 {
675 }
676
677 static void 
678 gdk_window_wayland_input_shape_combine_region (GdkWindow       *window,
679                                                const cairo_region_t *shape_region,
680                                                gint             offset_x,
681                                                gint             offset_y)
682 {
683 }
684
685 static gboolean
686 gdk_window_wayland_set_static_gravities (GdkWindow *window,
687                                          gboolean   use_static)
688 {
689   return TRUE;
690 }
691
692 static gboolean
693 gdk_wayland_window_queue_antiexpose (GdkWindow *window,
694                                      cairo_region_t *area)
695 {
696   return FALSE;
697 }
698
699 static void
700 gdk_wayland_window_translate (GdkWindow      *window,
701                               cairo_region_t *area,
702                               gint            dx,
703                               gint            dy)
704 {
705   cairo_surface_t *surface;
706   cairo_t *cr;
707
708   surface = gdk_wayland_window_ref_cairo_surface (window->impl_window);
709   cr = cairo_create (surface);
710   cairo_surface_destroy (surface);
711
712   gdk_cairo_region (cr, area);
713   cairo_clip (cr);
714   cairo_set_source_surface (cr, cairo_get_target (cr), dx, dy);
715   cairo_push_group (cr);
716   cairo_paint (cr);
717   cairo_pop_group_to_source (cr);
718   cairo_paint (cr);
719   cairo_destroy (cr);
720 }
721
722 static void
723 gdk_wayland_window_destroy (GdkWindow *window,
724                             gboolean   recursing,
725                             gboolean   foreign_destroy)
726 {
727   GdkToplevelWayland *toplevel;
728   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
729
730   g_return_if_fail (GDK_IS_WINDOW (window));
731
732   toplevel = _gdk_wayland_window_get_toplevel (window);
733   if (toplevel)
734     gdk_toplevel_wayland_free_contents (gdk_window_get_display (window),
735                                         toplevel);
736
737   if (impl->cairo_surface)
738     {
739       cairo_surface_finish (impl->cairo_surface);
740       cairo_surface_set_user_data (impl->cairo_surface, &gdk_wayland_cairo_key,
741                                    NULL, NULL);
742     }
743
744   if (impl->texture)
745     glDeleteTextures(1, &impl->texture);
746
747   if (!recursing && !foreign_destroy)
748     {
749       fprintf (stderr, "destroy window, surface %p\n",
750                GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface);
751
752       if (GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface)
753         wl_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface);
754     }
755 }
756
757 static void
758 gdk_window_wayland_destroy_foreign (GdkWindow *window)
759 {
760 }
761
762 static cairo_surface_t *
763 gdk_window_wayland_resize_cairo_surface (GdkWindow       *window,
764                                          cairo_surface_t *surface,
765                                          gint             width,
766                                          gint             height)
767 {
768   return surface;
769 }
770
771 static cairo_region_t *
772 gdk_wayland_window_get_shape (GdkWindow *window)
773 {
774   return NULL;
775 }
776
777 static cairo_region_t *
778 gdk_wayland_window_get_input_shape (GdkWindow *window)
779 {
780   return NULL;
781 }
782
783 static void
784 gdk_wayland_window_focus (GdkWindow *window,
785                           guint32    timestamp)
786 {
787   /* FIXME: wl_shell_focus() */
788 }
789
790 static void
791 gdk_wayland_window_set_type_hint (GdkWindow        *window,
792                                   GdkWindowTypeHint hint)
793 {
794   if (GDK_WINDOW_DESTROYED (window))
795     return;
796
797   switch (hint)
798     {
799     case GDK_WINDOW_TYPE_HINT_DIALOG:
800     case GDK_WINDOW_TYPE_HINT_MENU:
801     case GDK_WINDOW_TYPE_HINT_TOOLBAR:
802     case GDK_WINDOW_TYPE_HINT_UTILITY:
803     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
804     case GDK_WINDOW_TYPE_HINT_DOCK:
805     case GDK_WINDOW_TYPE_HINT_DESKTOP:
806     case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
807     case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
808     case GDK_WINDOW_TYPE_HINT_TOOLTIP:
809     case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
810     case GDK_WINDOW_TYPE_HINT_COMBO:
811     case GDK_WINDOW_TYPE_HINT_DND:
812       break;
813     default:
814       g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
815       /* Fall thru */
816     case GDK_WINDOW_TYPE_HINT_NORMAL:
817       break;
818     }
819 }
820
821 static GdkWindowTypeHint
822 gdk_wayland_window_get_type_hint (GdkWindow *window)
823 {
824   return GDK_WINDOW_TYPE_HINT_NORMAL;
825 }
826
827 void
828 gdk_wayland_window_set_modal_hint (GdkWindow *window,
829                                    gboolean   modal)
830 {
831 }
832
833 static void
834 gdk_wayland_window_set_skip_taskbar_hint (GdkWindow *window,
835                                           gboolean   skips_taskbar)
836 {
837 }
838
839 static void
840 gdk_wayland_window_set_skip_pager_hint (GdkWindow *window,
841                                         gboolean   skips_pager)
842 {
843 }
844
845 static void
846 gdk_wayland_window_set_urgency_hint (GdkWindow *window,
847                                      gboolean   urgent)
848 {
849 }
850
851 static void
852 gdk_wayland_window_set_geometry_hints (GdkWindow         *window,
853                                        const GdkGeometry *geometry,
854                                        GdkWindowHints     geom_mask)
855 {
856   if (GDK_WINDOW_DESTROYED (window) ||
857       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
858     return;
859
860   /*
861    * GDK_HINT_POS
862    * GDK_HINT_USER_POS
863    * GDK_HINT_USER_SIZE
864    * GDK_HINT_MIN_SIZE
865    * GDK_HINT_MAX_SIZE
866    * GDK_HINT_BASE_SIZE
867    * GDK_HINT_RESIZE_INC
868    * GDK_HINT_ASPECT
869    * GDK_HINT_WIN_GRAVITY
870    */
871 }
872
873 static void
874 gdk_wayland_window_set_title (GdkWindow   *window,
875                               const gchar *title)
876 {
877   g_return_if_fail (title != NULL);
878
879   if (GDK_WINDOW_DESTROYED (window))
880     return;
881 }
882
883 static void
884 gdk_wayland_window_set_role (GdkWindow   *window,
885                              const gchar *role)
886 {
887 }
888
889 static void
890 gdk_wayland_window_set_startup_id (GdkWindow   *window,
891                                    const gchar *startup_id)
892 {
893 }
894
895 static void
896 gdk_wayland_window_set_transient_for (GdkWindow *window,
897                                       GdkWindow *parent)
898 {
899 }
900
901 static void
902 gdk_wayland_window_get_root_origin (GdkWindow *window,
903                                    gint      *x,
904                                    gint      *y)
905 {
906   if (x)
907     *x = 0;
908
909   if (y)
910     *y = 0;
911 }
912
913 static void
914 gdk_wayland_window_get_frame_extents (GdkWindow    *window,
915                                       GdkRectangle *rect)
916 {
917   rect->x = window->x;
918   rect->y = window->y;
919   rect->width = window->width;
920   rect->height = window->height;
921 }
922
923 static void
924 gdk_wayland_window_set_override_redirect (GdkWindow *window,
925                                           gboolean override_redirect)
926 {
927 }
928
929 static void
930 gdk_wayland_window_set_accept_focus (GdkWindow *window,
931                                      gboolean accept_focus)
932 {
933 }
934
935 static void
936 gdk_wayland_window_set_focus_on_map (GdkWindow *window,
937                                      gboolean focus_on_map)
938 {
939   focus_on_map = focus_on_map != FALSE;
940
941   if (window->focus_on_map != focus_on_map)
942     {
943       window->focus_on_map = focus_on_map;
944
945       if ((!GDK_WINDOW_DESTROYED (window)) &&
946           (!window->focus_on_map) &&
947           WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
948         gdk_wayland_window_set_user_time (window, 0);
949     }
950 }
951
952 static void
953 gdk_wayland_window_set_icon_list (GdkWindow *window,
954                                   GList     *pixbufs)
955 {
956 }
957
958 static void
959 gdk_wayland_window_set_icon_name (GdkWindow   *window,
960                                   const gchar *name)
961 {
962   if (GDK_WINDOW_DESTROYED (window))
963     return;
964 }
965
966 static void
967 gdk_wayland_window_iconify (GdkWindow *window)
968 {
969 }
970
971 static void
972 gdk_wayland_window_deiconify (GdkWindow *window)
973 {
974   if (GDK_WINDOW_DESTROYED (window) ||
975       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
976     return;
977
978   if (GDK_WINDOW_IS_MAPPED (window))
979     {  
980       gdk_window_show (window);
981     }
982   else
983     {
984       /* Flip our client side flag, the real work happens on map. */
985       gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
986     }
987 }
988
989 static void
990 gdk_wayland_window_stick (GdkWindow *window)
991 {
992   if (GDK_WINDOW_DESTROYED (window))
993     return;
994 }
995
996 static void
997 gdk_wayland_window_unstick (GdkWindow *window)
998 {
999   if (GDK_WINDOW_DESTROYED (window))
1000     return;
1001 }
1002
1003 static void
1004 gdk_wayland_window_maximize (GdkWindow *window)
1005 {
1006   if (GDK_WINDOW_DESTROYED (window))
1007     return;
1008 }
1009
1010 static void
1011 gdk_wayland_window_unmaximize (GdkWindow *window)
1012 {
1013   if (GDK_WINDOW_DESTROYED (window))
1014     return;
1015 }
1016
1017 static void
1018 gdk_wayland_window_fullscreen (GdkWindow *window)
1019 {
1020   if (GDK_WINDOW_DESTROYED (window))
1021     return;
1022 }
1023
1024 static void
1025 gdk_wayland_window_unfullscreen (GdkWindow *window)
1026 {
1027   if (GDK_WINDOW_DESTROYED (window))
1028     return;
1029 }
1030
1031 static void
1032 gdk_wayland_window_set_keep_above (GdkWindow *window,
1033                                    gboolean   setting)
1034 {
1035   g_return_if_fail (GDK_IS_WINDOW (window));
1036
1037   if (GDK_WINDOW_DESTROYED (window))
1038     return;
1039 }
1040
1041 static void
1042 gdk_wayland_window_set_keep_below (GdkWindow *window, gboolean setting)
1043 {
1044   g_return_if_fail (GDK_IS_WINDOW (window));
1045
1046   if (GDK_WINDOW_DESTROYED (window))
1047     return;
1048 }
1049
1050 static GdkWindow *
1051 gdk_wayland_window_get_group (GdkWindow *window)
1052 {
1053   if (GDK_WINDOW_DESTROYED (window) ||
1054       !WINDOW_IS_TOPLEVEL (window))
1055     return NULL;
1056
1057   return NULL;
1058 }
1059
1060 static void
1061 gdk_wayland_window_set_group (GdkWindow *window,
1062                               GdkWindow *leader)
1063 {
1064   g_return_if_fail (GDK_IS_WINDOW (window));
1065   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1066   g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
1067 }
1068
1069 static void
1070 gdk_wayland_window_set_decorations (GdkWindow      *window,
1071                                     GdkWMDecoration decorations)
1072 {
1073 }
1074
1075 static gboolean
1076 gdk_wayland_window_get_decorations (GdkWindow       *window,
1077                                     GdkWMDecoration *decorations)
1078 {
1079   return FALSE;
1080 }
1081
1082 static void
1083 gdk_wayland_window_set_functions (GdkWindow    *window,
1084                                   GdkWMFunction functions)
1085 {
1086 }
1087
1088 static void
1089 gdk_wayland_window_begin_resize_drag (GdkWindow     *window,
1090                                       GdkWindowEdge  edge,
1091                                       gint           button,
1092                                       gint           root_x,
1093                                       gint           root_y,
1094                                       guint32        timestamp)
1095 {
1096   GdkDisplay *display = gdk_window_get_display (window);
1097   GdkDeviceManager *dm;
1098   GdkWindowImplWayland *impl;
1099   GdkDevice *device;
1100   uint32_t grab_type;
1101
1102   if (GDK_WINDOW_DESTROYED (window) ||
1103       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1104     return;
1105
1106   switch (edge)
1107     {
1108     case GDK_WINDOW_EDGE_NORTH_WEST:
1109       grab_type = WL_SHELL_RESIZE_TOP_LEFT;
1110       break;
1111
1112     case GDK_WINDOW_EDGE_NORTH:
1113       grab_type = WL_SHELL_RESIZE_TOP;
1114       break;
1115
1116     case GDK_WINDOW_EDGE_NORTH_EAST:
1117       grab_type = WL_SHELL_RESIZE_RIGHT;
1118       break;
1119
1120     case GDK_WINDOW_EDGE_WEST:
1121       grab_type = WL_SHELL_RESIZE_LEFT;
1122       break;
1123
1124     case GDK_WINDOW_EDGE_EAST:
1125       grab_type = WL_SHELL_RESIZE_RIGHT;
1126       break;
1127
1128     case GDK_WINDOW_EDGE_SOUTH_WEST:
1129       grab_type = WL_SHELL_RESIZE_BOTTOM_LEFT;
1130       break;
1131
1132     case GDK_WINDOW_EDGE_SOUTH:
1133       grab_type = WL_SHELL_RESIZE_BOTTOM;
1134       break;
1135
1136     case GDK_WINDOW_EDGE_SOUTH_EAST:
1137       grab_type = WL_SHELL_RESIZE_BOTTOM_RIGHT;
1138       break;
1139
1140     default:
1141       g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
1142                  edge);
1143       return;
1144     }
1145
1146   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1147   dm = gdk_display_get_device_manager (display);
1148   device = gdk_device_manager_get_client_pointer (dm);
1149
1150   wl_shell_resize(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface,
1151                   GDK_DEVICE_CORE (device)->device->device,
1152                   timestamp, grab_type);
1153 }
1154
1155 static void
1156 gdk_wayland_window_begin_move_drag (GdkWindow *window,
1157                                     gint       button,
1158                                     gint       root_x,
1159                                     gint       root_y,
1160                                     guint32    timestamp)
1161 {
1162   GdkDisplay *display = gdk_window_get_display (window);
1163   GdkDeviceManager *dm;
1164   GdkWindowImplWayland *impl;
1165   GdkDevice *device;
1166
1167   if (GDK_WINDOW_DESTROYED (window) ||
1168       !WINDOW_IS_TOPLEVEL (window))
1169     return;
1170
1171   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1172
1173   dm = gdk_display_get_device_manager (display);
1174   device = gdk_device_manager_get_client_pointer (dm);
1175
1176   wl_shell_move(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface,
1177                 GDK_DEVICE_CORE (device)->device->device, timestamp);
1178 }
1179
1180 static void
1181 gdk_wayland_window_enable_synchronized_configure (GdkWindow *window)
1182 {
1183 }
1184
1185 static void
1186 gdk_wayland_window_configure_finished (GdkWindow *window)
1187 {
1188   if (!WINDOW_IS_TOPLEVEL (window))
1189     return;
1190
1191   if (!GDK_IS_WINDOW_IMPL_WAYLAND (window->impl))
1192     return;
1193
1194   fprintf(stderr, "configure %p finished\n", window);
1195 }
1196
1197 static void
1198 gdk_wayland_window_set_opacity (GdkWindow *window,
1199                                 gdouble    opacity)
1200 {
1201 }
1202
1203 static void
1204 gdk_wayland_window_set_composited (GdkWindow *window,
1205                                    gboolean   composited)
1206 {
1207 }
1208
1209 static void
1210 gdk_wayland_window_destroy_notify (GdkWindow *window)
1211 {
1212   if (!GDK_WINDOW_DESTROYED (window))
1213     {
1214       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
1215         g_warning ("GdkWindow %p unexpectedly destroyed", window);
1216
1217       _gdk_window_destroy (window, TRUE);
1218     }
1219
1220   g_object_unref (window);
1221 }
1222
1223 static void
1224 gdk_wayland_window_process_updates_recurse (GdkWindow *window,
1225                                             cairo_region_t *region)
1226 {
1227   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
1228   cairo_rectangle_int_t rect;
1229   int i, n;
1230
1231   gdk_wayland_window_attach_image (window);
1232   if (!impl->mapped)
1233     {
1234       wl_surface_map_toplevel (impl->surface);
1235       impl->mapped = TRUE;
1236     }
1237
1238   n = cairo_region_num_rectangles(region);
1239   for (i = 0; i < n; i++)
1240     {
1241       cairo_region_get_rectangle (region, i, &rect);
1242       wl_surface_damage (impl->surface,
1243                          rect.x, rect.y, rect.width, rect.height);
1244     }
1245
1246   _gdk_window_process_updates_recurse (window, region);
1247 }
1248
1249 static void
1250 gdk_wayland_window_sync_rendering (GdkWindow *window)
1251 {
1252 }
1253
1254 static gboolean
1255 gdk_wayland_window_simulate_key (GdkWindow      *window,
1256                                  gint            x,
1257                                  gint            y,
1258                                  guint           keyval,
1259                                  GdkModifierType modifiers,
1260                                  GdkEventType    key_pressrelease)
1261 {
1262   return FALSE;
1263 }
1264
1265 static gboolean
1266 gdk_wayland_window_simulate_button (GdkWindow      *window,
1267                                     gint            x,
1268                                     gint            y,
1269                                     guint           button, /*1..3*/
1270                                     GdkModifierType modifiers,
1271                                     GdkEventType    button_pressrelease)
1272 {
1273   return FALSE;
1274 }
1275
1276 static gboolean
1277 gdk_wayland_window_get_property (GdkWindow   *window,
1278                                  GdkAtom      property,
1279                                  GdkAtom      type,
1280                                  gulong       offset,
1281                                  gulong       length,
1282                                  gint         pdelete,
1283                                  GdkAtom     *actual_property_type,
1284                                  gint        *actual_format_type,
1285                                  gint        *actual_length,
1286                                  guchar     **data)
1287 {
1288   return FALSE;
1289 }
1290
1291 static void
1292 gdk_wayland_window_change_property (GdkWindow    *window,
1293                                     GdkAtom       property,
1294                                     GdkAtom       type,
1295                                     gint          format,
1296                                     GdkPropMode   mode,
1297                                     const guchar *data,
1298                                     gint          nelements)
1299 {
1300 }
1301
1302 static void
1303 gdk_wayland_window_delete_property (GdkWindow *window,
1304                                     GdkAtom    property)
1305 {
1306 }
1307
1308 static void
1309 _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
1310 {
1311   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1312   GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
1313
1314   object_class->finalize = gdk_window_impl_wayland_finalize;
1315
1316   impl_class->ref_cairo_surface = gdk_wayland_window_ref_cairo_surface;
1317   impl_class->show = gdk_wayland_window_show;
1318   impl_class->hide = gdk_wayland_window_hide;
1319   impl_class->withdraw = gdk_window_wayland_withdraw;
1320   impl_class->set_events = gdk_window_wayland_set_events;
1321   impl_class->get_events = gdk_window_wayland_get_events;
1322   impl_class->raise = gdk_window_wayland_raise;
1323   impl_class->lower = gdk_window_wayland_lower;
1324   impl_class->restack_under = gdk_window_wayland_restack_under;
1325   impl_class->restack_toplevel = gdk_window_wayland_restack_toplevel;
1326   impl_class->move_resize = gdk_window_wayland_move_resize;
1327   impl_class->set_background = gdk_window_wayland_set_background;
1328   impl_class->reparent = gdk_window_wayland_reparent;
1329   impl_class->set_device_cursor = gdk_window_wayland_set_device_cursor;
1330   impl_class->get_geometry = gdk_window_wayland_get_geometry;
1331   impl_class->get_root_coords = gdk_window_wayland_get_root_coords;
1332   impl_class->get_device_state = gdk_window_wayland_get_device_state;
1333   impl_class->shape_combine_region = gdk_window_wayland_shape_combine_region;
1334   impl_class->input_shape_combine_region = gdk_window_wayland_input_shape_combine_region;
1335   impl_class->set_static_gravities = gdk_window_wayland_set_static_gravities;
1336   impl_class->queue_antiexpose = gdk_wayland_window_queue_antiexpose;
1337   impl_class->translate = gdk_wayland_window_translate;
1338   impl_class->destroy = gdk_wayland_window_destroy;
1339   impl_class->destroy_foreign = gdk_window_wayland_destroy_foreign;
1340   impl_class->resize_cairo_surface = gdk_window_wayland_resize_cairo_surface;
1341   impl_class->get_shape = gdk_wayland_window_get_shape;
1342   impl_class->get_input_shape = gdk_wayland_window_get_input_shape;
1343   /* impl_class->beep */
1344
1345   impl_class->focus = gdk_wayland_window_focus;
1346   impl_class->set_type_hint = gdk_wayland_window_set_type_hint;
1347   impl_class->get_type_hint = gdk_wayland_window_get_type_hint;
1348   impl_class->set_modal_hint = gdk_wayland_window_set_modal_hint;
1349   impl_class->set_skip_taskbar_hint = gdk_wayland_window_set_skip_taskbar_hint;
1350   impl_class->set_skip_pager_hint = gdk_wayland_window_set_skip_pager_hint;
1351   impl_class->set_urgency_hint = gdk_wayland_window_set_urgency_hint;
1352   impl_class->set_geometry_hints = gdk_wayland_window_set_geometry_hints;
1353   impl_class->set_title = gdk_wayland_window_set_title;
1354   impl_class->set_role = gdk_wayland_window_set_role;
1355   impl_class->set_startup_id = gdk_wayland_window_set_startup_id;
1356   impl_class->set_transient_for = gdk_wayland_window_set_transient_for;
1357   impl_class->get_root_origin = gdk_wayland_window_get_root_origin;
1358   impl_class->get_frame_extents = gdk_wayland_window_get_frame_extents;
1359   impl_class->set_override_redirect = gdk_wayland_window_set_override_redirect;
1360   impl_class->set_accept_focus = gdk_wayland_window_set_accept_focus;
1361   impl_class->set_focus_on_map = gdk_wayland_window_set_focus_on_map;
1362   impl_class->set_icon_list = gdk_wayland_window_set_icon_list;
1363   impl_class->set_icon_name = gdk_wayland_window_set_icon_name;
1364   impl_class->iconify = gdk_wayland_window_iconify;
1365   impl_class->deiconify = gdk_wayland_window_deiconify;
1366   impl_class->stick = gdk_wayland_window_stick;
1367   impl_class->unstick = gdk_wayland_window_unstick;
1368   impl_class->maximize = gdk_wayland_window_maximize;
1369   impl_class->unmaximize = gdk_wayland_window_unmaximize;
1370   impl_class->fullscreen = gdk_wayland_window_fullscreen;
1371   impl_class->unfullscreen = gdk_wayland_window_unfullscreen;
1372   impl_class->set_keep_above = gdk_wayland_window_set_keep_above;
1373   impl_class->set_keep_below = gdk_wayland_window_set_keep_below;
1374   impl_class->get_group = gdk_wayland_window_get_group;
1375   impl_class->set_group = gdk_wayland_window_set_group;
1376   impl_class->set_decorations = gdk_wayland_window_set_decorations;
1377   impl_class->get_decorations = gdk_wayland_window_get_decorations;
1378   impl_class->set_functions = gdk_wayland_window_set_functions;
1379   impl_class->begin_resize_drag = gdk_wayland_window_begin_resize_drag;
1380   impl_class->begin_move_drag = gdk_wayland_window_begin_move_drag;
1381   impl_class->enable_synchronized_configure = gdk_wayland_window_enable_synchronized_configure;
1382   impl_class->configure_finished = gdk_wayland_window_configure_finished;
1383   impl_class->set_opacity = gdk_wayland_window_set_opacity;
1384   impl_class->set_composited = gdk_wayland_window_set_composited;
1385   impl_class->destroy_notify = gdk_wayland_window_destroy_notify;
1386   impl_class->get_drag_protocol = _gdk_wayland_window_get_drag_protocol;
1387   impl_class->register_dnd = _gdk_wayland_window_register_dnd;
1388   impl_class->drag_begin = _gdk_wayland_window_drag_begin;
1389   impl_class->process_updates_recurse = gdk_wayland_window_process_updates_recurse;
1390   impl_class->sync_rendering = gdk_wayland_window_sync_rendering;
1391   impl_class->simulate_key = gdk_wayland_window_simulate_key;
1392   impl_class->simulate_button = gdk_wayland_window_simulate_button;
1393   impl_class->get_property = gdk_wayland_window_get_property;
1394   impl_class->change_property = gdk_wayland_window_change_property;
1395   impl_class->delete_property = gdk_wayland_window_delete_property;
1396 }