]> Pileus Git - ~andy/gtk/blob - gdk/broadway/gdkwindow-broadway.c
c4931976b8dec7c1320c66117e69c409d2e6c445
[~andy/gtk] / gdk / broadway / gdkwindow-broadway.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3  * Josh MacDonald, Ryan Lortie
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /*
20  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
21  * file for a list of people on the GTK+ Team.  See the ChangeLog
22  * files for a list of changes.  These files are distributed with
23  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
24  */
25
26 #include "config.h"
27
28 #include "gdkwindow-broadway.h"
29 #include "gdkscreen-broadway.h"
30
31 #include "gdkwindow.h"
32 #include "gdkwindowimpl.h"
33 #include "gdkdisplay-broadway.h"
34 #include "gdkprivate-broadway.h"
35 #include "gdkinternals.h"
36 #include "gdkdeviceprivate.h"
37 #include "gdkeventsource.h"
38
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <netinet/in.h>
43 #include <unistd.h>
44
45 /* Forward declarations */
46 static void     gdk_window_broadway_set_background     (GdkWindow      *window,
47                                                    cairo_pattern_t *pattern);
48
49 static void        gdk_window_impl_broadway_finalize   (GObject            *object);
50
51 static const cairo_user_data_key_t gdk_broadway_cairo_key;
52
53 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
54   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
55    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
56
57 #define WINDOW_IS_TOPLEVEL(window)                   \
58   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
59    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
60    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
61
62 struct _GdkBroadwayWindow {
63   GdkWindow parent;
64 };
65
66 struct _GdkBroadwayWindowClass {
67   GdkWindowClass parent_class;
68 };
69
70 G_DEFINE_TYPE (GdkBroadwayWindow, gdk_broadway_window, GDK_TYPE_WINDOW)
71
72 static void
73 gdk_broadway_window_class_init (GdkBroadwayWindowClass *broadway_window_class)
74 {
75 }
76
77 static void
78 gdk_broadway_window_init (GdkBroadwayWindow *broadway_window)
79 {
80 }
81
82 G_DEFINE_TYPE (GdkWindowImplBroadway,
83                gdk_window_impl_broadway,
84                GDK_TYPE_WINDOW_IMPL)
85
86 static guint dirty_flush_id = 0;
87
88 static gboolean
89 dirty_flush_idle (gpointer data)
90 {
91   GList *l;
92   GdkBroadwayDisplay *display;
93
94   dirty_flush_id = 0;
95
96   display = GDK_BROADWAY_DISPLAY (gdk_display_get_default ());
97
98   for (l = display->toplevels; l != NULL; l = l->next)
99     {
100       GdkWindowImplBroadway *impl = l->data;
101
102       if (impl->dirty)
103         {
104           impl->dirty = FALSE;
105           _gdk_broadway_server_window_update (display->server,
106                                               impl->id,
107                                               impl->surface);
108         }
109     }
110
111   /* We sync here to ensure all references to the impl->surface memory
112      is done, as we may later paint new data in them. */
113   gdk_display_sync (GDK_DISPLAY (display));
114
115   return FALSE;
116 }
117
118 static void
119 queue_dirty_flush (GdkBroadwayDisplay *display)
120 {
121   if (dirty_flush_id == 0)
122     dirty_flush_id = gdk_threads_add_idle (dirty_flush_idle, NULL);
123 }
124
125 static void
126 gdk_window_impl_broadway_init (GdkWindowImplBroadway *impl)
127 {
128   impl->toplevel_window_type = -1;
129   impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
130                                                (GDestroyNotify) g_object_unref);
131 }
132
133 static void
134 gdk_window_impl_broadway_finalize (GObject *object)
135 {
136   GdkWindow *wrapper;
137   GdkWindowImplBroadway *impl;
138   GdkBroadwayDisplay *broadway_display;
139
140   g_return_if_fail (GDK_IS_WINDOW_IMPL_BROADWAY (object));
141
142   impl = GDK_WINDOW_IMPL_BROADWAY (object);
143
144   wrapper = impl->wrapper;
145
146   _gdk_broadway_window_grab_check_destroy (wrapper);
147
148   broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (impl->wrapper));
149
150   g_hash_table_remove (broadway_display->id_ht, GINT_TO_POINTER(impl->id));
151
152   if (impl->cursor)
153     g_object_unref (impl->cursor);
154
155   g_hash_table_destroy (impl->device_cursor);
156
157   broadway_display->toplevels = g_list_remove (broadway_display->toplevels, impl);
158
159   G_OBJECT_CLASS (gdk_window_impl_broadway_parent_class)->finalize (object);
160 }
161
162 void
163 _gdk_broadway_screen_init_root_window (GdkScreen * screen)
164 {
165   GdkWindow *window;
166   GdkWindowImplBroadway *impl;
167   GdkBroadwayScreen *broadway_screen;
168
169   broadway_screen = GDK_BROADWAY_SCREEN (screen);
170
171   g_assert (broadway_screen->root_window == NULL);
172
173   broadway_screen->root_window = g_object_new (GDK_TYPE_BROADWAY_WINDOW, NULL);
174
175   window = broadway_screen->root_window;
176   window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_BROADWAY, NULL);
177   window->impl_window = window;
178   window->visual = gdk_screen_get_system_visual (screen);
179
180   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
181
182   impl->screen = screen;
183   impl->wrapper = window;
184   impl->id = 0;
185
186   window->window_type = GDK_WINDOW_ROOT;
187   window->depth = 24;
188
189   window->x = 0;
190   window->y = 0;
191   window->abs_x = 0;
192   window->abs_y = 0;
193   window->width = gdk_screen_get_width (screen);
194   window->height = gdk_screen_get_height (screen);
195   window->viewable = TRUE;
196
197   _gdk_window_update_size (broadway_screen->root_window);
198 }
199
200 void
201 _gdk_broadway_display_create_window_impl (GdkDisplay    *display,
202                                           GdkWindow     *window,
203                                           GdkWindow     *real_parent,
204                                           GdkScreen     *screen,
205                                           GdkEventMask   event_mask,
206                                           GdkWindowAttr *attributes,
207                                           gint           attributes_mask)
208 {
209   GdkWindowImplBroadway *impl;
210   GdkBroadwayDisplay *broadway_display;
211
212   broadway_display = GDK_BROADWAY_DISPLAY (display);
213
214   impl = g_object_new (GDK_TYPE_WINDOW_IMPL_BROADWAY, NULL);
215   window->impl = (GdkWindowImpl *)impl;
216   impl->id = _gdk_broadway_server_new_window (broadway_display->server,
217                                               window->x,
218                                               window->y,
219                                               window->width,
220                                               window->height,
221                                               window->window_type == GDK_WINDOW_TEMP);
222   g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER(impl->id), window);
223   impl->wrapper = window;
224
225   impl->screen = screen;
226
227   g_assert (window->window_type == GDK_WINDOW_TOPLEVEL ||
228             window->window_type == GDK_WINDOW_TEMP);
229   g_assert (GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_ROOT);
230
231   broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl);
232 }
233
234 void
235 _gdk_broadway_window_resize_surface (GdkWindow *window)
236 {
237   GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
238   cairo_surface_t *old;
239
240   if (impl->surface)
241     {
242       old = impl->surface;
243
244       impl->surface = _gdk_broadway_server_create_surface (gdk_window_get_width (impl->wrapper),
245                                                            gdk_window_get_height (impl->wrapper));
246
247       cairo_surface_destroy (old);
248     }
249
250   if (impl->ref_surface)
251     {
252       cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
253                                    NULL, NULL);
254       impl->ref_surface = NULL;
255     }
256
257   gdk_window_invalidate_rect (window, NULL, TRUE);
258 }
259
260 static void
261 ref_surface_destroyed (void *data)
262 {
263   GdkWindowImplBroadway *impl = data;
264
265   impl->ref_surface = NULL;
266 }
267
268 static cairo_surface_t *
269 gdk_window_broadway_ref_cairo_surface (GdkWindow *window)
270 {
271   GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
272   int w, h;
273
274   if (GDK_IS_WINDOW_IMPL_BROADWAY (window) &&
275       GDK_WINDOW_DESTROYED (impl->wrapper))
276     return NULL;
277
278   w = gdk_window_get_width (impl->wrapper);
279   h = gdk_window_get_height (impl->wrapper);
280
281   /* Create actual backing store if missing */
282   if (!impl->surface)
283     impl->surface = _gdk_broadway_server_create_surface (w, h);
284
285   /* Create a destroyable surface referencing the real one */
286   if (!impl->ref_surface)
287     {
288       impl->ref_surface =
289         cairo_surface_create_for_rectangle (impl->surface,
290                                             0, 0,
291                                             w, h);
292       if (impl->ref_surface)
293         cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
294                                      impl, ref_surface_destroyed);
295     }
296   else
297     cairo_surface_reference (impl->ref_surface);
298
299   return impl->ref_surface;
300 }
301
302 static void
303 _gdk_broadway_window_destroy (GdkWindow *window,
304                               gboolean   recursing,
305                               gboolean   foreign_destroy)
306 {
307   GdkWindowImplBroadway *impl;
308   GdkBroadwayDisplay *broadway_display;
309
310   g_return_if_fail (GDK_IS_WINDOW (window));
311
312   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
313
314   _gdk_broadway_selection_window_destroyed (window);
315   _gdk_broadway_window_grab_check_destroy (window);
316
317   if (impl->ref_surface)
318     {
319       cairo_surface_finish (impl->ref_surface);
320       cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
321                                    NULL, NULL);
322     }
323
324   if (impl->surface)
325     {
326       cairo_surface_destroy (impl->surface);
327       impl->surface = NULL;
328     }
329
330   broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
331   g_hash_table_remove (broadway_display->id_ht, GINT_TO_POINTER(impl->id));
332
333   _gdk_broadway_server_destroy_window (broadway_display->server,
334                                        impl->id);
335 }
336
337 static cairo_surface_t *
338 gdk_window_broadway_resize_cairo_surface (GdkWindow       *window,
339                                           cairo_surface_t *surface,
340                                           gint             width,
341                                           gint             height)
342 {
343   /* Image surfaces cannot be resized */
344   cairo_surface_destroy (surface);
345
346   return NULL;
347 }
348
349 static void
350 gdk_broadway_window_destroy_foreign (GdkWindow *window)
351 {
352 }
353
354 /* This function is called when the XWindow is really gone.
355  */
356 static void
357 gdk_broadway_window_destroy_notify (GdkWindow *window)
358 {
359   if (!GDK_WINDOW_DESTROYED (window))
360     {
361       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
362         g_warning ("GdkWindow %p unexpectedly destroyed", window);
363
364       _gdk_window_destroy (window, TRUE);
365     }
366
367   g_object_unref (window);
368 }
369
370 static void
371 gdk_window_broadway_show (GdkWindow *window, gboolean already_mapped)
372 {
373   GdkWindowImplBroadway *impl;
374   GdkBroadwayDisplay *broadway_display;
375
376   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
377   impl->visible = TRUE;
378
379   if (window->event_mask & GDK_STRUCTURE_MASK)
380     _gdk_make_event (GDK_WINDOW (window), GDK_MAP, NULL, FALSE);
381
382   if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
383     _gdk_make_event (GDK_WINDOW (window), GDK_MAP, NULL, FALSE);
384
385   broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
386   if (_gdk_broadway_server_window_show (broadway_display->server, impl->id))
387     queue_dirty_flush (broadway_display);
388
389 }
390
391 static void
392 gdk_window_broadway_hide (GdkWindow *window)
393 {
394   GdkWindowImplBroadway *impl;
395   GdkBroadwayDisplay *broadway_display;
396
397   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
398   impl->visible = FALSE;
399
400   if (window->event_mask & GDK_STRUCTURE_MASK)
401     _gdk_make_event (GDK_WINDOW (window), GDK_UNMAP, NULL, FALSE);
402
403   if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
404     _gdk_make_event (GDK_WINDOW (window), GDK_UNMAP, NULL, FALSE);
405
406   broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
407   if (_gdk_broadway_server_window_hide (broadway_display->server, impl->id))
408     queue_dirty_flush (broadway_display);
409
410   _gdk_window_clear_update_area (window);
411 }
412
413 static void
414 gdk_window_broadway_withdraw (GdkWindow *window)
415 {
416   gdk_window_broadway_hide (window);
417 }
418
419 static void
420 gdk_window_broadway_move_resize (GdkWindow *window,
421                                  gboolean   with_move,
422                                  gint       x,
423                                  gint       y,
424                                  gint       width,
425                                  gint       height)
426 {
427   GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
428   GdkBroadwayDisplay *broadway_display;
429   gboolean size_changed;
430
431   size_changed = FALSE;
432
433   broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
434
435   if (width > 0 || height > 0)
436     {
437       if (width < 1)
438         width = 1;
439
440       if (height < 1)
441         height = 1;
442
443       if (width != window->width ||
444           height != window->height)
445         {
446           size_changed = TRUE;
447
448           /* Resize clears the content */
449           impl->dirty = TRUE;
450           impl->last_synced = FALSE;
451
452           window->width = width;
453           window->height = height;
454           _gdk_broadway_window_resize_surface (window);
455         }
456     }
457
458   _gdk_broadway_server_window_move_resize (broadway_display->server,
459                                            impl->id,
460                                            with_move,
461                                            x, y,
462                                            window->width, window->height);
463   queue_dirty_flush (broadway_display);
464   if (size_changed)
465     window->resize_count++;
466 }
467
468 static gboolean
469 gdk_window_broadway_reparent (GdkWindow *window,
470                               GdkWindow *new_parent,
471                               gint       x,
472                               gint       y)
473 {
474   return FALSE;
475 }
476
477 static void
478 gdk_window_broadway_raise (GdkWindow *window)
479 {
480 }
481
482 static void
483 gdk_window_broadway_restack_under (GdkWindow *window,
484                                    GList *native_siblings /* in requested order, first is bottom-most */)
485 {
486 }
487
488 static void
489 gdk_window_broadway_restack_toplevel (GdkWindow *window,
490                                       GdkWindow *sibling,
491                                       gboolean   above)
492 {
493 }
494
495 static void
496 gdk_window_broadway_lower (GdkWindow *window)
497 {
498 }
499
500
501 static void
502 gdk_broadway_window_focus (GdkWindow *window,
503                            guint32    timestamp)
504 {
505 }
506
507 static void
508 gdk_broadway_window_set_type_hint (GdkWindow        *window,
509                                    GdkWindowTypeHint hint)
510 {
511 }
512
513 static GdkWindowTypeHint
514 gdk_broadway_window_get_type_hint (GdkWindow *window)
515 {
516   return GDK_WINDOW_TYPE_HINT_NORMAL;
517 }
518
519 static void
520 gdk_broadway_window_set_modal_hint (GdkWindow *window,
521                                     gboolean   modal)
522 {
523 }
524
525 static void
526 gdk_broadway_window_set_skip_taskbar_hint (GdkWindow *window,
527                                            gboolean   skips_taskbar)
528 {
529 }
530
531 static void
532 gdk_broadway_window_set_skip_pager_hint (GdkWindow *window,
533                                          gboolean   skips_pager)
534 {
535 }
536
537 static void
538 gdk_broadway_window_set_urgency_hint (GdkWindow *window,
539                                       gboolean   urgent)
540 {
541 }
542
543 static void
544 gdk_broadway_window_set_geometry_hints (GdkWindow         *window,
545                                         const GdkGeometry *geometry,
546                                         GdkWindowHints     geom_mask)
547 {
548 }
549
550 static void
551 gdk_broadway_window_set_title (GdkWindow   *window,
552                                const gchar *title)
553 {
554 }
555
556 static void
557 gdk_broadway_window_set_role (GdkWindow   *window,
558                               const gchar *role)
559 {
560 }
561
562 static void
563 gdk_broadway_window_set_startup_id (GdkWindow   *window,
564                                     const gchar *startup_id)
565 {
566 }
567
568 static void
569 gdk_broadway_window_set_transient_for (GdkWindow *window,
570                                        GdkWindow *parent)
571 {
572   GdkBroadwayDisplay *display;
573   GdkWindowImplBroadway *impl;
574   int parent_id;
575
576   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
577
578   parent_id = 0;
579   if (parent)
580     parent_id = GDK_WINDOW_IMPL_BROADWAY (parent->impl)->id;
581
582   impl->transient_for = parent_id;
583
584   display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (impl->wrapper));
585   _gdk_broadway_server_window_set_transient_for (display->server, impl->id, impl->transient_for);
586 }
587
588 static void
589 gdk_window_broadway_set_background (GdkWindow      *window,
590                                     cairo_pattern_t *pattern)
591 {
592   return;
593 }
594
595 static void
596 gdk_window_broadway_set_device_cursor (GdkWindow *window,
597                                        GdkDevice *device,
598                                        GdkCursor *cursor)
599 {
600   GdkWindowImplBroadway *impl;
601
602   g_return_if_fail (GDK_IS_WINDOW (window));
603   g_return_if_fail (GDK_IS_DEVICE (device));
604
605   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
606
607   if (!cursor)
608     g_hash_table_remove (impl->device_cursor, device);
609   else
610     {
611       _gdk_broadway_cursor_update_theme (cursor);
612       g_hash_table_replace (impl->device_cursor,
613                             device, gdk_cursor_ref (cursor));
614     }
615
616   if (!GDK_WINDOW_DESTROYED (window))
617     GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
618 }
619
620 GdkCursor *
621 _gdk_broadway_window_get_cursor (GdkWindow *window)
622 {
623   GdkWindowImplBroadway *impl;
624
625   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
626
627   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
628
629   return impl->cursor;
630 }
631
632 static void
633 gdk_window_broadway_get_geometry (GdkWindow *window,
634                                   gint      *x,
635                                   gint      *y,
636                                   gint      *width,
637                                   gint      *height)
638 {
639   GdkWindowImplBroadway *impl;
640
641   g_return_if_fail (GDK_IS_WINDOW (window));
642
643   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
644
645   /* TODO: These should really roundtrip to the client to get the current data */
646
647   if (x)
648     *x = impl->wrapper->x;
649   if (y)
650     *y = impl->wrapper->y;
651   if (width)
652     *width = impl->wrapper->width;
653   if (height)
654     *height = impl->wrapper->height;
655
656 }
657
658 static gint
659 gdk_window_broadway_get_root_coords (GdkWindow *window,
660                                      gint       x,
661                                      gint       y,
662                                      gint      *root_x,
663                                      gint      *root_y)
664 {
665   GdkWindowImplBroadway *impl;
666
667   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
668
669   if (root_x)
670     *root_x = x + impl->wrapper->x;
671   if (root_y)
672     *root_y = y + impl->wrapper->y;
673
674   return 1;
675 }
676
677 static void
678 gdk_broadway_window_get_root_origin (GdkWindow *window,
679                                      gint      *x,
680                                      gint      *y)
681 {
682   GdkWindowImplBroadway *impl;
683
684   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
685
686   /* TODO: This should take wm frame into account */
687
688   if (x)
689     *x = impl->wrapper->x;
690
691   if (y)
692     *y = impl->wrapper->x;
693 }
694
695 static void
696 gdk_broadway_window_get_frame_extents (GdkWindow    *window,
697                                        GdkRectangle *rect)
698 {
699   g_return_if_fail (rect != NULL);
700
701   /* TODO: This should take wm frame into account */
702
703   rect->x = window->x;
704   rect->y = window->y;
705   rect->width = window->width;
706   rect->height = window->height;
707 }
708
709 static gboolean
710 gdk_window_broadway_get_device_state (GdkWindow       *window,
711                                       GdkDevice       *device,
712                                       gint            *x,
713                                       gint            *y,
714                                       GdkModifierType *mask)
715 {
716   GdkWindow *child;
717
718   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
719
720   if (GDK_WINDOW_DESTROYED (window))
721     return FALSE;
722
723   GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
724                                               NULL, &child,
725                                               NULL, NULL,
726                                               x, y, mask);
727   return child != NULL;
728 }
729
730 static GdkEventMask
731 gdk_window_broadway_get_events (GdkWindow *window)
732 {
733   if (GDK_WINDOW_DESTROYED (window))
734     return 0;
735
736   return 0;
737 }
738
739 static void
740 gdk_window_broadway_set_events (GdkWindow    *window,
741                                 GdkEventMask  event_mask)
742 {
743   if (!GDK_WINDOW_DESTROYED (window))
744     {
745     }
746 }
747
748 static void
749 gdk_window_broadway_shape_combine_region (GdkWindow       *window,
750                                           const cairo_region_t *shape_region,
751                                           gint             offset_x,
752                                           gint             offset_y)
753 {
754 }
755
756 static void
757 gdk_window_broadway_input_shape_combine_region (GdkWindow       *window,
758                                                 const cairo_region_t *shape_region,
759                                                 gint             offset_x,
760                                                 gint             offset_y)
761 {
762 }
763
764
765 static void
766 gdk_broadway_window_set_override_redirect (GdkWindow *window,
767                                            gboolean override_redirect)
768 {
769 }
770
771 static void
772 gdk_broadway_window_set_accept_focus (GdkWindow *window,
773                                       gboolean accept_focus)
774 {
775   accept_focus = accept_focus != FALSE;
776
777   if (window->accept_focus != accept_focus)
778     {
779       window->accept_focus = accept_focus;
780     }
781 }
782
783 static void
784 gdk_broadway_window_set_focus_on_map (GdkWindow *window,
785                                       gboolean focus_on_map)
786 {
787   focus_on_map = focus_on_map != FALSE;
788
789   if (window->focus_on_map != focus_on_map)
790     {
791       window->focus_on_map = focus_on_map;
792     }
793 }
794
795
796 static void
797 gdk_broadway_window_set_icon_list (GdkWindow *window,
798                                    GList     *pixbufs)
799 {
800 }
801
802 static void
803 gdk_broadway_window_set_icon_name (GdkWindow   *window,
804                                    const gchar *name)
805 {
806   if (GDK_WINDOW_DESTROYED (window) ||
807       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
808     return;
809
810   g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
811                       GUINT_TO_POINTER (name != NULL));
812 }
813
814 static void
815 gdk_broadway_window_iconify (GdkWindow *window)
816 {
817   if (GDK_WINDOW_DESTROYED (window) ||
818       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
819     return;
820 }
821
822 static void
823 gdk_broadway_window_deiconify (GdkWindow *window)
824 {
825   if (GDK_WINDOW_DESTROYED (window) ||
826       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
827     return;
828 }
829
830 static void
831 gdk_broadway_window_stick (GdkWindow *window)
832 {
833   if (GDK_WINDOW_DESTROYED (window) ||
834       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
835     return;
836
837 }
838
839 static void
840 gdk_broadway_window_unstick (GdkWindow *window)
841 {
842   if (GDK_WINDOW_DESTROYED (window) ||
843       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
844     return;
845
846 }
847
848 static void
849 gdk_broadway_window_maximize (GdkWindow *window)
850 {
851   if (GDK_WINDOW_DESTROYED (window) ||
852       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
853     return;
854
855 }
856
857 static void
858 gdk_broadway_window_unmaximize (GdkWindow *window)
859 {
860   if (GDK_WINDOW_DESTROYED (window) ||
861       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
862     return;
863
864 }
865
866 static void
867 gdk_broadway_window_fullscreen (GdkWindow *window)
868 {
869   if (GDK_WINDOW_DESTROYED (window) ||
870       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
871     return;
872
873 }
874
875 static void
876 gdk_broadway_window_unfullscreen (GdkWindow *window)
877 {
878   if (GDK_WINDOW_DESTROYED (window) ||
879       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
880     return;
881
882 }
883
884 static void
885 gdk_broadway_window_set_keep_above (GdkWindow *window,
886                                     gboolean   setting)
887 {
888   g_return_if_fail (GDK_IS_WINDOW (window));
889
890   if (GDK_WINDOW_DESTROYED (window) ||
891       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
892     return;
893
894 }
895
896 static void
897 gdk_broadway_window_set_keep_below (GdkWindow *window, gboolean setting)
898 {
899   g_return_if_fail (GDK_IS_WINDOW (window));
900
901   if (GDK_WINDOW_DESTROYED (window) ||
902       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
903     return;
904
905 }
906
907 static GdkWindow *
908 gdk_broadway_window_get_group (GdkWindow *window)
909 {
910   if (GDK_WINDOW_DESTROYED (window) ||
911       !WINDOW_IS_TOPLEVEL (window))
912     return NULL;
913
914   return window;
915 }
916
917 static void
918 gdk_broadway_window_set_group (GdkWindow *window,
919                                GdkWindow *leader)
920 {
921 }
922
923 static void
924 gdk_broadway_window_set_decorations (GdkWindow      *window,
925                                      GdkWMDecoration decorations)
926 {
927   if (GDK_WINDOW_DESTROYED (window) ||
928       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
929     return;
930
931 }
932
933 static gboolean
934 gdk_broadway_window_get_decorations (GdkWindow       *window,
935                                      GdkWMDecoration *decorations)
936 {
937   gboolean result = FALSE;
938
939   if (GDK_WINDOW_DESTROYED (window) ||
940       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
941     return FALSE;
942
943   return result;
944 }
945
946 static void
947 gdk_broadway_window_set_functions (GdkWindow    *window,
948                                    GdkWMFunction functions)
949 {
950   g_return_if_fail (GDK_IS_WINDOW (window));
951
952   if (GDK_WINDOW_DESTROYED (window) ||
953       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
954     return;
955 }
956
957 static cairo_region_t *
958 gdk_broadway_window_get_shape (GdkWindow *window)
959 {
960   return NULL;
961 }
962
963 static cairo_region_t *
964 gdk_broadway_window_get_input_shape (GdkWindow *window)
965 {
966   return NULL;
967 }
968
969
970 static gboolean
971 gdk_window_broadway_set_static_gravities (GdkWindow *window,
972                                           gboolean   use_static)
973 {
974   return TRUE;
975 }
976
977 typedef struct _MoveResizeData MoveResizeData;
978
979 struct _MoveResizeData
980 {
981   GdkDisplay *display;
982
983   GdkWindow *moveresize_window;
984   GdkWindow *moveresize_emulation_window;
985   gboolean is_resize;
986   GdkWindowEdge resize_edge;
987   gint moveresize_button;
988   gint moveresize_x;
989   gint moveresize_y;
990   gint moveresize_orig_x;
991   gint moveresize_orig_y;
992   gint moveresize_orig_width;
993   gint moveresize_orig_height;
994   long moveresize_process_time;
995   BroadwayInputMsg *moveresize_pending_event;
996 };
997
998 static MoveResizeData *
999 get_move_resize_data (GdkDisplay *display,
1000                       gboolean    create)
1001 {
1002   MoveResizeData *mv_resize;
1003   static GQuark move_resize_quark = 0;
1004
1005   if (!move_resize_quark)
1006     move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize");
1007
1008   mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark);
1009
1010   if (!mv_resize && create)
1011     {
1012       mv_resize = g_new0 (MoveResizeData, 1);
1013       mv_resize->display = display;
1014
1015       g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize);
1016     }
1017
1018   return mv_resize;
1019 }
1020
1021 static void
1022 update_pos (MoveResizeData *mv_resize,
1023             gint            new_root_x,
1024             gint            new_root_y)
1025 {
1026   gint dx, dy;
1027
1028   dx = new_root_x - mv_resize->moveresize_x;
1029   dy = new_root_y - mv_resize->moveresize_y;
1030
1031   if (mv_resize->is_resize)
1032     {
1033       gint x, y, w, h;
1034
1035       x = mv_resize->moveresize_orig_x;
1036       y = mv_resize->moveresize_orig_y;
1037
1038       w = mv_resize->moveresize_orig_width;
1039       h = mv_resize->moveresize_orig_height;
1040
1041       switch (mv_resize->resize_edge)
1042         {
1043         case GDK_WINDOW_EDGE_NORTH_WEST:
1044           x += dx;
1045           y += dy;
1046           w -= dx;
1047           h -= dy;
1048           break;
1049         case GDK_WINDOW_EDGE_NORTH:
1050           y += dy;
1051           h -= dy;
1052           break;
1053         case GDK_WINDOW_EDGE_NORTH_EAST:
1054           y += dy;
1055           h -= dy;
1056           w += dx;
1057           break;
1058         case GDK_WINDOW_EDGE_SOUTH_WEST:
1059           h += dy;
1060           x += dx;
1061           w -= dx;
1062           break;
1063         case GDK_WINDOW_EDGE_SOUTH_EAST:
1064           w += dx;
1065           h += dy;
1066           break;
1067         case GDK_WINDOW_EDGE_SOUTH:
1068           h += dy;
1069           break;
1070         case GDK_WINDOW_EDGE_EAST:
1071           w += dx;
1072           break;
1073         case GDK_WINDOW_EDGE_WEST:
1074           x += dx;
1075           w -= dx;
1076           break;
1077         }
1078
1079       x = MAX (x, 0);
1080       y = MAX (y, 0);
1081       w = MAX (w, 1);
1082       h = MAX (h, 1);
1083
1084       gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
1085     }
1086   else
1087     {
1088       gint x, y;
1089
1090       x = mv_resize->moveresize_orig_x + dx;
1091       y = mv_resize->moveresize_orig_y + dy;
1092
1093       gdk_window_move (mv_resize->moveresize_window, x, y);
1094     }
1095 }
1096
1097 static void
1098 finish_drag (MoveResizeData *mv_resize)
1099 {
1100   gdk_window_destroy (mv_resize->moveresize_emulation_window);
1101   mv_resize->moveresize_emulation_window = NULL;
1102   g_object_unref (mv_resize->moveresize_window);
1103   mv_resize->moveresize_window = NULL;
1104
1105   if (mv_resize->moveresize_pending_event)
1106     {
1107       g_free (mv_resize->moveresize_pending_event);
1108       mv_resize->moveresize_pending_event = NULL;
1109     }
1110 }
1111
1112 static gboolean
1113 moveresize_lookahead (GdkDisplay *display,
1114                       MoveResizeData *mv_resize,
1115                       BroadwayInputMsg *event)
1116 {
1117   GdkBroadwayDisplay *broadway_display;
1118
1119   broadway_display = GDK_BROADWAY_DISPLAY (display);
1120
1121   return !_gdk_broadway_server_lookahead_event (broadway_display->server, "mb");
1122 }
1123
1124 gboolean
1125 _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
1126                                        BroadwayInputMsg *event)
1127 {
1128   guint button_mask = 0;
1129   MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
1130
1131   if (!mv_resize || !mv_resize->moveresize_window)
1132     return FALSE;
1133
1134   button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
1135
1136   switch (event->base.type)
1137     {
1138     case 'm':
1139       if (mv_resize->moveresize_window->resize_count > 0)
1140         {
1141           if (mv_resize->moveresize_pending_event)
1142             *mv_resize->moveresize_pending_event = *event;
1143           else
1144             mv_resize->moveresize_pending_event =
1145               g_memdup (event, sizeof (BroadwayInputMsg));
1146
1147           break;
1148         }
1149       if (!moveresize_lookahead (display, mv_resize, event))
1150         break;
1151
1152       update_pos (mv_resize,
1153                   event->pointer.root_x,
1154                   event->pointer.root_y);
1155
1156       /* This should never be triggered in normal cases, but in the
1157        * case where the drag started without an implicit grab being
1158        * in effect, we could miss the release if it occurs before
1159        * we grab the pointer; this ensures that we will never
1160        * get a permanently stuck grab.
1161        */
1162       if ((event->pointer.state & button_mask) == 0)
1163         finish_drag (mv_resize);
1164       break;
1165
1166     case 'B':
1167       update_pos (mv_resize,
1168                   event->pointer.root_x,
1169                   event->pointer.root_y);
1170
1171       if (event->button.button == mv_resize->moveresize_button)
1172         finish_drag (mv_resize);
1173       break;
1174     }
1175   return TRUE;
1176 }
1177
1178 gboolean
1179 _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
1180                                          GdkWindow  *window)
1181 {
1182   BroadwayInputMsg *tmp_event;
1183   MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
1184
1185   if (!mv_resize || window != mv_resize->moveresize_window)
1186     return FALSE;
1187
1188   if (mv_resize->moveresize_pending_event)
1189     {
1190       tmp_event = mv_resize->moveresize_pending_event;
1191       mv_resize->moveresize_pending_event = NULL;
1192       _gdk_broadway_moveresize_handle_event (display, tmp_event);
1193       g_free (tmp_event);
1194     }
1195
1196   return TRUE;
1197 }
1198
1199 static void
1200 create_moveresize_window (MoveResizeData *mv_resize,
1201                           guint32         timestamp)
1202 {
1203   GdkWindowAttr attributes;
1204   gint attributes_mask;
1205   GdkGrabStatus status;
1206
1207   g_assert (mv_resize->moveresize_emulation_window == NULL);
1208
1209   attributes.x = -100;
1210   attributes.y = -100;
1211   attributes.width = 10;
1212   attributes.height = 10;
1213   attributes.window_type = GDK_WINDOW_TEMP;
1214   attributes.wclass = GDK_INPUT_ONLY;
1215   attributes.override_redirect = TRUE;
1216   attributes.event_mask = 0;
1217
1218   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
1219
1220   mv_resize->moveresize_emulation_window =
1221     gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)),
1222                     &attributes,
1223                     attributes_mask);
1224
1225   gdk_window_show (mv_resize->moveresize_emulation_window);
1226
1227   status = gdk_pointer_grab (mv_resize->moveresize_emulation_window,
1228                              FALSE,
1229                              GDK_BUTTON_RELEASE_MASK |
1230                              GDK_POINTER_MOTION_MASK,
1231                              NULL,
1232                              NULL,
1233                              timestamp);
1234
1235   if (status != GDK_GRAB_SUCCESS)
1236     {
1237       /* If this fails, some other client has grabbed the window
1238        * already.
1239        */
1240       finish_drag (mv_resize);
1241     }
1242
1243   mv_resize->moveresize_process_time = 0;
1244 }
1245
1246 static void
1247 gdk_broadway_window_begin_resize_drag (GdkWindow     *window,
1248                                        GdkWindowEdge  edge,
1249                                        GdkDevice     *device,
1250                                        gint           button,
1251                                        gint           root_x,
1252                                        gint           root_y,
1253                                        guint32        timestamp)
1254 {
1255   GdkBroadwayDisplay *broadway_display;
1256   MoveResizeData *mv_resize;
1257
1258   if (GDK_WINDOW_DESTROYED (window) ||
1259       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1260     return;
1261
1262   /* We need a connection to be able to get mouse events, if not, punt */
1263   broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
1264
1265   mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
1266
1267   mv_resize->is_resize = TRUE;
1268   mv_resize->moveresize_button = button;
1269   mv_resize->resize_edge = edge;
1270   mv_resize->moveresize_x = root_x;
1271   mv_resize->moveresize_y = root_y;
1272   mv_resize->moveresize_window = g_object_ref (window);
1273
1274   gdk_window_get_origin (mv_resize->moveresize_window,
1275                          &mv_resize->moveresize_orig_x,
1276                          &mv_resize->moveresize_orig_y);
1277   mv_resize->moveresize_orig_width = gdk_window_get_width (window);
1278   mv_resize->moveresize_orig_height = gdk_window_get_height (window);
1279
1280   create_moveresize_window (mv_resize, timestamp);
1281 }
1282
1283 static void
1284 gdk_broadway_window_begin_move_drag (GdkWindow *window,
1285                                      GdkDevice *device,
1286                                      gint       button,
1287                                      gint       root_x,
1288                                      gint       root_y,
1289                                      guint32    timestamp)
1290 {
1291   if (GDK_WINDOW_DESTROYED (window) ||
1292       !WINDOW_IS_TOPLEVEL (window))
1293     return;
1294
1295 }
1296
1297 static gboolean
1298 gdk_broadway_window_beep (GdkWindow *window)
1299 {
1300   return FALSE;
1301 }
1302
1303 static void
1304 gdk_broadway_window_set_opacity (GdkWindow *window,
1305                                  gdouble    opacity)
1306 {
1307   g_return_if_fail (GDK_IS_WINDOW (window));
1308
1309   if (GDK_WINDOW_DESTROYED (window) ||
1310       !WINDOW_IS_TOPLEVEL (window))
1311     return;
1312
1313   if (opacity < 0)
1314     opacity = 0;
1315   else if (opacity > 1)
1316     opacity = 1;
1317 }
1318
1319 static void
1320 gdk_broadway_window_set_composited (GdkWindow *window,
1321                                     gboolean   composited)
1322 {
1323 }
1324
1325 static void
1326 gdk_broadway_window_process_updates_recurse (GdkWindow *window,
1327                                              cairo_region_t *region)
1328 {
1329   GdkWindowImplBroadway *impl;
1330
1331   _gdk_window_process_updates_recurse (window, region);
1332
1333   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
1334   impl->dirty = TRUE;
1335   queue_dirty_flush (GDK_BROADWAY_DISPLAY (gdk_window_get_display (window)));
1336 }
1337
1338 void
1339 _gdk_broadway_display_before_process_all_updates (GdkDisplay *display)
1340 {
1341 }
1342
1343 void
1344 _gdk_broadway_display_after_process_all_updates (GdkDisplay *display)
1345 {
1346 }
1347
1348 gboolean
1349 _gdk_broadway_window_queue_antiexpose (GdkWindow *window,
1350                                        cairo_region_t *area)
1351 {
1352   return TRUE;
1353 }
1354
1355 static void
1356 copy_region (cairo_surface_t *surface,
1357              cairo_region_t *area,
1358              gint            dx,
1359              gint            dy)
1360 {
1361   cairo_t *cr;
1362
1363   cr = cairo_create (surface);
1364
1365   gdk_cairo_region (cr, area);
1366   cairo_clip (cr);
1367
1368   /* NB: This is a self-copy and Cairo doesn't support that yet.
1369    * So we do a litle trick.
1370    */
1371   cairo_push_group (cr);
1372
1373   cairo_set_source_surface (cr, surface, dx, dy);
1374   cairo_paint (cr);
1375
1376   cairo_pop_group_to_source (cr);
1377   cairo_paint (cr);
1378
1379   cairo_destroy (cr);
1380 }
1381
1382 void
1383 _gdk_broadway_window_translate (GdkWindow      *window,
1384                                 cairo_region_t *area,
1385                                 gint            dx,
1386                                 gint            dy)
1387 {
1388   GdkWindowImplBroadway *impl;
1389   GdkBroadwayDisplay *broadway_display;
1390
1391   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
1392
1393   if (impl->surface)
1394     {
1395       copy_region (impl->surface, area, dx, dy);
1396       broadway_display = GDK_BROADWAY_DISPLAY (gdk_window_get_display (window));
1397
1398       if (_gdk_broadway_server_window_translate (broadway_display->server,
1399                                                  impl->id,
1400                                                  area, dx, dy))
1401         queue_dirty_flush (broadway_display);
1402     }
1403 }
1404
1405 guint32
1406 gdk_broadway_get_last_seen_time (GdkWindow  *window)
1407 {
1408   GdkDisplay *display;
1409
1410   display = gdk_window_get_display (window);
1411   return _gdk_broadway_server_get_last_seen_time (GDK_BROADWAY_DISPLAY (display)->server);
1412 }
1413
1414 static void
1415 gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass)
1416 {
1417   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1418   GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
1419
1420   object_class->finalize = gdk_window_impl_broadway_finalize;
1421
1422   impl_class->ref_cairo_surface = gdk_window_broadway_ref_cairo_surface;
1423   impl_class->show = gdk_window_broadway_show;
1424   impl_class->hide = gdk_window_broadway_hide;
1425   impl_class->withdraw = gdk_window_broadway_withdraw;
1426   impl_class->set_events = gdk_window_broadway_set_events;
1427   impl_class->get_events = gdk_window_broadway_get_events;
1428   impl_class->raise = gdk_window_broadway_raise;
1429   impl_class->lower = gdk_window_broadway_lower;
1430   impl_class->restack_under = gdk_window_broadway_restack_under;
1431   impl_class->restack_toplevel = gdk_window_broadway_restack_toplevel;
1432   impl_class->move_resize = gdk_window_broadway_move_resize;
1433   impl_class->set_background = gdk_window_broadway_set_background;
1434   impl_class->reparent = gdk_window_broadway_reparent;
1435   impl_class->set_device_cursor = gdk_window_broadway_set_device_cursor;
1436   impl_class->get_geometry = gdk_window_broadway_get_geometry;
1437   impl_class->get_root_coords = gdk_window_broadway_get_root_coords;
1438   impl_class->get_device_state = gdk_window_broadway_get_device_state;
1439   impl_class->shape_combine_region = gdk_window_broadway_shape_combine_region;
1440   impl_class->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
1441   impl_class->set_static_gravities = gdk_window_broadway_set_static_gravities;
1442   impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
1443   impl_class->translate = _gdk_broadway_window_translate;
1444   impl_class->destroy = _gdk_broadway_window_destroy;
1445   impl_class->destroy_foreign = gdk_broadway_window_destroy_foreign;
1446   impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
1447   impl_class->get_shape = gdk_broadway_window_get_shape;
1448   impl_class->get_input_shape = gdk_broadway_window_get_input_shape;
1449   impl_class->beep = gdk_broadway_window_beep;
1450
1451   impl_class->focus = gdk_broadway_window_focus;
1452   impl_class->set_type_hint = gdk_broadway_window_set_type_hint;
1453   impl_class->get_type_hint = gdk_broadway_window_get_type_hint;
1454   impl_class->set_modal_hint = gdk_broadway_window_set_modal_hint;
1455   impl_class->set_skip_taskbar_hint = gdk_broadway_window_set_skip_taskbar_hint;
1456   impl_class->set_skip_pager_hint = gdk_broadway_window_set_skip_pager_hint;
1457   impl_class->set_urgency_hint = gdk_broadway_window_set_urgency_hint;
1458   impl_class->set_geometry_hints = gdk_broadway_window_set_geometry_hints;
1459   impl_class->set_title = gdk_broadway_window_set_title;
1460   impl_class->set_role = gdk_broadway_window_set_role;
1461   impl_class->set_startup_id = gdk_broadway_window_set_startup_id;
1462   impl_class->set_transient_for = gdk_broadway_window_set_transient_for;
1463   impl_class->get_root_origin = gdk_broadway_window_get_root_origin;
1464   impl_class->get_frame_extents = gdk_broadway_window_get_frame_extents;
1465   impl_class->set_override_redirect = gdk_broadway_window_set_override_redirect;
1466   impl_class->set_accept_focus = gdk_broadway_window_set_accept_focus;
1467   impl_class->set_focus_on_map = gdk_broadway_window_set_focus_on_map;
1468   impl_class->set_icon_list = gdk_broadway_window_set_icon_list;
1469   impl_class->set_icon_name = gdk_broadway_window_set_icon_name;
1470   impl_class->iconify = gdk_broadway_window_iconify;
1471   impl_class->deiconify = gdk_broadway_window_deiconify;
1472   impl_class->stick = gdk_broadway_window_stick;
1473   impl_class->unstick = gdk_broadway_window_unstick;
1474   impl_class->maximize = gdk_broadway_window_maximize;
1475   impl_class->unmaximize = gdk_broadway_window_unmaximize;
1476   impl_class->fullscreen = gdk_broadway_window_fullscreen;
1477   impl_class->unfullscreen = gdk_broadway_window_unfullscreen;
1478   impl_class->set_keep_above = gdk_broadway_window_set_keep_above;
1479   impl_class->set_keep_below = gdk_broadway_window_set_keep_below;
1480   impl_class->get_group = gdk_broadway_window_get_group;
1481   impl_class->set_group = gdk_broadway_window_set_group;
1482   impl_class->set_decorations = gdk_broadway_window_set_decorations;
1483   impl_class->get_decorations = gdk_broadway_window_get_decorations;
1484   impl_class->set_functions = gdk_broadway_window_set_functions;
1485   impl_class->set_functions = gdk_broadway_window_set_functions;
1486   impl_class->begin_resize_drag = gdk_broadway_window_begin_resize_drag;
1487   impl_class->begin_move_drag = gdk_broadway_window_begin_move_drag;
1488   impl_class->set_opacity = gdk_broadway_window_set_opacity;
1489   impl_class->set_composited = gdk_broadway_window_set_composited;
1490   impl_class->destroy_notify = gdk_broadway_window_destroy_notify;
1491   impl_class->register_dnd = _gdk_broadway_window_register_dnd;
1492   impl_class->drag_begin = _gdk_broadway_window_drag_begin;
1493   impl_class->process_updates_recurse = gdk_broadway_window_process_updates_recurse;
1494   impl_class->sync_rendering = _gdk_broadway_window_sync_rendering;
1495   impl_class->simulate_key = _gdk_broadway_window_simulate_key;
1496   impl_class->simulate_button = _gdk_broadway_window_simulate_button;
1497   impl_class->get_property = _gdk_broadway_window_get_property;
1498   impl_class->change_property = _gdk_broadway_window_change_property;
1499   impl_class->delete_property = _gdk_broadway_window_delete_property;
1500   impl_class->get_drag_protocol = _gdk_broadway_window_get_drag_protocol;
1501 }