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