]> Pileus Git - ~andy/gtk/blob - gdk/broadway/gdkwindow-broadway.c
[broadway] Implement window resize
[~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 static void        gdk_window_impl_iface_init     (GdkWindowImplIface *iface);
53
54 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
55   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
56    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
57
58 #define WINDOW_IS_TOPLEVEL(window)                   \
59   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
60    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
61    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
62
63 /* Return whether time1 is considered later than time2 as far as xserver
64  * time is concerned.  Accounts for wraparound.
65  */
66 #define XSERVER_TIME_IS_LATER(time1, time2)                        \
67   ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
68     (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
69   )
70
71 G_DEFINE_TYPE_WITH_CODE (GdkWindowImplBroadway,
72                          gdk_window_impl_broadway,
73                          GDK_TYPE_DRAWABLE_IMPL_BROADWAY,
74                          G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL,
75                                                 gdk_window_impl_iface_init));
76
77 static GList *all_windows;
78
79 GType
80 _gdk_window_impl_get_type (void)
81 {
82   return gdk_window_impl_broadway_get_type ();
83 }
84
85 static void
86 diff_surfaces (cairo_surface_t *surface,
87                cairo_surface_t *old_surface)
88 {
89   guint8 *data, *old_data;
90   guint32 *line, *old_line;
91   int w, h, stride, old_stride;
92   int x, y;
93
94   data = cairo_image_surface_get_data (surface);
95   old_data = cairo_image_surface_get_data (old_surface);
96
97   w = cairo_image_surface_get_width (surface);
98   h = cairo_image_surface_get_height (surface);
99
100   stride = cairo_image_surface_get_stride (surface);
101   old_stride = cairo_image_surface_get_stride (old_surface);
102
103   for (y = 0; y < h; y++)
104     {
105       line = (guint32 *)data;
106       old_line = (guint32 *)old_data;
107
108       for (x = 0; x < w; x++)
109         {
110           if ((*line & 0xffffff) == (*old_line & 0xffffff))
111             *old_line = 0;
112           else
113             *old_line = *line | 0xff000000;
114           line ++;
115           old_line ++;
116         }
117
118       data += stride;
119       old_data += old_stride;
120     }
121 }
122
123 static guint dirty_flush_id = 0;
124
125 static void
126 window_data_send (BroadwayClient *client, GdkWindowImplBroadway *impl)
127 {
128   GdkDrawableImplBroadway *drawable_impl = GDK_DRAWABLE_IMPL_BROADWAY (impl);
129   cairo_t *cr;
130
131   if (drawable_impl->surface == NULL)
132     return;
133
134   if (impl->last_synced)
135     {
136       diff_surfaces (drawable_impl->surface,
137                      drawable_impl->last_surface);
138       broadway_client_put_rgba (client, impl->id, 0, 0,
139                                 cairo_image_surface_get_width (drawable_impl->last_surface),
140                                 cairo_image_surface_get_height (drawable_impl->last_surface),
141                                 cairo_image_surface_get_stride (drawable_impl->last_surface),
142                                 cairo_image_surface_get_data (drawable_impl->last_surface));
143     }
144   else
145     {
146       impl->last_synced = TRUE;
147       broadway_client_put_rgb (client, impl->id, 0, 0,
148                                cairo_image_surface_get_width (drawable_impl->surface),
149                                cairo_image_surface_get_height (drawable_impl->surface),
150                                cairo_image_surface_get_stride (drawable_impl->surface),
151                                cairo_image_surface_get_data (drawable_impl->surface));
152     }
153
154   cr = cairo_create (drawable_impl->last_surface);
155   cairo_set_source_surface (cr, drawable_impl->surface, 0, 0);
156   cairo_paint (cr);
157   cairo_destroy (cr);
158 }
159
160 static gboolean
161 dirty_flush_idle (gpointer data)
162 {
163   GList *l;
164   GdkDisplayBroadway *display;
165   BroadwayClient *client;
166
167   dirty_flush_id = 0;
168
169   display = GDK_DISPLAY_BROADWAY (gdk_display_get_default ());
170   client = display->output;
171   if (client == NULL)
172     return FALSE;
173
174   for (l = all_windows; l != NULL; l = l->next)
175     {
176       GdkWindowImplBroadway *impl = l->data;
177
178       if (impl->dirty)
179         {
180           impl->dirty = FALSE;
181           window_data_send (display->output, impl);
182         }
183     }
184
185   broadway_client_flush (client);
186
187   return FALSE;
188 }
189
190 static void
191 queue_dirty_flush (GdkDisplayBroadway *display)
192 {
193   if (dirty_flush_id == 0 && display->output != NULL)
194     dirty_flush_id = gdk_threads_add_idle (dirty_flush_idle, NULL);
195 }
196
197 void
198 _gdk_broadway_resync_windows (void)
199 {
200   GdkDisplayBroadway *display;
201   GList *l;
202
203   dirty_flush_id = 0;
204
205   display = GDK_DISPLAY_BROADWAY (gdk_display_get_default ());
206
207   for (l = all_windows; l != NULL; l = l->next)
208     {
209       GdkWindowImplBroadway *impl = l->data;
210       GdkWindowObject *private;
211
212       private = (GdkWindowObject*) GDK_DRAWABLE_IMPL_BROADWAY (impl)->wrapper;
213
214       if (impl->id == 0)
215         continue; /* Skip root */
216
217       impl->dirty = FALSE;
218       impl->last_synced = FALSE;
219       broadway_client_new_surface (display->output,
220                                    impl->id,
221                                    private->x,
222                                    private->y,
223                                    private->width,
224                                    private->height);
225       if (GDK_WINDOW_IS_MAPPED (private))
226         {
227           broadway_client_show_surface (display->output, impl->id);
228           window_data_send (display->output, impl);
229         }
230     }
231
232   broadway_client_flush (display->output);
233 }
234
235 static void
236 gdk_window_impl_broadway_init (GdkWindowImplBroadway *impl)
237 {
238   all_windows = g_list_prepend (all_windows, impl);
239   impl->toplevel_window_type = -1;
240   impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
241                                                (GDestroyNotify) gdk_cursor_unref);
242 }
243
244 static void
245 gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass)
246 {
247   GObjectClass *object_class = G_OBJECT_CLASS (klass);
248
249   object_class->finalize = gdk_window_impl_broadway_finalize;
250 }
251
252 static void
253 gdk_window_impl_broadway_finalize (GObject *object)
254 {
255   GdkWindowObject *wrapper;
256   GdkDrawableImplBroadway *draw_impl;
257   GdkWindowImplBroadway *window_impl;
258   GdkDisplayBroadway *display_broadway;
259
260   g_return_if_fail (GDK_IS_WINDOW_IMPL_BROADWAY (object));
261
262   draw_impl = GDK_DRAWABLE_IMPL_BROADWAY (object);
263   window_impl = GDK_WINDOW_IMPL_BROADWAY (object);
264
265   wrapper = (GdkWindowObject*) draw_impl->wrapper;
266
267   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (draw_impl->wrapper));
268   g_hash_table_remove (display_broadway->id_ht, GINT_TO_POINTER(window_impl->id));
269
270   if (window_impl->cursor)
271     gdk_cursor_unref (window_impl->cursor);
272
273   g_hash_table_destroy (window_impl->device_cursor);
274
275   all_windows = g_list_remove (all_windows, window_impl);
276
277   G_OBJECT_CLASS (gdk_window_impl_broadway_parent_class)->finalize (object);
278 }
279
280 void
281 _gdk_windowing_window_init (GdkScreen * screen)
282 {
283   GdkWindowObject *private;
284   GdkDrawableImplBroadway *draw_impl;
285   GdkScreenBroadway *screen_broadway;
286
287   screen_broadway = GDK_SCREEN_BROADWAY (screen);
288
289   g_assert (screen_broadway->root_window == NULL);
290
291   screen_broadway->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
292
293   private = (GdkWindowObject *) screen_broadway->root_window;
294   private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
295   private->impl_window = private;
296   private->visual = gdk_screen_get_system_visual (screen);
297
298   draw_impl = GDK_DRAWABLE_IMPL_BROADWAY (private->impl);
299
300   draw_impl->screen = screen;
301   draw_impl->wrapper = GDK_DRAWABLE (private);
302
303   private->window_type = GDK_WINDOW_ROOT;
304   private->depth = 24;
305
306   private->x = 0;
307   private->y = 0;
308   private->abs_x = 0;
309   private->abs_y = 0;
310   private->width = gdk_screen_get_width (screen);
311   private->height = gdk_screen_get_height (screen);
312   private->viewable = TRUE;
313
314   _gdk_window_update_size (screen_broadway->root_window);
315 }
316
317 void
318 _gdk_window_impl_new (GdkWindow     *window,
319                       GdkWindow     *real_parent,
320                       GdkScreen     *screen,
321                       GdkEventMask   event_mask,
322                       GdkWindowAttr *attributes,
323                       gint           attributes_mask)
324 {
325   GdkWindowObject *private;
326   GdkWindowImplBroadway *impl;
327   GdkDrawableImplBroadway *draw_impl;
328   GdkScreenBroadway *screen_broadway;
329   GdkDisplayBroadway *display_broadway;
330   static int current_id = 1; /* 0 is the root window */
331
332   private = (GdkWindowObject *) window;
333
334   screen_broadway = GDK_SCREEN_BROADWAY (screen);
335   display_broadway = GDK_DISPLAY_BROADWAY (GDK_SCREEN_DISPLAY (screen));
336
337
338   impl = g_object_new (_gdk_window_impl_get_type (), NULL);
339   private->impl = (GdkDrawable *)impl;
340   impl->id = current_id++;
341   g_hash_table_insert (display_broadway->id_ht, GINT_TO_POINTER(impl->id), window);
342   draw_impl = GDK_DRAWABLE_IMPL_BROADWAY (impl);
343   draw_impl->wrapper = GDK_DRAWABLE (window);
344
345   draw_impl->screen = screen;
346
347   g_assert (private->window_type == GDK_WINDOW_TOPLEVEL ||
348             private->window_type == GDK_WINDOW_TEMP);
349   g_assert (GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_ROOT);
350
351   if (display_broadway->output)
352     broadway_client_new_surface (display_broadway->output,
353                                  impl->id,
354                                  private->x,
355                                  private->y,
356                                  private->width,
357                                  private->height);
358 }
359
360
361 GdkWindow *
362 gdk_window_foreign_new_for_display (GdkDisplay     *display,
363                                     GdkNativeWindow anid)
364 {
365   return NULL;
366 }
367
368 GdkWindow *
369 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
370 {
371   return NULL;
372 }
373
374 GdkWindow *
375 gdk_window_lookup (GdkNativeWindow anid)
376 {
377   return NULL;
378 }
379
380 static void
381 _gdk_broadway_window_destroy (GdkWindow *window,
382                               gboolean   recursing,
383                               gboolean   foreign_destroy)
384 {
385   GdkWindowObject *private = (GdkWindowObject *)window;
386   GdkWindowImplBroadway *impl;
387   GdkDisplayBroadway *display_broadway;
388
389   g_return_if_fail (GDK_IS_WINDOW (window));
390
391   private = (GdkWindowObject*) window;
392   impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
393
394   _gdk_selection_window_destroyed (window);
395
396   _gdk_broadway_drawable_finish (private->impl);
397
398   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
399   if (display_broadway->output)
400     broadway_client_destroy_surface (display_broadway->output,
401                                      impl->id);
402 }
403
404 static cairo_surface_t *
405 gdk_window_broadway_resize_cairo_surface (GdkWindow       *window,
406                                           cairo_surface_t *surface,
407                                           gint             width,
408                                           gint             height)
409 {
410   /* Image surfaces cannot be resized */
411   cairo_surface_destroy (surface);
412
413   return NULL;
414 }
415
416 void
417 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
418 {
419 }
420
421 /* This function is called when the XWindow is really gone.
422  */
423 void
424 gdk_window_destroy_notify (GdkWindow *window)
425 {
426   GdkWindowImplBroadway *window_impl;
427
428   window_impl = GDK_WINDOW_IMPL_BROADWAY (((GdkWindowObject *)window)->impl);
429
430   if (!GDK_WINDOW_DESTROYED (window))
431     {
432       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
433         g_warning ("GdkWindow %p unexpectedly destroyed", window);
434
435       _gdk_window_destroy (window, TRUE);
436     }
437
438   g_object_unref (window);
439 }
440
441 static void
442 gdk_window_broadway_show (GdkWindow *window, gboolean already_mapped)
443 {
444   GdkWindowObject *private;
445   GdkWindowImplBroadway *impl;
446   GdkDisplayBroadway *display_broadway;
447
448   private = (GdkWindowObject*) window;
449   impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
450
451   if (private->event_mask & GDK_STRUCTURE_MASK)
452     _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
453
454   if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
455     _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
456
457   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
458   if (display_broadway->output)
459     {
460       broadway_client_show_surface (display_broadway->output, impl->id);
461       queue_dirty_flush (display_broadway);
462     }
463 }
464
465 static void
466 gdk_window_broadway_hide (GdkWindow *window)
467 {
468   GdkWindowObject *private;
469   GdkWindowImplBroadway *impl;
470   GdkDisplayBroadway *display_broadway;
471
472   private = (GdkWindowObject*) window;
473   impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
474
475   if (private->event_mask & GDK_STRUCTURE_MASK)
476     _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
477
478   if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
479     _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
480
481   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
482   if (display_broadway->output)
483     {
484       broadway_client_hide_surface (display_broadway->output, impl->id);
485       queue_dirty_flush (display_broadway);
486     }
487
488   _gdk_window_clear_update_area (window);
489 }
490
491 static void
492 gdk_window_broadway_withdraw (GdkWindow *window)
493 {
494   gdk_window_broadway_hide (window);
495 }
496
497 static void
498 gdk_window_broadway_move_resize (GdkWindow *window,
499                                  gboolean   with_move,
500                                  gint       x,
501                                  gint       y,
502                                  gint       width,
503                                  gint       height)
504 {
505   GdkWindowObject *private = (GdkWindowObject *) window;;
506   GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
507   GdkDrawableImplBroadway *drawable = GDK_DRAWABLE_IMPL_BROADWAY (impl);
508   GdkDisplayBroadway *display_broadway;
509   gboolean changed;
510
511   changed = FALSE;
512
513   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
514   if (with_move)
515     {
516       changed = TRUE;
517       private->x = x;
518       private->y = y;
519       if (display_broadway->output != NULL)
520         {
521           broadway_client_move_surface (display_broadway->output,
522                                         impl->id, x, y);
523           queue_dirty_flush (display_broadway);
524         }
525     }
526
527
528   if (width > 0 || height > 0)
529     {
530       if (width < 1)
531         width = 1;
532
533       if (height < 1)
534         height = 1;
535
536       if (width != private->width ||
537           height != private->height)
538         {
539           changed = TRUE;
540
541           /* Resize clears the content */
542           impl->dirty = TRUE;
543           impl->last_synced = FALSE;
544
545           broadway_client_resize_surface (display_broadway->output,
546                                           impl->id, width, height);
547           queue_dirty_flush (display_broadway);
548
549           private->width = width;
550           private->height = height;
551           _gdk_broadway_drawable_update_size (private->impl);
552           gdk_window_invalidate_rect (window, NULL, TRUE);
553         }
554     }
555
556   if (changed)
557     {
558       GdkEvent *event;
559       GList *node;
560
561       event = gdk_event_new (GDK_CONFIGURE);
562       event->configure.window = g_object_ref (window);
563       event->configure.x = private->x;
564       event->configure.y = private->y;
565       event->configure.width = private->width;
566       event->configure.height = private->height;
567
568       gdk_event_set_device (event, GDK_DISPLAY_OBJECT (display_broadway)->core_pointer);
569
570       node = _gdk_event_queue_append (GDK_DISPLAY_OBJECT (display_broadway), event);
571       _gdk_windowing_got_event (GDK_DISPLAY_OBJECT (display_broadway), node, event, 0);
572     }
573 }
574
575 static gboolean
576 gdk_window_broadway_reparent (GdkWindow *window,
577                          GdkWindow *new_parent,
578                          gint       x,
579                          gint       y)
580 {
581   return FALSE;
582 }
583
584 static void
585 gdk_window_broadway_raise (GdkWindow *window)
586 {
587 }
588
589 static void
590 gdk_window_broadway_restack_under (GdkWindow *window,
591                               GList *native_siblings /* in requested order, first is bottom-most */)
592 {
593 }
594
595 static void
596 gdk_window_broadway_restack_toplevel (GdkWindow *window,
597                                  GdkWindow *sibling,
598                                  gboolean   above)
599 {
600 }
601
602 static void
603 gdk_window_broadway_lower (GdkWindow *window)
604 {
605 }
606
607
608 void
609 gdk_window_focus (GdkWindow *window,
610                   guint32    timestamp)
611 {
612 }
613
614 void
615 gdk_window_set_type_hint (GdkWindow        *window,
616                           GdkWindowTypeHint hint)
617 {
618 }
619
620 GdkWindowTypeHint
621 gdk_window_get_type_hint (GdkWindow *window)
622 {
623   return GDK_WINDOW_TYPE_HINT_NORMAL;
624 }
625
626 void
627 gdk_window_set_modal_hint (GdkWindow *window,
628                            gboolean   modal)
629 {
630 }
631
632 void
633 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
634                                   gboolean   skips_taskbar)
635 {
636 }
637
638 void
639 gdk_window_set_skip_pager_hint (GdkWindow *window,
640                                 gboolean   skips_pager)
641 {
642 }
643
644 void
645 gdk_window_set_urgency_hint (GdkWindow *window,
646                              gboolean   urgent)
647 {
648 }
649
650 void
651 gdk_window_set_geometry_hints (GdkWindow         *window,
652                                const GdkGeometry *geometry,
653                                GdkWindowHints     geom_mask)
654 {
655 }
656
657 void
658 gdk_window_set_title (GdkWindow   *window,
659                       const gchar *title)
660 {
661 }
662
663 void
664 gdk_window_set_role (GdkWindow   *window,
665                      const gchar *role)
666 {
667 }
668
669 void
670 gdk_window_set_startup_id (GdkWindow   *window,
671                            const gchar *startup_id)
672 {
673 }
674
675 void
676 gdk_window_set_transient_for (GdkWindow *window,
677                               GdkWindow *parent)
678 {
679 }
680
681 static void
682 gdk_window_broadway_set_background (GdkWindow      *window,
683                                cairo_pattern_t *pattern)
684 {
685   return;
686 }
687
688 static void
689 gdk_window_broadway_set_device_cursor (GdkWindow *window,
690                                   GdkDevice *device,
691                                   GdkCursor *cursor)
692 {
693   GdkWindowObject *private;
694   GdkWindowImplBroadway *impl;
695
696   g_return_if_fail (GDK_IS_WINDOW (window));
697   g_return_if_fail (GDK_IS_DEVICE (device));
698
699   private = (GdkWindowObject *) window;
700   impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
701
702   if (!cursor)
703     g_hash_table_remove (impl->device_cursor, device);
704   else
705     {
706       _gdk_broadway_cursor_update_theme (cursor);
707       g_hash_table_replace (impl->device_cursor,
708                             device, gdk_cursor_ref (cursor));
709     }
710
711   if (!GDK_WINDOW_DESTROYED (window))
712     GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
713 }
714
715 GdkCursor *
716 _gdk_broadway_window_get_cursor (GdkWindow *window)
717 {
718   GdkWindowObject *private;
719   GdkWindowImplBroadway *impl;
720
721   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
722
723   private = (GdkWindowObject *)window;
724   impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
725
726   return impl->cursor;
727 }
728
729 static void
730 gdk_window_broadway_get_geometry (GdkWindow *window,
731                              gint      *x,
732                              gint      *y,
733                              gint      *width,
734                              gint      *height,
735                              gint      *depth)
736 {
737 }
738
739 static gint
740 gdk_window_broadway_get_root_coords (GdkWindow *window,
741                                 gint       x,
742                                 gint       y,
743                                 gint      *root_x,
744                                 gint      *root_y)
745 {
746   if (root_x)
747     *root_x = x;
748   if (root_y)
749     *root_y = y;
750
751   return 1;
752 }
753
754 void
755 gdk_window_get_root_origin (GdkWindow *window,
756                             gint      *x,
757                             gint      *y)
758 {
759   if (x)
760     *x = 0;
761
762   if (y)
763     *y = 0;
764 }
765
766 void
767 gdk_window_get_frame_extents (GdkWindow    *window,
768                               GdkRectangle *rect)
769 {
770   GdkWindowObject *private;
771
772   g_return_if_fail (rect != NULL);
773
774   private = (GdkWindowObject*) window;
775
776   rect->x = private->x;
777   rect->y = private->y;
778   rect->width = private->width;
779   rect->height = private->height;
780 }
781
782 void
783 _gdk_windowing_get_device_state (GdkDisplay       *display,
784                                  GdkDevice        *device,
785                                  GdkScreen       **screen,
786                                  gint             *x,
787                                  gint             *y,
788                                  GdkModifierType  *mask)
789 {
790   if (display->closed)
791     return;
792
793 }
794
795 static gboolean
796 gdk_window_broadway_get_device_state (GdkWindow       *window,
797                                  GdkDevice       *device,
798                                  gint            *x,
799                                  gint            *y,
800                                  GdkModifierType *mask)
801 {
802   return FALSE;
803 }
804
805 void
806 gdk_display_warp_pointer (GdkDisplay *display,
807                           GdkScreen  *screen,
808                           gint        x,
809                           gint        y)
810 {
811   GdkDevice *device;
812
813   g_return_if_fail (GDK_IS_DISPLAY (display));
814   g_return_if_fail (GDK_IS_SCREEN (screen));
815
816   device = display->core_pointer;
817   GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
818 }
819
820 void
821 gdk_display_warp_device (GdkDisplay *display,
822                          GdkDevice  *device,
823                          GdkScreen  *screen,
824                          gint        x,
825                          gint        y)
826 {
827   g_return_if_fail (GDK_IS_DISPLAY (display));
828   g_return_if_fail (GDK_IS_DEVICE (device));
829   g_return_if_fail (GDK_IS_SCREEN (screen));
830   g_return_if_fail (display == gdk_device_get_display (device));
831
832   GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
833 }
834
835 GdkWindow*
836 _gdk_windowing_window_at_device_position (GdkDisplay      *display,
837                                           GdkDevice       *device,
838                                           gint            *win_x,
839                                           gint            *win_y,
840                                           GdkModifierType *mask,
841                                           gboolean         get_toplevel)
842 {
843   GdkWindow *window;
844   GdkWindowObject *private;
845   GdkDisplayBroadway *display_broadway;
846   GdkScreen *screen;
847
848   display_broadway = GDK_DISPLAY_BROADWAY (display);
849   screen = gdk_display_get_screen (display, 0);
850   window = _gdk_window_find_child_at (gdk_screen_get_root_window (screen),
851                                       display_broadway->last_x,
852                                       display_broadway->last_y);
853
854   if (window != NULL)
855     {
856       private = (GdkWindowObject *)window;
857       *win_x = display_broadway->last_x - private->x;
858       *win_y = display_broadway->last_y - private->y;
859     }
860
861   return window;
862 }
863
864 static GdkEventMask
865 gdk_window_broadway_get_events (GdkWindow *window)
866 {
867   if (GDK_WINDOW_DESTROYED (window))
868     return 0;
869
870   return 0;
871 }
872 static void
873 gdk_window_broadway_set_events (GdkWindow    *window,
874                            GdkEventMask  event_mask)
875 {
876   if (!GDK_WINDOW_DESTROYED (window))
877     {
878     }
879 }
880
881 static void
882 gdk_window_broadway_shape_combine_region (GdkWindow       *window,
883                                      const cairo_region_t *shape_region,
884                                      gint             offset_x,
885                                      gint             offset_y)
886 {
887 }
888
889 static void
890 gdk_window_broadway_input_shape_combine_region (GdkWindow       *window,
891                                            const cairo_region_t *shape_region,
892                                            gint             offset_x,
893                                            gint             offset_y)
894 {
895 }
896
897
898 void
899 gdk_window_set_override_redirect (GdkWindow *window,
900                                   gboolean override_redirect)
901 {
902 }
903
904 void
905 gdk_window_set_accept_focus (GdkWindow *window,
906                              gboolean accept_focus)
907 {
908   GdkWindowObject *private;
909
910   private = (GdkWindowObject *)window;
911
912   accept_focus = accept_focus != FALSE;
913
914   if (private->accept_focus != accept_focus)
915     {
916       private->accept_focus = accept_focus;
917     }
918 }
919
920 void
921 gdk_window_set_focus_on_map (GdkWindow *window,
922                              gboolean focus_on_map)
923 {
924   GdkWindowObject *private;
925
926   private = (GdkWindowObject *)window;
927
928   focus_on_map = focus_on_map != FALSE;
929
930   if (private->focus_on_map != focus_on_map)
931     {
932       private->focus_on_map = focus_on_map;
933     }
934 }
935
936
937 void
938 gdk_window_set_icon_list (GdkWindow *window,
939                           GList     *pixbufs)
940 {
941 }
942
943 void
944 gdk_window_set_icon_name (GdkWindow   *window, 
945                           const gchar *name)
946 {
947   GdkDisplay *display;
948
949   if (GDK_WINDOW_DESTROYED (window) ||
950       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
951     return;
952
953   display = gdk_window_get_display (window);
954
955   g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
956                       GUINT_TO_POINTER (name != NULL));
957 }
958
959 void
960 gdk_window_iconify (GdkWindow *window)
961 {
962   if (GDK_WINDOW_DESTROYED (window) ||
963       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
964     return;
965 }
966
967 void
968 gdk_window_deiconify (GdkWindow *window)
969 {
970   if (GDK_WINDOW_DESTROYED (window) ||
971       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
972     return;
973 }
974
975 void
976 gdk_window_stick (GdkWindow *window)
977 {
978   if (GDK_WINDOW_DESTROYED (window) ||
979       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
980     return;
981
982 }
983
984 void
985 gdk_window_unstick (GdkWindow *window)
986 {
987   if (GDK_WINDOW_DESTROYED (window) ||
988       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
989     return;
990
991 }
992
993 void
994 gdk_window_maximize (GdkWindow *window)
995 {
996   if (GDK_WINDOW_DESTROYED (window) ||
997       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
998     return;
999
1000 }
1001
1002 void
1003 gdk_window_unmaximize (GdkWindow *window)
1004 {
1005   if (GDK_WINDOW_DESTROYED (window) ||
1006       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1007     return;
1008
1009 }
1010
1011 void
1012 gdk_window_fullscreen (GdkWindow *window)
1013 {
1014   if (GDK_WINDOW_DESTROYED (window) ||
1015       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1016     return;
1017
1018 }
1019
1020 void
1021 gdk_window_unfullscreen (GdkWindow *window)
1022 {
1023   if (GDK_WINDOW_DESTROYED (window) ||
1024       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1025     return;
1026
1027 }
1028
1029 void
1030 gdk_window_set_keep_above (GdkWindow *window,
1031                            gboolean   setting)
1032 {
1033   g_return_if_fail (GDK_IS_WINDOW (window));
1034
1035   if (GDK_WINDOW_DESTROYED (window) ||
1036       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1037     return;
1038
1039 }
1040
1041 void
1042 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
1043 {
1044   g_return_if_fail (GDK_IS_WINDOW (window));
1045
1046   if (GDK_WINDOW_DESTROYED (window) ||
1047       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1048     return;
1049
1050 }
1051
1052 GdkWindow *
1053 gdk_window_get_group (GdkWindow *window)
1054 {
1055   if (GDK_WINDOW_DESTROYED (window) ||
1056       !WINDOW_IS_TOPLEVEL (window))
1057     return NULL;
1058
1059   return window;
1060 }
1061
1062 void
1063 gdk_window_set_group (GdkWindow *window,
1064                       GdkWindow *leader)
1065 {
1066 }
1067
1068 void
1069 gdk_window_set_decorations (GdkWindow      *window,
1070                             GdkWMDecoration decorations)
1071 {
1072   if (GDK_WINDOW_DESTROYED (window) ||
1073       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1074     return;
1075
1076 }
1077
1078 gboolean
1079 gdk_window_get_decorations(GdkWindow       *window,
1080                            GdkWMDecoration *decorations)
1081 {
1082   gboolean result = FALSE;
1083
1084   if (GDK_WINDOW_DESTROYED (window) ||
1085       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1086     return FALSE;
1087
1088   return result;
1089 }
1090
1091 void
1092 gdk_window_set_functions (GdkWindow    *window,
1093                           GdkWMFunction functions)
1094 {
1095   g_return_if_fail (GDK_IS_WINDOW (window));
1096
1097   if (GDK_WINDOW_DESTROYED (window) ||
1098       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1099     return;
1100 }
1101
1102 cairo_region_t *
1103 _gdk_windowing_window_get_shape (GdkWindow *window)
1104 {
1105   return NULL;
1106 }
1107
1108 cairo_region_t *
1109 _gdk_windowing_window_get_input_shape (GdkWindow *window)
1110 {
1111   return NULL;
1112 }
1113
1114
1115 static gboolean
1116 gdk_window_broadway_set_static_gravities (GdkWindow *window,
1117                                      gboolean   use_static)
1118 {
1119   return TRUE;
1120 }
1121
1122 void
1123 gdk_window_begin_resize_drag (GdkWindow     *window,
1124                               GdkWindowEdge  edge,
1125                               gint           button,
1126                               gint           root_x,
1127                               gint           root_y,
1128                               guint32        timestamp)
1129 {
1130   if (GDK_WINDOW_DESTROYED (window) ||
1131       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1132     return;
1133
1134 }
1135
1136 void
1137 gdk_window_begin_move_drag (GdkWindow *window,
1138                             gint       button,
1139                             gint       root_x,
1140                             gint       root_y,
1141                             guint32    timestamp)
1142 {
1143   if (GDK_WINDOW_DESTROYED (window) ||
1144       !WINDOW_IS_TOPLEVEL (window))
1145     return;
1146
1147 }
1148
1149 void
1150 gdk_window_enable_synchronized_configure (GdkWindow *window)
1151 {
1152   GdkWindowObject *private = (GdkWindowObject *)window;
1153
1154   if (!GDK_IS_WINDOW_IMPL_BROADWAY (private->impl))
1155     return;
1156 }
1157
1158 void
1159 gdk_window_configure_finished (GdkWindow *window)
1160 {
1161   if (!WINDOW_IS_TOPLEVEL (window))
1162     return;
1163 }
1164
1165 void
1166 _gdk_windowing_window_beep (GdkWindow *window)
1167 {
1168   GdkDisplay *display;
1169
1170   g_return_if_fail (GDK_IS_WINDOW (window));
1171
1172   display = GDK_WINDOW_DISPLAY (window);
1173
1174   gdk_display_beep (display);
1175 }
1176
1177 void
1178 gdk_window_set_opacity (GdkWindow *window,
1179                         gdouble    opacity)
1180 {
1181   GdkDisplay *display;
1182
1183   g_return_if_fail (GDK_IS_WINDOW (window));
1184
1185   if (GDK_WINDOW_DESTROYED (window) ||
1186       !WINDOW_IS_TOPLEVEL (window))
1187     return;
1188
1189   display = gdk_window_get_display (window);
1190
1191   if (opacity < 0)
1192     opacity = 0;
1193   else if (opacity > 1)
1194     opacity = 1;
1195
1196 }
1197
1198 void
1199 _gdk_windowing_window_set_composited (GdkWindow *window,
1200                                       gboolean   composited)
1201 {
1202 }
1203
1204 void
1205 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
1206                                                cairo_region_t *region)
1207 {
1208   GdkWindowObject *private;
1209   GdkWindowImplBroadway *impl;
1210
1211   _gdk_window_process_updates_recurse (window, region);
1212
1213   private = (GdkWindowObject *)window;
1214   impl = GDK_WINDOW_IMPL_BROADWAY (private->impl);
1215   impl->dirty = TRUE;
1216   queue_dirty_flush (GDK_DISPLAY_BROADWAY (gdk_window_get_display (window)));
1217 }
1218
1219 void
1220 _gdk_windowing_before_process_all_updates (void)
1221 {
1222 }
1223
1224 void
1225 _gdk_windowing_after_process_all_updates (void)
1226 {
1227 }
1228
1229 gboolean
1230 _gdk_broadway_window_queue_antiexpose (GdkWindow *window,
1231                                   cairo_region_t *area)
1232 {
1233   return TRUE;
1234 }
1235
1236 static void
1237 copy_region (cairo_surface_t *surface,
1238              cairo_region_t *area,
1239              gint            dx,
1240              gint            dy)
1241 {
1242   cairo_t *cr;
1243
1244   cr = cairo_create (surface);
1245
1246   gdk_cairo_region (cr, area);
1247   cairo_clip (cr);
1248
1249   /* NB: This is a self-copy and Cairo doesn't support that yet.
1250    * So we do a litle trick.
1251    */
1252   cairo_push_group (cr);
1253
1254   cairo_set_source_surface (cr, surface, dx, dy);
1255   cairo_paint (cr);
1256
1257   cairo_pop_group_to_source (cr);
1258   cairo_paint (cr);
1259
1260   cairo_destroy (cr);
1261 }
1262
1263 void
1264 _gdk_broadway_window_translate (GdkWindow      *window,
1265                                 cairo_region_t *area,
1266                                 gint            dx,
1267                                 gint            dy)
1268 {
1269   GdkWindowObject *private;
1270   GdkDrawableImplBroadway *impl;
1271   GdkDisplayBroadway *display_broadway;
1272   int n_rects, i;
1273   BroadwayRect *rects;
1274   cairo_rectangle_int_t rect;
1275
1276   private = (GdkWindowObject *)window;
1277   impl = GDK_DRAWABLE_IMPL_BROADWAY (private->impl);
1278
1279   if (impl->surface)
1280     {
1281       copy_region (impl->surface, area, dx, dy);
1282       if (GDK_WINDOW_IMPL_BROADWAY (impl)->last_synced)
1283         {
1284           copy_region (impl->last_surface, area, dx, dy);
1285           n_rects = cairo_region_num_rectangles (area);
1286           rects = g_new (BroadwayRect, n_rects);
1287           for (i = 0; i < n_rects; i++)
1288             {
1289               cairo_region_get_rectangle (area, i, &rect);
1290               rects[i].x = rect.x;
1291               rects[i].y = rect.y;
1292               rects[i].width = rect.width;
1293               rects[i].height = rect.height;
1294             }
1295           display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
1296           broadway_client_copy_rectangles (display_broadway->output,
1297                                            GDK_WINDOW_IMPL_BROADWAY (impl)->id,
1298                                            rects, n_rects, dx, dy);
1299           queue_dirty_flush (display_broadway);
1300           g_free (rects);
1301         }
1302     }
1303 }
1304
1305 static void
1306 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
1307 {
1308   iface->show = gdk_window_broadway_show;
1309   iface->hide = gdk_window_broadway_hide;
1310   iface->withdraw = gdk_window_broadway_withdraw;
1311   iface->set_events = gdk_window_broadway_set_events;
1312   iface->get_events = gdk_window_broadway_get_events;
1313   iface->raise = gdk_window_broadway_raise;
1314   iface->lower = gdk_window_broadway_lower;
1315   iface->restack_under = gdk_window_broadway_restack_under;
1316   iface->restack_toplevel = gdk_window_broadway_restack_toplevel;
1317   iface->move_resize = gdk_window_broadway_move_resize;
1318   iface->set_background = gdk_window_broadway_set_background;
1319   iface->reparent = gdk_window_broadway_reparent;
1320   iface->set_device_cursor = gdk_window_broadway_set_device_cursor;
1321   iface->get_geometry = gdk_window_broadway_get_geometry;
1322   iface->get_root_coords = gdk_window_broadway_get_root_coords;
1323   iface->get_device_state = gdk_window_broadway_get_device_state;
1324   iface->shape_combine_region = gdk_window_broadway_shape_combine_region;
1325   iface->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
1326   iface->set_static_gravities = gdk_window_broadway_set_static_gravities;
1327   iface->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
1328   iface->translate = _gdk_broadway_window_translate;
1329   iface->destroy = _gdk_broadway_window_destroy;
1330   iface->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
1331 }