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