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