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