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