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