]> Pileus Git - ~andy/gtk/blob - gdk/gdkwindow.c
e509f3b37669f7c583d5002bd3fe4a45827bc384
[~andy/gtk] / gdk / gdkwindow.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include <config.h>
28 #include "gdkwindow.h"
29 #include "gdkinternals.h"
30 #include "gdk.h"                /* For gdk_rectangle_union() */
31 #include "gdkpixmap.h"
32 #include "gdkdrawable.h"
33 #include "gdkpixmap.h"
34 #include "gdkscreen.h"
35 #include "gdkalias.h"
36
37 #define USE_BACKING_STORE       /* Appears to work on Win32, too, now. */
38
39 typedef struct _GdkWindowPaint GdkWindowPaint;
40
41 struct _GdkWindowPaint
42 {
43   GdkRegion *region;
44   GdkPixmap *pixmap;
45   gint x_offset;
46   gint y_offset;
47 };
48
49 static GdkGC *gdk_window_create_gc      (GdkDrawable     *drawable,
50                                          GdkGCValues     *values,
51                                          GdkGCValuesMask  mask);
52 static void   gdk_window_draw_rectangle (GdkDrawable     *drawable,
53                                          GdkGC           *gc,
54                                          gboolean         filled,
55                                          gint             x,
56                                          gint             y,
57                                          gint             width,
58                                          gint             height);
59 static void   gdk_window_draw_arc       (GdkDrawable     *drawable,
60                                          GdkGC           *gc,
61                                          gboolean         filled,
62                                          gint             x,
63                                          gint             y,
64                                          gint             width,
65                                          gint             height,
66                                          gint             angle1,
67                                          gint             angle2);
68 static void   gdk_window_draw_polygon   (GdkDrawable     *drawable,
69                                          GdkGC           *gc,
70                                          gboolean         filled,
71                                          GdkPoint        *points,
72                                          gint             npoints);
73 static void   gdk_window_draw_text      (GdkDrawable     *drawable,
74                                          GdkFont         *font,
75                                          GdkGC           *gc,
76                                          gint             x,
77                                          gint             y,
78                                          const gchar     *text,
79                                          gint             text_length);
80 static void   gdk_window_draw_text_wc   (GdkDrawable     *drawable,
81                                          GdkFont         *font,
82                                          GdkGC           *gc,
83                                          gint             x,
84                                          gint             y,
85                                          const GdkWChar  *text,
86                                          gint             text_length);
87 static void   gdk_window_draw_drawable  (GdkDrawable     *drawable,
88                                          GdkGC           *gc,
89                                          GdkPixmap       *src,
90                                          gint             xsrc,
91                                          gint             ysrc,
92                                          gint             xdest,
93                                          gint             ydest,
94                                          gint             width,
95                                          gint             height);
96 static void   gdk_window_draw_points    (GdkDrawable     *drawable,
97                                          GdkGC           *gc,
98                                          GdkPoint        *points,
99                                          gint             npoints);
100 static void   gdk_window_draw_segments  (GdkDrawable     *drawable,
101                                          GdkGC           *gc,
102                                          GdkSegment      *segs,
103                                          gint             nsegs);
104 static void   gdk_window_draw_lines     (GdkDrawable     *drawable,
105                                          GdkGC           *gc,
106                                          GdkPoint        *points,
107                                          gint             npoints);
108
109 static void gdk_window_draw_glyphs             (GdkDrawable      *drawable,
110                                                 GdkGC            *gc,
111                                                 PangoFont        *font,
112                                                 gint              x,
113                                                 gint              y,
114                                                 PangoGlyphString *glyphs);
115 static void gdk_window_draw_glyphs_transformed (GdkDrawable      *drawable,
116                                                 GdkGC            *gc,
117                                                 PangoMatrix      *matrix,
118                                                 PangoFont        *font,
119                                                 gint              x,
120                                                 gint              y,
121                                                 PangoGlyphString *glyphs);
122
123 static void   gdk_window_draw_image     (GdkDrawable     *drawable,
124                                          GdkGC           *gc,
125                                          GdkImage        *image,
126                                          gint             xsrc,
127                                          gint             ysrc,
128                                          gint             xdest,
129                                          gint             ydest,
130                                          gint             width,
131                                          gint             height);
132
133 static void gdk_window_draw_pixbuf (GdkDrawable     *drawable,
134                                     GdkGC           *gc,
135                                     GdkPixbuf       *pixbuf,
136                                     gint             src_x,
137                                     gint             src_y,
138                                     gint             dest_x,
139                                     gint             dest_y,
140                                     gint             width,
141                                     gint             height,
142                                     GdkRgbDither     dither,
143                                     gint             x_dither,
144                                     gint             y_dither);
145
146 static void gdk_window_draw_trapezoids (GdkDrawable   *drawable,
147                                         GdkGC         *gc,
148                                         GdkTrapezoid  *trapezoids,
149                                         gint           n_trapezoids);
150
151 static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
152                                            GdkImage    *image,
153                                            gint         src_x,
154                                            gint         src_y,
155                                            gint         dest_x,
156                                            gint         dest_y,
157                                            gint         width,
158                                            gint         height);
159
160 static void gdk_window_set_cairo_target (GdkDrawable *drawable,
161                                          cairo_t     *cr);
162
163 static void   gdk_window_real_get_size  (GdkDrawable     *drawable,
164                                          gint            *width,
165                                          gint            *height);
166
167 static GdkVisual*   gdk_window_real_get_visual   (GdkDrawable *drawable);
168 static gint         gdk_window_real_get_depth    (GdkDrawable *drawable);
169 static GdkScreen*   gdk_window_real_get_screen   (GdkDrawable *drawable);
170 static void         gdk_window_real_set_colormap (GdkDrawable *drawable,
171                                                   GdkColormap *cmap);
172 static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
173
174 static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable,
175                                                        gint         x,
176                                                        gint         y,
177                                                        gint         width,
178                                                        gint         height,
179                                                        gint        *composite_x_offset,
180                                                        gint        *composite_y_offset);
181 static GdkRegion*   gdk_window_get_clip_region        (GdkDrawable *drawable);
182 static GdkRegion*   gdk_window_get_visible_region     (GdkDrawable *drawable);
183
184 static void gdk_window_free_paint_stack (GdkWindow *window);
185
186 static void gdk_window_init       (GdkWindowObject      *window);
187 static void gdk_window_class_init (GdkWindowObjectClass *klass);
188 static void gdk_window_finalize   (GObject              *object);
189 static void gdk_window_clear_backing_rect (GdkWindow *window,
190                                            gint       x,
191                                            gint       y,
192                                            gint       width,
193                                            gint       height);
194
195 static gpointer parent_class = NULL;
196
197 GType
198 gdk_window_object_get_type (void)
199 {
200   static GType object_type = 0;
201
202   if (!object_type)
203     {
204       static const GTypeInfo object_info =
205       {
206         sizeof (GdkWindowObjectClass),
207         (GBaseInitFunc) NULL,
208         (GBaseFinalizeFunc) NULL,
209         (GClassInitFunc) gdk_window_class_init,
210         NULL,           /* class_finalize */
211         NULL,           /* class_data */
212         sizeof (GdkWindowObject),
213         0,              /* n_preallocs */
214         (GInstanceInitFunc) gdk_window_init,
215       };
216       
217       object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
218                                             "GdkWindow",
219                                             &object_info, 0);
220     }
221   
222   return object_type;
223 }
224
225 static void
226 gdk_window_init (GdkWindowObject *window)
227 {
228   /* 0-initialization is good for all other fields. */
229
230   window->window_type = GDK_WINDOW_CHILD;
231
232   window->state = GDK_WINDOW_STATE_WITHDRAWN;
233   
234   window->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
235 }
236
237 static void
238 gdk_window_class_init (GdkWindowObjectClass *klass)
239 {
240   GObjectClass *object_class = G_OBJECT_CLASS (klass);
241   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
242   
243   parent_class = g_type_class_peek_parent (klass);
244
245   object_class->finalize = gdk_window_finalize;
246
247   drawable_class->create_gc = gdk_window_create_gc;
248   drawable_class->draw_rectangle = gdk_window_draw_rectangle;
249   drawable_class->draw_arc = gdk_window_draw_arc;
250   drawable_class->draw_polygon = gdk_window_draw_polygon;
251   drawable_class->draw_text = gdk_window_draw_text;
252   drawable_class->draw_text_wc = gdk_window_draw_text_wc;
253   drawable_class->draw_drawable = gdk_window_draw_drawable;
254   drawable_class->draw_points = gdk_window_draw_points;
255   drawable_class->draw_segments = gdk_window_draw_segments;
256   drawable_class->draw_lines = gdk_window_draw_lines;
257   drawable_class->draw_glyphs = gdk_window_draw_glyphs;
258   drawable_class->draw_glyphs_transformed = gdk_window_draw_glyphs_transformed;
259   drawable_class->draw_image = gdk_window_draw_image;
260   drawable_class->draw_pixbuf = gdk_window_draw_pixbuf;
261   drawable_class->draw_trapezoids = gdk_window_draw_trapezoids;
262   drawable_class->get_depth = gdk_window_real_get_depth;
263   drawable_class->get_screen = gdk_window_real_get_screen;
264   drawable_class->get_size = gdk_window_real_get_size;
265   drawable_class->set_colormap = gdk_window_real_set_colormap;
266   drawable_class->get_colormap = gdk_window_real_get_colormap;
267   drawable_class->get_visual = gdk_window_real_get_visual;
268   drawable_class->_copy_to_image = gdk_window_copy_to_image;
269   drawable_class->set_cairo_target = gdk_window_set_cairo_target;
270   drawable_class->get_clip_region = gdk_window_get_clip_region;
271   drawable_class->get_visible_region = gdk_window_get_visible_region;
272   drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
273 }
274
275 static void
276 gdk_window_finalize (GObject *object)
277 {
278   GdkWindow *window = GDK_WINDOW (object);
279   GdkWindowObject *obj = (GdkWindowObject *) object;
280   
281   if (!GDK_WINDOW_DESTROYED (window))
282     {
283       if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
284         {
285           g_warning ("losing last reference to undestroyed window\n");
286           _gdk_window_destroy (window, FALSE);
287         }
288       else
289         /* We use TRUE here, to keep us from actually calling
290          * XDestroyWindow() on the window
291          */
292         _gdk_window_destroy (window, TRUE);
293     }
294
295   g_object_unref (obj->impl);
296   obj->impl = NULL;
297   
298   G_OBJECT_CLASS (parent_class)->finalize (object);
299 }
300
301 static void
302 window_remove_filters (GdkWindow *window)
303 {
304   GdkWindowObject *obj = (GdkWindowObject*) window;
305
306   if (obj->filters)
307     {
308       GList *tmp_list;
309       
310       for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
311         g_free (tmp_list->data);
312     
313       g_list_free (obj->filters);
314       obj->filters = NULL;
315     }
316 }
317
318 /**
319  * _gdk_window_destroy_hierarchy:
320  * @window: a #GdkWindow
321  * @recursing: If TRUE, then this is being called because a parent
322  *            was destroyed. This generally means that the call to the 
323  *            windowing system to destroy the window can be omitted, since
324  *            it will be destroyed as a result of the parent being destroyed.
325  *            Unless @foreign_destroy.           
326  * @foreign_destroy: If TRUE, the window or a parent was destroyed by some 
327  *            external agency. The window has already been destroyed and no 
328  *            windowing system calls should be made. (This may never happen
329  *            for some windowing systems.)
330  *
331  * Internal function to destroy a window. Like gdk_window_destroy(),
332  * but does not drop the reference count created by gdk_window_new().
333  **/
334 static void
335 _gdk_window_destroy_hierarchy (GdkWindow *window,
336                                gboolean   recursing,
337                                gboolean   foreign_destroy)
338 {
339   GdkWindowObject *private;
340   GdkWindowObject *temp_private;
341   GdkWindow *temp_window;
342   GList *children;
343   GList *tmp;
344   
345   g_return_if_fail (window != NULL);
346   
347   private = (GdkWindowObject*) window;
348   
349   if (GDK_WINDOW_DESTROYED (window))
350     return;
351     
352   switch (GDK_WINDOW_TYPE (window))
353     {
354     case GDK_WINDOW_TOPLEVEL:
355     case GDK_WINDOW_CHILD:
356     case GDK_WINDOW_DIALOG:
357     case GDK_WINDOW_TEMP:
358     case GDK_WINDOW_FOREIGN:
359       if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_FOREIGN && !foreign_destroy)
360         {
361           /* Logically, it probably makes more sense to send
362            * a "destroy yourself" message to the foreign window
363            * whether or not it's in our heirarchy; but for historical
364            * reasons, we only send "destroy yourself" messages to
365            * foreign windows in our heirarchy.
366            */
367           if (private->parent)
368             _gdk_windowing_window_destroy_foreign (window);
369
370           /* Also for historical reasons, we remove any filters
371            * on a foreign window when it or a parent is destroyed;
372            * this likely causes problems if two separate portions
373            * of code are maintaining filter lists on a foreign window.
374            */
375           window_remove_filters (window);
376         }
377       else
378         {
379           private->state |= GDK_WINDOW_STATE_WITHDRAWN;
380           
381           if (private->parent)
382             {
383               GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
384               if (parent_private->children)
385                 parent_private->children = g_list_remove (parent_private->children, window);
386             }
387
388           _gdk_window_clear_update_area (window);
389           gdk_window_free_paint_stack (window);
390           
391           if (private->bg_pixmap &&
392               private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
393               private->bg_pixmap != GDK_NO_BG)
394             {
395               g_object_unref (private->bg_pixmap);
396               private->bg_pixmap = NULL;
397             }
398           
399           if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_FOREIGN)
400             g_assert (private->children == NULL);
401           else
402             {
403               children = tmp = private->children;
404               private->children = NULL;
405               
406               while (tmp)
407                 {
408                   temp_window = tmp->data;
409                   tmp = tmp->next;
410                   
411                   temp_private = (GdkWindowObject*) temp_window;
412                   if (temp_private)
413                     _gdk_window_destroy_hierarchy (temp_window,
414                                                    TRUE, foreign_destroy);
415                 }
416               
417               g_list_free (children);
418             }
419           
420           _gdk_windowing_window_destroy (window, recursing, foreign_destroy);
421           private->parent = NULL;
422           private->destroyed = TRUE;
423
424           window_remove_filters (window);
425
426           gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
427         }
428       break;
429       
430     case GDK_WINDOW_ROOT:
431       g_error ("attempted to destroy root window");
432       break;
433     }
434 }
435
436 /**
437  * _gdk_window_destroy:
438  * @window: a #GdkWindow
439  * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
440  *            external agency. The window has already been destroyed and no
441  *            windowing system calls should be made. (This may never happen
442  *            for some windowing systems.)
443  *
444  * Internal function to destroy a window. Like gdk_window_destroy(),
445  * but does not drop the reference count created by gdk_window_new().
446  **/
447 void
448 _gdk_window_destroy (GdkWindow *window,
449                      gboolean   foreign_destroy)
450 {
451   _gdk_window_destroy_hierarchy (window, FALSE, foreign_destroy);
452 }
453
454 /**
455  * gdk_window_destroy:
456  * @window: a #GdkWindow
457  *
458  * Destroys the window system resources associated with @window and decrements @window's
459  * reference count. The window system resources for all children of @window are also
460  * destroyed, but the children's reference counts are not decremented.
461  *
462  * Note that a window will not be destroyed automatically when its reference count
463  * reaches zero. You must call this function yourself before that happens.
464  *
465  **/
466 void
467 gdk_window_destroy (GdkWindow *window)
468 {
469   _gdk_window_destroy_hierarchy (window, FALSE, FALSE);
470   g_object_unref (window);
471 }
472
473 /**
474  * gdk_window_set_user_data:
475  * @window: a #GdkWindow
476  * @user_data: user data
477  *
478  * For most purposes this function is deprecated in favor of
479  * g_object_set_data(). However, for historical reasons GTK+ stores
480  * the #GtkWidget that owns a #GdkWindow as user data on the
481  * #GdkWindow. So, custom widget implementations should use
482  * this function for that. If GTK+ receives an event for a #GdkWindow,
483  * and the user data for the window is non-%NULL, GTK+ will assume the
484  * user data is a #GtkWidget, and forward the event to that widget.
485  * 
486  **/
487 void
488 gdk_window_set_user_data (GdkWindow *window,
489                           gpointer   user_data)
490 {
491   g_return_if_fail (window != NULL);
492   
493   ((GdkWindowObject*)window)->user_data = user_data;
494 }
495
496 /**
497  * gdk_window_get_user_data:
498  * @window: a #GdkWindow
499  * @data: return location for user data
500  *
501  * Retrieves the user data for @window, which is normally the widget
502  * that @window belongs to. See gdk_window_set_user_data().
503  * 
504  **/
505 void
506 gdk_window_get_user_data (GdkWindow *window,
507                           gpointer  *data)
508 {
509   g_return_if_fail (window != NULL);
510   
511   *data = ((GdkWindowObject*)window)->user_data;
512 }
513
514 /**
515  * gdk_window_get_window_type:
516  * @window: a #GdkWindow
517  * 
518  * Gets the type of the window. See #GdkWindowType.
519  * 
520  * Return value: type of window
521  **/
522 GdkWindowType
523 gdk_window_get_window_type (GdkWindow *window)
524 {
525   g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
526   
527   return GDK_WINDOW_TYPE (window);
528 }
529
530 /**
531  * gdk_window_get_position:
532  * @window: a #GdkWindow
533  * @x: X coordinate of window
534  * @y: Y coordinate of window
535  *
536  * Obtains the position of the window as reported in the
537  * most-recently-processed #GdkEventConfigure. Contrast with
538  * gdk_window_get_geometry() which queries the X server for the
539  * current window position, regardless of which events have been
540  * received or processed.
541  *
542  * The position coordinates are relative to the window's parent window.
543  * 
544  **/
545 void
546 gdk_window_get_position (GdkWindow *window,
547                          gint      *x,
548                          gint      *y)
549 {
550   GdkWindowObject *obj;
551   
552   g_return_if_fail (GDK_IS_WINDOW (window));
553   
554   obj = (GdkWindowObject*) window;
555   
556   if (x)
557     *x = obj->x;
558   if (y)
559     *y = obj->y;
560 }
561
562 /**
563  * gdk_window_get_parent:
564  * @window: a #GdkWindow
565  * 
566  * Obtains the parent of @window, as known to GDK. Does not query the
567  * X server; thus this returns the parent as passed to gdk_window_new(),
568  * not the actual parent. This should never matter unless you're using
569  * Xlib calls mixed with GDK calls on the X11 platform. It may also
570  * matter for toplevel windows, because the window manager may choose
571  * to reparent them.
572  * 
573  * Return value: parent of @window
574  **/
575 GdkWindow*
576 gdk_window_get_parent (GdkWindow *window)
577 {
578   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
579   
580   return (GdkWindow*) ((GdkWindowObject*) window)->parent;
581 }
582
583 /**
584  * gdk_window_get_toplevel:
585  * @window: a #GdkWindow
586  * 
587  * Gets the toplevel window that's an ancestor of @window.
588  * 
589  * Return value: the toplevel window containing @window
590  **/
591 GdkWindow*
592 gdk_window_get_toplevel (GdkWindow *window)
593 {
594   GdkWindowObject *obj;
595   
596   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
597
598   obj = (GdkWindowObject *)window;
599   while (GDK_WINDOW_TYPE (obj) == GDK_WINDOW_CHILD)
600     obj = (GdkWindowObject *)obj->parent;
601   
602   return GDK_WINDOW (obj);
603 }
604
605 /**
606  * gdk_window_get_children:
607  * @window: a #GdkWindow
608  * 
609  * Gets the list of children of @window known to GDK.
610  * This function only returns children created via GDK,
611  * so for example it's useless when used with the root window;
612  * it only returns windows an application created itself.
613  *
614  * The returned list must be freed, but the elements in the
615  * list need not be.
616  * 
617  * Return value: list of child windows inside @window
618  **/
619 GList*
620 gdk_window_get_children (GdkWindow *window)
621 {
622   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
623
624   if (GDK_WINDOW_DESTROYED (window))
625     return NULL;
626
627   return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
628 }
629
630 /**
631  * gdk_window_peek_children:
632  * @window: a #GdkWindow
633  * 
634  * Like gdk_window_get_children(), but does not copy the list of
635  * children, so the list does not need to be freed.
636  * 
637  * Return value: a reference to the list of child windows in @window
638  **/
639 GList *
640 gdk_window_peek_children (GdkWindow *window)
641 {
642   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
643
644   if (GDK_WINDOW_DESTROYED (window))
645     return NULL;
646
647   return GDK_WINDOW_OBJECT (window)->children;
648 }
649
650 /**
651  * gdk_window_add_filter:
652  * @window: a #GdkWindow
653  * @function: filter callback
654  * @data: data to pass to filter callback
655  *
656  * Adds an event filter to @window, allowing you to intercept events
657  * before they reach GDK. This is a low-level operation and makes it
658  * easy to break GDK and/or GTK+, so you have to know what you're
659  * doing. Pass %NULL for @window to get all events for all windows,
660  * instead of events for a specific window.
661  * 
662  **/
663 void          
664 gdk_window_add_filter (GdkWindow     *window,
665                        GdkFilterFunc  function,
666                        gpointer       data)
667 {
668   GdkWindowObject *private;
669   GList *tmp_list;
670   GdkEventFilter *filter;
671   
672   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
673
674   private = (GdkWindowObject*) window;
675   if (private && GDK_WINDOW_DESTROYED (window))
676     return;
677   
678   if (private)
679     tmp_list = private->filters;
680   else
681     tmp_list = _gdk_default_filters;
682   
683   while (tmp_list)
684     {
685       filter = (GdkEventFilter *)tmp_list->data;
686       if ((filter->function == function) && (filter->data == data))
687         return;
688       tmp_list = tmp_list->next;
689     }
690   
691   filter = g_new (GdkEventFilter, 1);
692   filter->function = function;
693   filter->data = data;
694   
695   if (private)
696     private->filters = g_list_append (private->filters, filter);
697   else
698     _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
699 }
700
701 /**
702  * gdk_window_remove_filter:
703  * @window: a #GdkWindow
704  * @function: previously-added filter function
705  * @data: user data for previously-added filter function
706  *
707  * Remove a filter previously added with gdk_window_add_filter().
708  * 
709  **/
710 void
711 gdk_window_remove_filter (GdkWindow     *window,
712                           GdkFilterFunc  function,
713                           gpointer       data)
714 {
715   GdkWindowObject *private;
716   GList *tmp_list, *node;
717   GdkEventFilter *filter;
718   
719   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
720
721   private = (GdkWindowObject*) window;
722   
723   if (private)
724     tmp_list = private->filters;
725   else
726     tmp_list = _gdk_default_filters;
727   
728   while (tmp_list)
729     {
730       filter = (GdkEventFilter *)tmp_list->data;
731       node = tmp_list;
732       tmp_list = tmp_list->next;
733       
734       if ((filter->function == function) && (filter->data == data))
735         {
736           if (private)
737             private->filters = g_list_remove_link (private->filters, node);
738           else
739             _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
740           g_list_free_1 (node);
741           g_free (filter);
742           
743           return;
744         }
745     }
746 }
747
748 /**
749  * gdk_screen_get_toplevel_windows:
750  * @screen: The #GdkScreen where the toplevels are located.
751  * 
752  * Obtains a list of all toplevel windows known to GDK on the screen @screen.
753  * A toplevel window is a child of the root window (see
754  * gdk_get_default_root_window()).
755  *
756  * The returned list should be freed with g_list_free(), but
757  * its elements need not be freed.
758  * 
759  * Return value: list of toplevel windows, free with g_list_free()
760  *
761  * Since: 2.2
762  **/
763 GList *
764 gdk_screen_get_toplevel_windows (GdkScreen *screen)
765 {
766   GdkWindow * root_window;
767   GList *new_list = NULL;
768   GList *tmp_list;
769   
770   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
771   
772   root_window = gdk_screen_get_root_window (screen);
773
774   tmp_list = ((GdkWindowObject *)root_window)->children;
775   while (tmp_list)
776     {
777       if (GDK_WINDOW_TYPE (tmp_list->data) != GDK_WINDOW_FOREIGN)
778         new_list = g_list_prepend (new_list, tmp_list->data);
779       tmp_list = tmp_list->next;
780     }
781   
782   return new_list;
783 }
784
785 /**
786  * gdk_window_get_toplevels:
787  * 
788  * Obtains a list of all toplevel windows known to GDK on the default
789  * screen (see gdk_window_get_toplevels_for_screen()).
790  * A toplevel window is a child of the root window (see
791  * gdk_get_default_root_window()).
792  *
793  * The returned list should be freed with g_list_free(), but
794  * its elements need not be freed.
795  * 
796  * Return value: list of toplevel windows, free with g_list_free()
797  **/
798 GList *
799 gdk_window_get_toplevels (void)
800 {
801   return gdk_screen_get_toplevel_windows (gdk_screen_get_default ());
802 }
803
804 /**
805  * gdk_window_is_visible:
806  * @window: a #GdkWindow
807  * 
808  * Checks whether the window has been mapped (with gdk_window_show() or
809  * gdk_window_show_unraised()).
810  * 
811  * Return value: %TRUE if the window is mapped
812  **/
813 gboolean 
814 gdk_window_is_visible (GdkWindow *window)
815 {
816   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
817   
818   return GDK_WINDOW_IS_MAPPED (window);
819 }
820
821 /**
822  * gdk_window_is_viewable:
823  * @window: a #GdkWindow
824  * 
825  * Check if the window and all ancestors of the window are
826  * mapped. (This is not necessarily "viewable" in the X sense, since
827  * we only check as far as we have GDK window parents, not to the root
828  * window.)
829  *
830  * Return value: %TRUE if the window is viewable
831  **/
832 gboolean 
833 gdk_window_is_viewable (GdkWindow *window)
834 {
835   GdkWindowObject *private = (GdkWindowObject *)window;
836   GdkScreen *screen;
837   GdkWindow *root_window;
838   
839   g_return_val_if_fail (window != NULL, FALSE);
840   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
841
842   screen = gdk_drawable_get_screen (window);
843   root_window = gdk_screen_get_root_window (screen);
844   
845   while (private && 
846          (private != (GdkWindowObject *)root_window) &&
847          (GDK_WINDOW_TYPE (private) != GDK_WINDOW_FOREIGN))
848     {
849       if (GDK_WINDOW_DESTROYED (private) || !GDK_WINDOW_IS_MAPPED (private))
850         return FALSE;
851       
852       private = (GdkWindowObject *)private->parent;
853     }
854   
855   return TRUE;
856 }
857
858 /**
859  * gdk_window_get_state:
860  * @window: a #GdkWindow
861  * 
862  * Gets the bitwise OR of the currently active window state flags,
863  * from the #GdkWindowState enumeration.
864  * 
865  * Return value: window state bitfield
866  **/
867 GdkWindowState
868 gdk_window_get_state (GdkWindow *window)
869 {
870   GdkWindowObject *private = (GdkWindowObject *)window;
871   
872   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
873   
874   return private->state;
875 }
876
877 /**
878  * gdk_window_begin_paint_rect:
879  * @window: a #GdkWindow
880  * @rectangle: rectangle you intend to draw to
881  *
882  * A convenience wrapper around gdk_window_begin_paint_region() which
883  * creates a rectangular region for you. See
884  * gdk_window_begin_paint_region() for details.
885  * 
886  **/
887 void
888 gdk_window_begin_paint_rect (GdkWindow    *window,
889                              GdkRectangle *rectangle)
890 {
891   GdkRegion *region;
892
893   g_return_if_fail (window != NULL);
894   g_return_if_fail (GDK_IS_WINDOW (window));
895
896   region = gdk_region_rectangle (rectangle);
897   gdk_window_begin_paint_region (window, region);
898   gdk_region_destroy (region);
899 }
900
901 #ifdef GDK_WINDOWING_X11
902 #include "x11/gdkx.h"
903 #endif
904
905 /**
906  * gdk_window_begin_paint_region:
907  * @window: a #GdkWindow
908  * @region: region you intend to draw to
909  *
910  * Indicates that you are beginning the process of redrawing @region.
911  * A backing store (offscreen buffer) large enough to contain @region
912  * will be created. The backing store will be initialized with the
913  * background color or background pixmap for @window. Then, all
914  * drawing operations performed on @window will be diverted to the
915  * backing store.  When you call gdk_window_end_paint(), the backing
916  * store will be copied to @window, making it visible onscreen. Only
917  * the part of @window contained in @region will be modified; that is,
918  * drawing operations are clipped to @region.
919  *
920  * The net result of all this is to remove flicker, because the user
921  * sees the finished product appear all at once when you call
922  * gdk_window_end_paint(). If you draw to @window directly without
923  * calling gdk_window_begin_paint_region(), the user may see flicker
924  * as individual drawing operations are performed in sequence.  The
925  * clipping and background-initializing features of
926  * gdk_window_begin_paint_region() are conveniences for the
927  * programmer, so you can avoid doing that work yourself.
928  *
929  * When using GTK+, the widget system automatically places calls to
930  * gdk_window_begin_paint_region() and gdk_window_end_paint() around
931  * emissions of the expose_event signal. That is, if you're writing an
932  * expose event handler, you can assume that the exposed area in
933  * #GdkEventExpose has already been cleared to the window background,
934  * is already set as the clip region, and already has a backing store.
935  * Therefore in most cases, application code need not call
936  * gdk_window_begin_paint_region(). (You can disable the automatic
937  * calls around expose events on a widget-by-widget basis by calling
938  * gtk_widget_set_double_buffered().)
939  *
940  * If you call this function multiple times before calling the
941  * matching gdk_window_end_paint(), the backing stores are pushed onto
942  * a stack. gdk_window_end_paint() copies the topmost backing store
943  * onscreen, subtracts the topmost region from all other regions in
944  * the stack, and pops the stack. All drawing operations affect only
945  * the topmost backing store in the stack. One matching call to
946  * gdk_window_end_paint() is required for each call to
947  * gdk_window_begin_paint_region().
948  * 
949  **/
950 void          
951 gdk_window_begin_paint_region (GdkWindow *window,
952                                GdkRegion *region)
953 {
954 #ifdef USE_BACKING_STORE
955   GdkWindowObject *private = (GdkWindowObject *)window;
956   GdkRectangle clip_box;
957   GdkWindowPaint *paint;
958   GSList *list;
959   
960   g_return_if_fail (window != NULL);
961   g_return_if_fail (GDK_IS_WINDOW (window));
962
963   if (GDK_WINDOW_DESTROYED (window))
964     return;
965
966   gdk_region_get_clipbox (region, &clip_box);
967
968   paint = g_new (GdkWindowPaint, 1);
969   paint->region = gdk_region_copy (region);
970   paint->x_offset = clip_box.x;
971   paint->y_offset = clip_box.y;
972   paint->pixmap =
973     gdk_pixmap_new (window,
974                     MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1);
975
976   for (list = private->paint_stack; list != NULL; list = list->next)
977     {
978       GdkWindowPaint *tmp_paint = list->data;
979
980       gdk_region_subtract (tmp_paint->region, paint->region);
981     }
982   
983   private->paint_stack = g_slist_prepend (private->paint_stack, paint);
984
985   if (!gdk_region_empty (region))
986     {
987       gdk_window_clear_backing_rect (window,
988                                      clip_box.x, clip_box.y,
989                                      clip_box.width, clip_box.height);
990     }
991 #endif /* USE_BACKING_STORE */
992 }
993
994 /**
995  * gdk_window_end_paint:
996  * @window: a #GdkWindow
997  *
998  * Indicates that the backing store created by the most recent call to
999  * gdk_window_begin_paint_region() should be copied onscreen and
1000  * deleted, leaving the next-most-recent backing store or no backing
1001  * store at all as the active paint region. See
1002  * gdk_window_begin_paint_region() for full details. It is an error to
1003  * call this function without a matching
1004  * gdk_window_begin_paint_region() first.
1005  * 
1006  **/
1007 void
1008 gdk_window_end_paint (GdkWindow *window)
1009 {
1010 #ifdef USE_BACKING_STORE
1011   GdkWindowObject *private = (GdkWindowObject *)window;
1012   GdkWindowPaint *paint;
1013   GdkGC *tmp_gc;
1014   GdkRectangle clip_box;
1015   gint x_offset, y_offset;
1016
1017   g_return_if_fail (window != NULL);
1018   g_return_if_fail (GDK_IS_WINDOW (window));
1019
1020   if (GDK_WINDOW_DESTROYED (window))
1021     return;
1022
1023   if (private->paint_stack == NULL)
1024     {
1025       g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
1026       return;
1027     }
1028
1029   paint = private->paint_stack->data;
1030   private->paint_stack = g_slist_delete_link (private->paint_stack, 
1031                                               private->paint_stack);
1032
1033   gdk_region_get_clipbox (paint->region, &clip_box);
1034
1035   tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE);
1036
1037   _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset);
1038
1039   gdk_gc_set_clip_region (tmp_gc, paint->region);
1040   gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset);
1041
1042   gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
1043                      clip_box.x - paint->x_offset,
1044                      clip_box.y - paint->y_offset,
1045                      clip_box.x - x_offset, clip_box.y - y_offset,
1046                      clip_box.width, clip_box.height);
1047
1048   /* Reset clip region of the cached GdkGC */
1049   gdk_gc_set_clip_region (tmp_gc, NULL);
1050   
1051   g_object_unref (paint->pixmap);
1052   gdk_region_destroy (paint->region);
1053   g_free (paint);
1054 #endif /* USE_BACKING_STORE */
1055 }
1056
1057 static void
1058 gdk_window_free_paint_stack (GdkWindow *window)
1059 {
1060   GdkWindowObject *private = (GdkWindowObject *)window;
1061   
1062   if (private->paint_stack)
1063     {
1064       GSList *tmp_list = private->paint_stack;
1065
1066       while (tmp_list)
1067         {
1068           GdkWindowPaint *paint = tmp_list->data;
1069
1070           if (tmp_list == private->paint_stack)
1071             g_object_unref (paint->pixmap);
1072                   
1073           gdk_region_destroy (paint->region);
1074           g_free (paint);
1075
1076           tmp_list = tmp_list->next;
1077         }
1078
1079       g_slist_free (private->paint_stack);
1080       private->paint_stack = NULL;
1081     }
1082 }
1083
1084 static void
1085 gdk_window_get_offsets (GdkWindow *window,
1086                         gint      *x_offset,
1087                         gint      *y_offset)
1088 {
1089   GdkWindowObject *private = (GdkWindowObject *)window;
1090   
1091   if (private->paint_stack)
1092     {
1093       GdkWindowPaint *paint = private->paint_stack->data;
1094       *x_offset = paint->x_offset;
1095       *y_offset = paint->y_offset;
1096     }
1097   else
1098     _gdk_windowing_window_get_offsets (window, x_offset, y_offset);
1099 }
1100
1101 /**
1102  * gdk_window_get_internal_paint_info:
1103  * @window: a #GdkWindow
1104  * @real_drawable: location to store the drawable to which drawing should be 
1105  *            done.
1106  * @x_offset: location to store the X offset between coordinates in @window,
1107  *            and the underlying window system primitive coordinates for 
1108  *            *@real_drawable.
1109  * @y_offset: location to store the Y offset between coordinates in @window,
1110  *            and the underlying window system primitive coordinates for
1111  *            *@real_drawable.
1112  * 
1113  * If you bypass the GDK layer and use windowing system primitives to
1114  * draw directly onto a #GdkWindow, then you need to deal with two
1115  * details: there may be an offset between GDK coordinates and windowing
1116  * system coordinates, and GDK may have redirected drawing to a offscreen
1117  * pixmap as the result of a gdk_window_begin_paint_region() calls.
1118  * This function allows retrieving the information you need to compensate
1119  * for these effects.
1120  *
1121  * This function exposes details of the GDK implementation, and is thus
1122  * likely to change in future releases of GDK.
1123  **/
1124 void
1125 gdk_window_get_internal_paint_info (GdkWindow    *window,
1126                                     GdkDrawable **real_drawable,
1127                                     gint         *x_offset,
1128                                     gint         *y_offset)
1129 {
1130   gint x_off, y_off;
1131   
1132   GdkWindowObject *private;
1133
1134   g_return_if_fail (GDK_IS_WINDOW (window));
1135
1136   private = (GdkWindowObject *)window;
1137
1138   if (real_drawable)
1139     {
1140       if (private->paint_stack)
1141         {
1142           GdkWindowPaint *paint = private->paint_stack->data;
1143           *real_drawable = paint->pixmap;
1144         }
1145       else
1146         *real_drawable = window;
1147     }
1148
1149   gdk_window_get_offsets (window, &x_off, &y_off);
1150
1151   if (x_offset)
1152     *x_offset = x_off;
1153   if (y_offset)
1154     *y_offset = y_off;
1155 }
1156
1157 #define OFFSET_GC(gc)                                         \
1158     gint x_offset, y_offset;                                  \
1159     gint old_clip_x = gc->clip_x_origin;    \
1160     gint old_clip_y = gc->clip_y_origin;    \
1161     gint old_ts_x = gc->ts_x_origin;        \
1162     gint old_ts_y = gc->ts_y_origin;        \
1163     gdk_window_get_offsets (drawable, &x_offset, &y_offset);  \
1164     if (x_offset != 0 || y_offset != 0)                       \
1165       {                                                       \
1166         gdk_gc_set_clip_origin (gc, old_clip_x - x_offset,    \
1167                                 old_clip_y - y_offset);       \
1168         gdk_gc_set_ts_origin (gc, old_ts_x - x_offset,        \
1169                               old_ts_y - y_offset);           \
1170       }
1171
1172 #define RESTORE_GC(gc)                                      \
1173     if (x_offset != 0 || y_offset != 0)                     \
1174      {                                                      \
1175        gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \
1176        gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y);       \
1177      }
1178
1179 static GdkGC *
1180 gdk_window_create_gc (GdkDrawable     *drawable,
1181                       GdkGCValues     *values,
1182                       GdkGCValuesMask  mask)
1183 {
1184   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
1185   
1186   if (GDK_WINDOW_DESTROYED (drawable))
1187     return NULL;
1188
1189   return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl,
1190                                  values, mask);
1191 }
1192
1193 static void
1194 gdk_window_draw_rectangle (GdkDrawable *drawable,
1195                            GdkGC       *gc,
1196                            gboolean     filled,
1197                            gint         x,
1198                            gint         y,
1199                            gint         width,
1200                            gint         height)
1201 {
1202   GdkWindowObject *private = (GdkWindowObject *)drawable;
1203   OFFSET_GC (gc);
1204
1205   if (GDK_WINDOW_DESTROYED (drawable))
1206     return;
1207   
1208   if (private->paint_stack)
1209     {
1210       GdkWindowPaint *paint = private->paint_stack->data;
1211       gdk_draw_rectangle (paint->pixmap, gc, filled,
1212                           x - x_offset, y - y_offset, width, height);
1213     }
1214   else
1215     gdk_draw_rectangle (private->impl, gc, filled,
1216                         x - x_offset, y - y_offset, width, height);
1217
1218   RESTORE_GC (gc);
1219 }
1220
1221 static void
1222 gdk_window_draw_arc (GdkDrawable *drawable,
1223                      GdkGC       *gc,
1224                      gboolean     filled,
1225                      gint         x,
1226                      gint         y,
1227                      gint         width,
1228                      gint         height,
1229                      gint         angle1,
1230                      gint         angle2)
1231 {
1232   GdkWindowObject *private = (GdkWindowObject *)drawable;
1233   OFFSET_GC (gc);
1234
1235   if (GDK_WINDOW_DESTROYED (drawable))
1236     return;
1237   
1238   if (private->paint_stack)
1239     {
1240       GdkWindowPaint *paint = private->paint_stack->data;
1241       gdk_draw_arc (paint->pixmap, gc, filled,
1242                     x - x_offset, y - y_offset,
1243                     width, height, angle1, angle2);
1244     }
1245   else
1246     gdk_draw_arc (private->impl, gc, filled,
1247                   x - x_offset, y - y_offset,
1248                   width, height, angle1, angle2);
1249   RESTORE_GC (gc);
1250 }
1251
1252 static void
1253 gdk_window_draw_polygon (GdkDrawable *drawable,
1254                          GdkGC       *gc,
1255                          gboolean     filled,
1256                          GdkPoint    *points,
1257                          gint         npoints)
1258 {
1259   GdkWindowObject *private = (GdkWindowObject *)drawable;
1260   GdkPoint *new_points;
1261   
1262   OFFSET_GC (gc);
1263
1264   if (GDK_WINDOW_DESTROYED (drawable))
1265     return;
1266   
1267   if (x_offset != 0 || y_offset != 0)
1268     {
1269       int i;
1270       
1271       new_points = g_new (GdkPoint, npoints);
1272       for (i=0; i<npoints; i++)
1273         {
1274           new_points[i].x = points[i].x - x_offset;
1275           new_points[i].y = points[i].y - y_offset;
1276         }
1277     }
1278   else
1279     new_points = points;
1280
1281   if (private->paint_stack)
1282     {
1283       GdkWindowPaint *paint = private->paint_stack->data;
1284       gdk_draw_polygon (paint->pixmap, gc, filled, new_points, npoints);
1285
1286     }
1287   else
1288     gdk_draw_polygon (private->impl, gc, filled, new_points, npoints);
1289   
1290   if (new_points != points)
1291     g_free (new_points);
1292
1293   RESTORE_GC (gc);
1294 }
1295
1296 static void
1297 gdk_window_draw_text (GdkDrawable *drawable,
1298                       GdkFont     *font,
1299                       GdkGC       *gc,
1300                       gint         x,
1301                       gint         y,
1302                       const gchar *text,
1303                       gint         text_length)
1304 {
1305   GdkWindowObject *private = (GdkWindowObject *)drawable;
1306   OFFSET_GC (gc);
1307
1308   if (GDK_WINDOW_DESTROYED (drawable))
1309     return;
1310   
1311   if (private->paint_stack)
1312     {
1313       GdkWindowPaint *paint = private->paint_stack->data;
1314       gdk_draw_text (paint->pixmap, font, gc, 
1315                      x - x_offset, y - y_offset, text, text_length);
1316
1317     }
1318   else
1319     gdk_draw_text (private->impl, font, gc,
1320                    x - x_offset, y - y_offset, text, text_length);
1321
1322   RESTORE_GC (gc);
1323 }
1324
1325 static void
1326 gdk_window_draw_text_wc (GdkDrawable    *drawable,
1327                          GdkFont        *font,
1328                          GdkGC          *gc,
1329                          gint            x,
1330                          gint            y,
1331                          const GdkWChar *text,
1332                          gint            text_length)
1333 {
1334   GdkWindowObject *private = (GdkWindowObject *)drawable;
1335   OFFSET_GC (gc);
1336
1337   if (GDK_WINDOW_DESTROYED (drawable))
1338     return;
1339   
1340   if (private->paint_stack)
1341     {
1342       GdkWindowPaint *paint = private->paint_stack->data;
1343       gdk_draw_text_wc (paint->pixmap, font, gc, 
1344                         x - x_offset, y - y_offset, text, text_length);
1345     }
1346   else
1347     gdk_draw_text_wc (private->impl, font, gc,
1348                       x - x_offset, y - y_offset, text, text_length);
1349   
1350   RESTORE_GC (gc);
1351 }
1352
1353 static GdkDrawable*
1354 gdk_window_get_composite_drawable (GdkDrawable *drawable,
1355                                    gint         x,
1356                                    gint         y,
1357                                    gint         width,
1358                                    gint         height,
1359                                    gint        *composite_x_offset,
1360                                    gint        *composite_y_offset)
1361 {
1362   GdkWindowObject *private = (GdkWindowObject *)drawable;
1363   GSList *list;
1364   GdkPixmap *tmp_pixmap;
1365   GdkRectangle rect;
1366   GdkGC *tmp_gc;
1367   gboolean overlap_buffer;
1368
1369   _gdk_windowing_window_get_offsets (drawable,
1370                                      composite_x_offset,
1371                                      composite_y_offset);
1372   
1373   if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
1374       || private->paint_stack == NULL)
1375     {
1376       /* No backing store */
1377       return g_object_ref (drawable);
1378     }
1379
1380   /* See if the buffered part is overlapping the part we want
1381    * to get
1382    */
1383   rect.x = x;
1384   rect.y = y;
1385   rect.width = width;
1386   rect.height = height;
1387
1388   overlap_buffer = FALSE;
1389   
1390   for (list = private->paint_stack; list != NULL; list = list->next)
1391     {
1392       GdkWindowPaint *paint = list->data;
1393       GdkOverlapType overlap;
1394
1395       overlap = gdk_region_rect_in (paint->region, &rect);
1396
1397       if (overlap == GDK_OVERLAP_RECTANGLE_IN)
1398         {
1399           *composite_x_offset = paint->x_offset;
1400           *composite_y_offset = paint->y_offset;
1401           
1402           return g_object_ref (paint->pixmap);
1403         }
1404       else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
1405         {
1406           overlap_buffer = TRUE;
1407           break;
1408         }
1409     }
1410
1411   if (!overlap_buffer)
1412     return g_object_ref (drawable);
1413
1414   tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1);
1415   tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE);
1416
1417   /* Copy the current window contents */
1418   gdk_draw_drawable (tmp_pixmap,
1419                      tmp_gc,
1420                      private->impl,
1421                      x - *composite_x_offset,
1422                      y - *composite_y_offset,
1423                      0, 0,
1424                      width, height);
1425
1426   /* paint the backing stores */
1427   for (list = private->paint_stack; list != NULL; list = list->next)
1428     {
1429       GdkWindowPaint *paint = list->data;
1430
1431       gdk_gc_set_clip_region (tmp_gc, paint->region);
1432       gdk_gc_set_clip_origin (tmp_gc, -x, -y);
1433       
1434       gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
1435                          x - paint->x_offset,
1436                          y - paint->y_offset,
1437                          0, 0, width, height);
1438     }
1439
1440   /* Reset clip region of the cached GdkGC */
1441   gdk_gc_set_clip_region (tmp_gc, NULL);
1442
1443   /* Set these to location of tmp_pixmap within the window */
1444   *composite_x_offset = x;
1445   *composite_y_offset = y;
1446
1447   return tmp_pixmap;
1448 }
1449
1450 static GdkRegion*
1451 gdk_window_get_clip_region (GdkDrawable *drawable)
1452 {
1453   GdkWindowObject *private = (GdkWindowObject *)drawable;
1454   GdkRegion *result;
1455
1456   result = gdk_drawable_get_clip_region (private->impl);
1457
1458   if (private->paint_stack)
1459     {
1460       GdkRegion *paint_region = gdk_region_new ();
1461       GSList *tmp_list = private->paint_stack;
1462
1463       while (tmp_list)
1464         {
1465           GdkWindowPaint *paint = tmp_list->data;
1466           
1467           gdk_region_union (paint_region, paint->region);
1468
1469           tmp_list = tmp_list->next;
1470         }
1471
1472       gdk_region_intersect (result, paint_region);
1473       gdk_region_destroy (paint_region);
1474     }
1475
1476   return result;
1477 }
1478
1479 static GdkRegion*
1480 gdk_window_get_visible_region (GdkDrawable *drawable)
1481 {
1482   GdkWindowObject *private = (GdkWindowObject*) drawable;
1483   
1484   return gdk_drawable_get_visible_region (private->impl);
1485 }
1486
1487 static void
1488 gdk_window_draw_drawable (GdkDrawable *drawable,
1489                           GdkGC       *gc,
1490                           GdkPixmap   *src,
1491                           gint         xsrc,
1492                           gint         ysrc,
1493                           gint         xdest,
1494                           gint         ydest,
1495                           gint         width,
1496                           gint         height)
1497 {
1498   GdkWindowObject *private = (GdkWindowObject *)drawable;
1499   OFFSET_GC (gc);
1500   
1501   if (GDK_WINDOW_DESTROYED (drawable))
1502     return;
1503
1504   /* If we have a backing pixmap draw to that */
1505   if (private->paint_stack)
1506     {
1507       GdkWindowPaint *paint = private->paint_stack->data;
1508       gdk_draw_drawable (paint->pixmap, gc,
1509                          src, xsrc, ysrc,
1510                          xdest - x_offset, ydest - y_offset, width, height);
1511
1512     }
1513   else
1514     gdk_draw_drawable (private->impl, gc,
1515                        src, xsrc, ysrc,
1516                        xdest - x_offset, ydest - y_offset,
1517                        width, height);
1518
1519   RESTORE_GC (gc);
1520 }
1521
1522 static void
1523 gdk_window_draw_points (GdkDrawable *drawable,
1524                         GdkGC       *gc,
1525                         GdkPoint    *points,
1526                         gint         npoints)
1527 {
1528   GdkWindowObject *private = (GdkWindowObject *)drawable;
1529   GdkPoint *new_points;
1530   
1531   OFFSET_GC (gc);
1532
1533   if (GDK_WINDOW_DESTROYED (drawable))
1534     return;
1535   
1536   if (x_offset != 0 || y_offset != 0)
1537     {
1538       gint i;
1539
1540       new_points = g_new (GdkPoint, npoints);
1541       for (i=0; i<npoints; i++)
1542         {
1543           new_points[i].x = points[i].x - x_offset;
1544           new_points[i].y = points[i].y - y_offset;
1545         }
1546     }
1547   else
1548     new_points = points;
1549
1550   if (private->paint_stack)
1551     {
1552       GdkWindowPaint *paint = private->paint_stack->data;
1553       gdk_draw_points (paint->pixmap, gc, new_points, npoints);
1554     }
1555   else
1556     gdk_draw_points (private->impl, gc, points, npoints);
1557
1558   if (new_points != points)
1559     g_free (new_points);
1560
1561   RESTORE_GC (gc);
1562 }
1563
1564 static void
1565 gdk_window_draw_segments (GdkDrawable *drawable,
1566                           GdkGC       *gc,
1567                           GdkSegment  *segs,
1568                           gint         nsegs)
1569 {
1570   GdkWindowObject *private = (GdkWindowObject *)drawable;
1571   GdkSegment *new_segs;
1572
1573   OFFSET_GC (gc);
1574
1575   if (GDK_WINDOW_DESTROYED (drawable))
1576     return;
1577   
1578   if (x_offset != 0 || y_offset != 0)
1579     {
1580       gint i;
1581
1582       new_segs = g_new (GdkSegment, nsegs);
1583       for (i=0; i<nsegs; i++)
1584         {
1585           new_segs[i].x1 = segs[i].x1 - x_offset;
1586           new_segs[i].y1 = segs[i].y1 - y_offset;
1587           new_segs[i].x2 = segs[i].x2 - x_offset;
1588           new_segs[i].y2 = segs[i].y2 - y_offset;
1589         }
1590     }
1591   else
1592     new_segs = segs;
1593
1594   if (private->paint_stack)
1595     {
1596       GdkWindowPaint *paint = private->paint_stack->data;
1597       gdk_draw_segments (paint->pixmap, gc, new_segs, nsegs);
1598     }
1599   else
1600     gdk_draw_segments (private->impl, gc, new_segs, nsegs);
1601   
1602   if (new_segs != segs)
1603     g_free (new_segs);
1604
1605   RESTORE_GC (gc);
1606 }
1607
1608 static void
1609 gdk_window_draw_lines (GdkDrawable *drawable,
1610                        GdkGC       *gc,
1611                        GdkPoint    *points,
1612                        gint         npoints)
1613 {
1614   GdkWindowObject *private = (GdkWindowObject *)drawable;
1615   GdkPoint *new_points;
1616
1617   OFFSET_GC (gc);
1618
1619   if (GDK_WINDOW_DESTROYED (drawable))
1620     return;
1621   
1622   if (x_offset != 0 || y_offset != 0)
1623     {
1624       gint i;
1625
1626       new_points = g_new (GdkPoint, npoints);
1627       for (i=0; i<npoints; i++)
1628         {
1629           new_points[i].x = points[i].x - x_offset;
1630           new_points[i].y = points[i].y - y_offset;
1631         }
1632     }
1633   else
1634     new_points = points;
1635
1636   if (private->paint_stack)
1637     {
1638       GdkWindowPaint *paint = private->paint_stack->data;
1639       gdk_draw_lines (paint->pixmap, gc, new_points, npoints);
1640     }
1641   else
1642     gdk_draw_lines (private->impl, gc, new_points, npoints);
1643
1644   if (new_points != points)
1645     g_free (new_points);
1646
1647   RESTORE_GC (gc);
1648 }
1649
1650 static void
1651 gdk_window_draw_glyphs (GdkDrawable      *drawable,
1652                         GdkGC            *gc,
1653                         PangoFont        *font,
1654                         gint              x,
1655                         gint              y,
1656                         PangoGlyphString *glyphs)
1657 {
1658   GdkWindowObject *private = (GdkWindowObject *)drawable;
1659
1660   OFFSET_GC (gc);
1661
1662   if (GDK_WINDOW_DESTROYED (drawable))
1663     return;
1664   
1665   if (private->paint_stack)
1666     {
1667       GdkWindowPaint *paint = private->paint_stack->data;
1668
1669       gdk_draw_glyphs (paint->pixmap, gc, font, x - x_offset, y - y_offset, glyphs);
1670     }
1671   else
1672     gdk_draw_glyphs (private->impl, gc, font,
1673                      x - x_offset, y - y_offset, glyphs);
1674
1675   RESTORE_GC (gc);
1676 }
1677
1678 static void
1679 gdk_window_draw_glyphs_transformed (GdkDrawable      *drawable,
1680                                     GdkGC            *gc,
1681                                     PangoMatrix      *matrix,
1682                                     PangoFont        *font,
1683                                     gint              x,
1684                                     gint              y,
1685                                     PangoGlyphString *glyphs)
1686 {
1687   GdkWindowObject *private = (GdkWindowObject *)drawable;
1688   PangoMatrix tmp_matrix;
1689
1690   OFFSET_GC (gc);
1691
1692   if (GDK_WINDOW_DESTROYED (drawable))
1693     return;
1694
1695   if (x_offset != 0 || y_offset != 0)
1696     {
1697       if (matrix)
1698         {
1699           tmp_matrix = *matrix;
1700           tmp_matrix.x0 -= x_offset;
1701           tmp_matrix.y0 -= y_offset;
1702           matrix = &tmp_matrix;
1703         }
1704       else
1705         {
1706           x -= x_offset * PANGO_SCALE;
1707           y -= y_offset * PANGO_SCALE;
1708         }
1709     }
1710   
1711   if (private->paint_stack)
1712     {
1713       GdkWindowPaint *paint = private->paint_stack->data;
1714
1715       gdk_draw_glyphs_transformed (paint->pixmap, gc, matrix, font, x, y, glyphs);
1716     }
1717   else
1718     gdk_draw_glyphs_transformed (private->impl, gc, matrix, font, x, y, glyphs);
1719
1720   RESTORE_GC (gc);
1721 }
1722
1723 static GdkGC *
1724 gdk_window_get_bg_gc (GdkWindow      *window,
1725                       GdkWindowPaint *paint)
1726 {
1727   GdkWindowObject *private = (GdkWindowObject *)window;
1728
1729   guint gc_mask = 0;
1730   GdkGCValues gc_values;
1731
1732   if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
1733     {
1734       GdkWindowPaint tmp_paint = *paint;
1735       tmp_paint.x_offset += private->x;
1736       tmp_paint.y_offset += private->y;
1737       
1738       return gdk_window_get_bg_gc (GDK_WINDOW (private->parent), &tmp_paint);
1739     }
1740   else if (private->bg_pixmap && 
1741            private->bg_pixmap != GDK_PARENT_RELATIVE_BG && 
1742            private->bg_pixmap != GDK_NO_BG)
1743     {
1744       gc_values.fill = GDK_TILED;
1745       gc_values.tile = private->bg_pixmap;
1746       
1747       gc_mask = GDK_GC_FILL | GDK_GC_TILE;
1748
1749       return gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask);
1750     }
1751   else
1752     {
1753       GdkGC *gc = _gdk_drawable_get_scratch_gc (paint->pixmap, FALSE);
1754
1755       gdk_gc_set_foreground (gc, &(private->bg_color));
1756
1757       return g_object_ref (gc);
1758     }
1759 }
1760
1761 static void
1762 gdk_window_clear_backing_rect (GdkWindow *window,
1763                                gint       x,
1764                                gint       y,
1765                                gint       width,
1766                                gint       height)
1767 {
1768   GdkWindowObject *private = (GdkWindowObject *)window;
1769   GdkWindowPaint *paint = private->paint_stack->data;
1770   GdkGC *tmp_gc;
1771
1772   if (GDK_WINDOW_DESTROYED (window))
1773     return;
1774
1775   tmp_gc = gdk_window_get_bg_gc (window, paint);
1776   gdk_gc_set_clip_region (tmp_gc, paint->region);
1777   
1778   gdk_draw_rectangle (window, tmp_gc, TRUE,
1779                       x, y, width, height);
1780
1781   gdk_gc_set_clip_region (tmp_gc, NULL);
1782   
1783   g_object_unref (tmp_gc);
1784 }
1785
1786 /**
1787  * gdk_window_clear:
1788  * @window: a #GdkWindow
1789  * 
1790  * Clears an entire @window to the background color or background pixmap.
1791  **/
1792 void
1793 gdk_window_clear (GdkWindow *window)
1794 {
1795   gint width, height;
1796   
1797   g_return_if_fail (window != NULL);
1798   g_return_if_fail (GDK_IS_WINDOW (window));
1799
1800   gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
1801   
1802   gdk_window_clear_area (window, 0, 0,
1803                          width, height);
1804 }
1805
1806 /**
1807  * gdk_window_clear_area:
1808  * @window: a #GdkWindow
1809  * @x: x coordinate of rectangle to clear
1810  * @y: y coordinate of rectangle to clear
1811  * @width: width of rectangle to clear
1812  * @height: height of rectangle to clear
1813  *
1814  * Clears an area of @window to the background color or background pixmap.
1815  * 
1816  **/
1817 void
1818 gdk_window_clear_area (GdkWindow *window,
1819                        gint       x,
1820                        gint       y,
1821                        gint       width,
1822                        gint       height)
1823 {
1824   GdkWindowObject *private = (GdkWindowObject *)window;
1825
1826   g_return_if_fail (window != NULL);
1827   g_return_if_fail (GDK_IS_WINDOW (window));
1828   
1829   if (private->paint_stack)
1830     gdk_window_clear_backing_rect (window, x, y, width, height);
1831   else
1832     _gdk_windowing_window_clear_area (window, x, y, width, height);
1833 }
1834
1835 /**
1836  * gdk_window_clear_area_e:
1837  * @window: a #GdkWindow
1838  * @x: x coordinate of rectangle to clear
1839  * @y: y coordinate of rectangle to clear
1840  * @width: width of rectangle to clear
1841  * @height: height of rectangle to clear
1842  *
1843  * Like gdk_window_clear_area(), but also generates an expose event for
1844  * the cleared area.
1845  *
1846  * This function has a stupid name because it dates back to the mists
1847  * time, pre-GDK-1.0.
1848  * 
1849  **/
1850 void
1851 gdk_window_clear_area_e (GdkWindow *window,
1852                          gint       x,
1853                          gint       y,
1854                          gint       width,
1855                          gint       height)
1856 {
1857   GdkWindowObject *private = (GdkWindowObject *)window;
1858
1859   g_return_if_fail (window != NULL);
1860   g_return_if_fail (GDK_IS_WINDOW (window));
1861   
1862   if (private->paint_stack)
1863     gdk_window_clear_backing_rect (window, x, y, width, height);
1864
1865   _gdk_windowing_window_clear_area_e (window, x, y, width, height);
1866 }
1867
1868 static void
1869 gdk_window_draw_image (GdkDrawable *drawable,
1870                        GdkGC       *gc,
1871                        GdkImage    *image,
1872                        gint         xsrc,
1873                        gint         ysrc,
1874                        gint         xdest,
1875                        gint         ydest,
1876                        gint         width,
1877                        gint         height)
1878 {
1879   GdkWindowObject *private = (GdkWindowObject *)drawable;
1880
1881   OFFSET_GC (gc);
1882
1883   if (GDK_WINDOW_DESTROYED (drawable))
1884     return;
1885   
1886   if (private->paint_stack)
1887     {
1888       GdkWindowPaint *paint = private->paint_stack->data;
1889       gdk_draw_image (paint->pixmap, gc, image, xsrc, ysrc,
1890                       xdest - x_offset, ydest - y_offset,
1891                       width, height);
1892
1893     }
1894   else
1895     gdk_draw_image (private->impl, gc, image, xsrc, ysrc,
1896                     xdest - x_offset, ydest - y_offset,
1897                     width, height);
1898
1899   RESTORE_GC (gc);
1900 }
1901
1902 static void
1903 gdk_window_draw_pixbuf (GdkDrawable     *drawable,
1904                         GdkGC           *gc,
1905                         GdkPixbuf       *pixbuf,
1906                         gint             src_x,
1907                         gint             src_y,
1908                         gint             dest_x,
1909                         gint             dest_y,
1910                         gint             width,
1911                         gint             height,
1912                         GdkRgbDither     dither,
1913                         gint             x_dither,
1914                         gint             y_dither)
1915 {
1916   GdkWindowObject *private = (GdkWindowObject *)drawable;
1917
1918   if (GDK_WINDOW_DESTROYED (drawable))
1919     return;
1920   
1921   if (gc)
1922     {
1923       OFFSET_GC (gc);
1924   
1925       if (private->paint_stack)
1926         {
1927           GdkWindowPaint *paint = private->paint_stack->data;
1928           gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y,
1929                            dest_x - x_offset, dest_y - y_offset,
1930                            width, height,
1931                            dither, x_dither - x_offset, y_dither - y_offset);
1932         }
1933       else
1934         gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y,
1935                          dest_x - x_offset, dest_y - y_offset,
1936                          width, height,
1937                          dither, x_dither, y_dither);
1938       
1939       RESTORE_GC (gc);
1940     }
1941   else
1942     {
1943       gint x_offset, y_offset;
1944       gdk_window_get_offsets (drawable, &x_offset, &y_offset);
1945       
1946       if (private->paint_stack)
1947         {
1948           GdkWindowPaint *paint = private->paint_stack->data;
1949           gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y,
1950                            dest_x - x_offset, dest_y - y_offset,
1951                            width, height,
1952                             dither, x_dither - x_offset, y_dither - y_offset);
1953         }
1954       else
1955         gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y,
1956                          dest_x - x_offset, dest_y - y_offset,
1957                          width, height,
1958                          dither, x_dither, y_dither);
1959     }
1960 }
1961
1962 static void
1963 gdk_window_draw_trapezoids (GdkDrawable   *drawable,
1964                             GdkGC         *gc,
1965                             GdkTrapezoid  *trapezoids,
1966                             gint           n_trapezoids)
1967 {
1968   GdkWindowObject *private = (GdkWindowObject *)drawable;
1969   GdkTrapezoid *new_trapezoids = NULL;
1970
1971   OFFSET_GC (gc);
1972
1973   if (GDK_WINDOW_DESTROYED (drawable))
1974     return;
1975   
1976   if (x_offset != 0 || y_offset != 0)
1977     {
1978       gint i;
1979
1980       new_trapezoids = g_new (GdkTrapezoid, n_trapezoids);
1981       for (i=0; i < n_trapezoids; i++)
1982         {
1983           new_trapezoids[i].y1 = trapezoids[i].y1 - y_offset;
1984           new_trapezoids[i].x11 = trapezoids[i].x11 - x_offset;
1985           new_trapezoids[i].x21 = trapezoids[i].x21 - x_offset;
1986           new_trapezoids[i].y2 = trapezoids[i].y2 - y_offset;
1987           new_trapezoids[i].x12 = trapezoids[i].x12 - x_offset;
1988           new_trapezoids[i].x22 = trapezoids[i].x22 - x_offset;
1989         }
1990
1991       trapezoids = new_trapezoids;
1992     }
1993
1994   if (private->paint_stack)
1995     {
1996       GdkWindowPaint *paint = private->paint_stack->data;
1997       gdk_draw_trapezoids (paint->pixmap, gc, trapezoids, n_trapezoids);
1998     }
1999   else
2000     gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids);
2001   
2002   if (new_trapezoids)
2003     g_free (new_trapezoids);
2004
2005   RESTORE_GC (gc);
2006 }
2007
2008 static void
2009 gdk_window_real_get_size (GdkDrawable *drawable,
2010                           gint *width,
2011                           gint *height)
2012 {
2013   g_return_if_fail (GDK_IS_WINDOW (drawable));
2014
2015   gdk_drawable_get_size (GDK_WINDOW_OBJECT (drawable)->impl,
2016                          width, height);
2017 }
2018
2019 static GdkVisual*
2020 gdk_window_real_get_visual (GdkDrawable *drawable)
2021 {
2022   GdkColormap *colormap;
2023
2024   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2025
2026   colormap = gdk_drawable_get_colormap (drawable);
2027   return colormap ? gdk_colormap_get_visual (colormap) : NULL;
2028 }
2029
2030 static gint
2031 gdk_window_real_get_depth (GdkDrawable *drawable)
2032 {
2033   g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
2034
2035   return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
2036 }
2037
2038 static GdkScreen*
2039 gdk_window_real_get_screen (GdkDrawable *drawable)
2040 {
2041   return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
2042 }
2043
2044 static void
2045 gdk_window_real_set_colormap (GdkDrawable *drawable,
2046                               GdkColormap *cmap)
2047 {
2048   g_return_if_fail (GDK_IS_WINDOW (drawable));  
2049
2050   if (GDK_WINDOW_DESTROYED (drawable))
2051     return;
2052   
2053   gdk_drawable_set_colormap (((GdkWindowObject*)drawable)->impl, cmap);
2054 }
2055
2056 static GdkColormap*
2057 gdk_window_real_get_colormap (GdkDrawable *drawable)
2058 {
2059   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2060
2061   if (GDK_WINDOW_DESTROYED (drawable))
2062     return NULL;
2063   
2064   return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
2065 }
2066                       
2067 static GdkImage*
2068 gdk_window_copy_to_image (GdkDrawable     *drawable,
2069                           GdkImage        *image,
2070                           gint             src_x,
2071                           gint             src_y,
2072                           gint             dest_x,
2073                           gint             dest_y,
2074                           gint             width,
2075                           gint             height)
2076 {
2077   gint x_offset, y_offset;
2078   
2079   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2080   
2081   if (GDK_WINDOW_DESTROYED (drawable))
2082     return NULL;
2083
2084   /* If we're here, a composite image was not necessary, so
2085    * we can ignore the paint stack.
2086    */
2087   
2088   _gdk_windowing_window_get_offsets (drawable, &x_offset, &y_offset);
2089   
2090   return gdk_drawable_copy_to_image (((GdkWindowObject*)drawable)->impl,
2091                                      image,
2092                                      src_x - x_offset,
2093                                      src_y - y_offset,
2094                                      dest_x, dest_y,
2095                                      width, height);
2096 }
2097
2098 static void
2099 gdk_window_set_cairo_target (GdkDrawable *drawable,
2100                              cairo_t     *cr)
2101 {
2102   GdkWindowObject *private = (GdkWindowObject*) drawable;
2103   gint x_offset, y_offset;
2104   
2105   gdk_window_get_offsets (GDK_WINDOW (drawable), &x_offset, &y_offset);
2106
2107   if (private->paint_stack)
2108     {
2109       GdkWindowPaint *paint = private->paint_stack->data;
2110       gdk_drawable_set_cairo_target (paint->pixmap, cr);
2111     }
2112   else
2113     gdk_drawable_set_cairo_target (private->impl, cr);
2114
2115   cairo_translate (cr, - x_offset, - y_offset);
2116 }
2117
2118 /* Code for dirty-region queueing
2119  */
2120 static GSList *update_windows = NULL;
2121 static guint update_idle = 0;
2122 static gboolean debug_updates = FALSE;
2123
2124 static gboolean
2125 gdk_window_update_idle (gpointer data)
2126 {
2127   GDK_THREADS_ENTER ();
2128   gdk_window_process_all_updates ();
2129   GDK_THREADS_LEAVE ();
2130   
2131   return FALSE;
2132 }
2133
2134 static void
2135 gdk_window_schedule_update (GdkWindow *window)
2136 {
2137   if (window && GDK_WINDOW_OBJECT (window)->update_freeze_count)
2138     return;
2139
2140   if (!update_idle)
2141     {
2142       update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
2143                                      gdk_window_update_idle, NULL, NULL);
2144     }
2145 }
2146
2147 static void
2148 gdk_window_process_updates_internal (GdkWindow *window)
2149 {
2150   GdkWindowObject *private = (GdkWindowObject *)window;
2151   gboolean save_region = FALSE;
2152
2153   /* If an update got queued during update processing, we can get a
2154    * window in the update queue that has an empty update_area.
2155    * just ignore it.
2156    */
2157   if (private->update_area)
2158     {
2159       GdkRegion *update_area = private->update_area;
2160       private->update_area = NULL;
2161       
2162       if (_gdk_event_func && gdk_window_is_viewable (window))
2163         {
2164           GdkRectangle window_rect;
2165           GdkRegion *expose_region;
2166           GdkRegion *window_region;
2167           gint width, height;
2168
2169           if (debug_updates)
2170             {
2171               /* Make sure we see the red invalid area before redrawing. */
2172               gdk_display_sync (gdk_drawable_get_display (window));
2173               g_usleep (70000);
2174             }
2175           
2176           save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
2177
2178           if (save_region)
2179             expose_region = gdk_region_copy (update_area);
2180           else
2181             expose_region = update_area;
2182           
2183           gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
2184
2185           window_rect.x = 0;
2186           window_rect.y = 0;
2187           window_rect.width = width;
2188           window_rect.height = height;
2189
2190           window_region = gdk_region_rectangle (&window_rect);
2191           gdk_region_intersect (expose_region,
2192                                 window_region);
2193           gdk_region_destroy (window_region);
2194           
2195           if (!gdk_region_empty (expose_region) &&
2196               (private->event_mask & GDK_EXPOSURE_MASK))
2197             {
2198               GdkEvent event;
2199               
2200               event.expose.type = GDK_EXPOSE;
2201               event.expose.window = g_object_ref (window);
2202               event.expose.count = 0;
2203               event.expose.region = expose_region;
2204               gdk_region_get_clipbox (expose_region, &event.expose.area);
2205               
2206               (*_gdk_event_func) (&event, _gdk_event_data);
2207               
2208               g_object_unref (window);
2209             }
2210
2211           if (expose_region != update_area)
2212             gdk_region_destroy (expose_region);
2213         }
2214       if (!save_region)
2215         gdk_region_destroy (update_area);
2216     }
2217 }
2218
2219 static void
2220 flush_all_displays (void)
2221 {
2222   GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
2223   GSList *tmp_list;
2224
2225   for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
2226     gdk_display_flush (tmp_list->data);
2227
2228   g_slist_free (displays);
2229 }
2230
2231 /**
2232  * gdk_window_process_all_updates:
2233  *
2234  * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
2235  * in the application.
2236  * 
2237  **/
2238 void
2239 gdk_window_process_all_updates (void)
2240 {
2241   GSList *old_update_windows = update_windows;
2242   GSList *tmp_list = update_windows;
2243
2244   if (update_idle)
2245     g_source_remove (update_idle);
2246   
2247   update_windows = NULL;
2248   update_idle = 0;
2249
2250   g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
2251   
2252   while (tmp_list)
2253     {
2254       GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
2255       
2256       if (private->update_freeze_count)
2257         update_windows = g_slist_prepend (update_windows, private);
2258       else
2259         gdk_window_process_updates_internal (tmp_list->data);
2260       
2261       g_object_unref (tmp_list->data);
2262       tmp_list = tmp_list->next;
2263     }
2264
2265   g_slist_free (old_update_windows);
2266
2267   flush_all_displays ();
2268 }
2269
2270 /**
2271  * gdk_window_process_updates:
2272  * @window: a #GdkWindow
2273  * @update_children: whether to also process updates for child windows
2274  *
2275  * Sends one or more expose events to @window. The areas in each 
2276  * expose event will cover the entire update area for the window (see
2277  * gdk_window_invalidate_region() for details). Normally GDK calls
2278  * gdk_window_process_all_updates() on your behalf, so there's no
2279  * need to call this function unless you want to force expose events
2280  * to be delivered immediately and synchronously (vs. the usual
2281  * case, where GDK delivers them in an idle handler). Occasionally
2282  * this is useful to produce nicer scrolling behavior, for example.
2283  * 
2284  **/
2285 void
2286 gdk_window_process_updates (GdkWindow *window,
2287                             gboolean   update_children)
2288 {
2289   GdkWindowObject *private = (GdkWindowObject *)window;
2290
2291   g_return_if_fail (window != NULL);
2292   g_return_if_fail (GDK_IS_WINDOW (window));
2293   
2294   if (private->update_area && !private->update_freeze_count)
2295     {      
2296       gdk_window_process_updates_internal (window);
2297       update_windows = g_slist_remove (update_windows, window);
2298     }
2299
2300   if (update_children)
2301     {
2302       GList *tmp_list = private->children;
2303       while (tmp_list)
2304         {
2305           gdk_window_process_updates (tmp_list->data, TRUE);
2306           tmp_list = tmp_list->next;
2307         }
2308     }
2309 }
2310
2311 /**
2312  * gdk_window_invalidate_rect:
2313  * @window: a #GdkWindow
2314  * @rect: rectangle to invalidate
2315  * @invalidate_children: whether to also invalidate child windows
2316  *
2317  * A convenience wrapper around gdk_window_invalidate_region() which
2318  * invalidates a rectangular region. See
2319  * gdk_window_invalidate_region() for details.
2320  * 
2321  **/
2322 void
2323 gdk_window_invalidate_rect   (GdkWindow    *window,
2324                               GdkRectangle *rect,
2325                               gboolean      invalidate_children)
2326 {
2327   GdkRectangle window_rect;
2328   GdkRegion *region;
2329   GdkWindowObject *private = (GdkWindowObject *)window;
2330
2331   g_return_if_fail (window != NULL);
2332   g_return_if_fail (GDK_IS_WINDOW (window));
2333
2334   if (GDK_WINDOW_DESTROYED (window))
2335     return;
2336   
2337   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
2338     return;
2339
2340   if (!rect)
2341     {
2342       window_rect.x = 0;
2343       window_rect.y = 0;
2344       gdk_drawable_get_size (GDK_DRAWABLE (window),
2345                              &window_rect.width,
2346                              &window_rect.height);
2347       rect = &window_rect;
2348     }
2349
2350   region = gdk_region_rectangle (rect);
2351   gdk_window_invalidate_region (window, region, invalidate_children);
2352   gdk_region_destroy (region);
2353 }
2354
2355 static void
2356 draw_ugly_color (GdkWindow *window,
2357                 GdkRegion *region)
2358 {
2359   /* Draw ugly color all over the newly-invalid region */
2360   GdkColor ugly_color = { 0, 50000, 10000, 10000 };
2361   GdkGC *ugly_gc;
2362   GdkRectangle clipbox;
2363     
2364   ugly_gc = gdk_gc_new (window);
2365   gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
2366   gdk_gc_set_clip_region (ugly_gc, region);
2367
2368   gdk_region_get_clipbox (region, &clipbox);
2369   
2370   gdk_draw_rectangle (window,
2371                       ugly_gc,
2372                       TRUE,
2373                       clipbox.x, clipbox.y,
2374                       clipbox.width, clipbox.height);
2375   
2376   g_object_unref (ugly_gc);
2377 }
2378
2379 /**
2380  * gdk_window_invalidate_maybe_recurse:
2381  * @window: a #GdkWindow
2382  * @region: a #GdkRegion
2383  * @child_func: function to use to decide if to recurse to a child,
2384  *              %NULL means never recurse.
2385  * @user_data: data passed to @child_func
2386  *
2387  * Adds @region to the update area for @window. The update area is the
2388  * region that needs to be redrawn, or "dirty region." The call
2389  * gdk_window_process_updates() sends one or more expose events to the
2390  * window, which together cover the entire update area. An
2391  * application would normally redraw the contents of @window in
2392  * response to those expose events.
2393  *
2394  * GDK will call gdk_window_process_all_updates() on your behalf
2395  * whenever your program returns to the main loop and becomes idle, so
2396  * normally there's no need to do that manually, you just need to
2397  * invalidate regions that you know should be redrawn.
2398  *
2399  * The @child_func parameter controls whether the region of
2400  * each child window that intersects @region will also be invalidated.
2401  * Only children for which @child_func returns TRUE will have the area
2402  * invalidated.
2403  **/
2404 void
2405 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
2406                                      GdkRegion *region,
2407                                      gboolean (*child_func) (GdkWindow *, gpointer),
2408                                      gpointer   user_data)
2409 {
2410   GdkWindowObject *private = (GdkWindowObject *)window;
2411   GdkRegion *visible_region;
2412
2413   g_return_if_fail (window != NULL);
2414   g_return_if_fail (GDK_IS_WINDOW (window));
2415
2416   if (GDK_WINDOW_DESTROYED (window))
2417     return;
2418   
2419   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
2420     return;
2421
2422   visible_region = gdk_drawable_get_visible_region (window);
2423   gdk_region_intersect (visible_region, region);
2424
2425   if (!gdk_region_empty (visible_region))
2426     {
2427       if (debug_updates)
2428         draw_ugly_color (window, region);
2429       
2430       if (private->update_area)
2431         {
2432           gdk_region_union (private->update_area, visible_region);
2433         }
2434       else
2435         {
2436           update_windows = g_slist_prepend (update_windows, window);
2437           private->update_area = gdk_region_copy (visible_region);
2438           
2439           gdk_window_schedule_update (window);
2440         }
2441       
2442       if (child_func)
2443         {
2444           GList *tmp_list;
2445           
2446           tmp_list = private->children;
2447           while (tmp_list)
2448             {
2449               GdkWindowObject *child = tmp_list->data;
2450               tmp_list = tmp_list->next;
2451
2452               if (!child->input_only && (*child_func) ((GdkWindow *)child, user_data))
2453                 {
2454                   GdkRegion *child_region;
2455                   gint x, y;
2456
2457                   gdk_window_get_position ((GdkWindow *)child, &x, &y);
2458
2459                   /* This copy could be saved with a little more complexity */
2460                   child_region = gdk_region_copy (visible_region);
2461                   gdk_region_offset (child_region, - x, - y);
2462                   
2463                   gdk_window_invalidate_maybe_recurse ((GdkWindow *)child, child_region, child_func, user_data);
2464                   
2465                   gdk_region_destroy (child_region);
2466                 }
2467             }
2468         }
2469     }
2470   
2471   gdk_region_destroy (visible_region);
2472 }
2473
2474 static gboolean
2475 true_predicate (GdkWindow *window,
2476                 gpointer   user_data)
2477 {
2478   return TRUE;
2479 }
2480
2481 /**
2482  * gdk_window_invalidate_region:
2483  * @window: a #GdkWindow
2484  * @region: a #GdkRegion
2485  * @invalidate_children: %TRUE to also invalidate child windows 
2486  *
2487  * Adds @region to the update area for @window. The update area is the
2488  * region that needs to be redrawn, or "dirty region." The call
2489  * gdk_window_process_updates() sends one or more expose events to the
2490  * window, which together cover the entire update area. An
2491  * application would normally redraw the contents of @window in
2492  * response to those expose events.
2493  *
2494  * GDK will call gdk_window_process_all_updates() on your behalf
2495  * whenever your program returns to the main loop and becomes idle, so
2496  * normally there's no need to do that manually, you just need to
2497  * invalidate regions that you know should be redrawn.
2498  *
2499  * The @invalidate_children parameter controls whether the region of
2500  * each child window that intersects @region will also be invalidated.
2501  * If %FALSE, then the update area for child windows will remain
2502  * unaffected. See gdk_window_invalidate_maybe_recurse if you need
2503  * fine grained control over which children are invalidated.
2504  **/
2505 void
2506 gdk_window_invalidate_region (GdkWindow *window,
2507                               GdkRegion *region,
2508                               gboolean   invalidate_children)
2509 {
2510   gdk_window_invalidate_maybe_recurse (window, region,
2511                                        invalidate_children ?
2512                                          true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
2513                                        NULL);
2514 }
2515
2516 /**
2517  * gdk_window_get_update_area:
2518  * @window: a #GdkWindow
2519  * 
2520  * Transfers ownership of the update area from @window to the caller
2521  * of the function. That is, after calling this function, @window will
2522  * no longer have an invalid/dirty region; the update area is removed
2523  * from @window and handed to you. If a window has no update area,
2524  * gdk_window_get_update_area() returns %NULL. You are responsible for
2525  * calling gdk_region_destroy() on the returned region if it's non-%NULL.
2526  * 
2527  * Return value: the update area for @window
2528  **/
2529 GdkRegion *
2530 gdk_window_get_update_area (GdkWindow *window)
2531 {
2532   GdkWindowObject *private = (GdkWindowObject *)window;
2533   GdkRegion *tmp_region;
2534
2535   g_return_val_if_fail (window != NULL, NULL);
2536   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2537
2538   if (private->update_area)
2539     {
2540       tmp_region = private->update_area;
2541       private->update_area = NULL;
2542
2543       update_windows = g_slist_remove (update_windows, window);
2544       
2545       return tmp_region;
2546     }
2547   else
2548     return NULL;
2549 }
2550
2551 /**
2552  * _gdk_window_clear_update_area:
2553  * @window: a #GdkWindow.
2554  * 
2555  * Internal function to clear the update area for a window. This
2556  * is called when the window is hidden or destroyed.
2557  **/
2558 void
2559 _gdk_window_clear_update_area (GdkWindow *window)
2560 {
2561   GdkWindowObject *private = (GdkWindowObject *)window;
2562
2563   g_return_if_fail (window != NULL);
2564   g_return_if_fail (GDK_IS_WINDOW (window));
2565
2566   if (private->update_area)
2567     {
2568       update_windows = g_slist_remove (update_windows, window);
2569       
2570       gdk_region_destroy (private->update_area);
2571       private->update_area = NULL;
2572     }
2573 }
2574
2575 /**
2576  * gdk_window_freeze_updates:
2577  * @window: a #GdkWindow
2578  * 
2579  * Temporarily freezes a window such that it won't receive expose
2580  * events.  The window will begin receiving expose events again when
2581  * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
2582  * has been called more than once, gdk_window_thaw_updates() must be called
2583  * an equal number of times to begin processing exposes.
2584  **/
2585 void
2586 gdk_window_freeze_updates (GdkWindow *window)
2587 {
2588   GdkWindowObject *private = (GdkWindowObject *)window;
2589
2590   g_return_if_fail (window != NULL);
2591   g_return_if_fail (GDK_IS_WINDOW (window));
2592
2593   private->update_freeze_count++;
2594 }
2595
2596 /**
2597  * gdk_window_thaw_updates:
2598  * @window: a #GdkWindow
2599  * 
2600  * Thaws a window frozen with gdk_window_freeze_updates().
2601  **/
2602 void
2603 gdk_window_thaw_updates (GdkWindow *window)
2604 {
2605   GdkWindowObject *private = (GdkWindowObject *)window;
2606
2607   g_return_if_fail (window != NULL);
2608   g_return_if_fail (GDK_IS_WINDOW (window));
2609   g_return_if_fail (private->update_freeze_count > 0);
2610
2611   if (--private->update_freeze_count == 0)
2612     gdk_window_schedule_update (window);
2613 }
2614
2615 /**
2616  * gdk_window_set_debug_updates:
2617  * @setting: %TRUE to turn on update debugging
2618  *
2619  * With update debugging enabled, calls to
2620  * gdk_window_invalidate_region() clear the invalidated region of the
2621  * screen to a noticeable color, and GDK pauses for a short time
2622  * before sending exposes to windows during
2623  * gdk_window_process_updates().  The net effect is that you can see
2624  * the invalid region for each window and watch redraws as they
2625  * occur. This allows you to diagnose inefficiencies in your application.
2626  *
2627  * In essence, because the GDK rendering model prevents all flicker,
2628  * if you are redrawing the same region 400 times you may never
2629  * notice, aside from noticing a speed problem. Enabling update
2630  * debugging causes GTK to flicker slowly and noticeably, so you can
2631  * see exactly what's being redrawn when, in what order.
2632  *
2633  * The --gtk-debug=updates command line option passed to GTK+ programs
2634  * enables this debug option at application startup time. That's
2635  * usually more useful than calling gdk_window_set_debug_updates()
2636  * yourself, though you might want to use this function to enable
2637  * updates sometime after application startup time.
2638  * 
2639  **/
2640 void
2641 gdk_window_set_debug_updates (gboolean setting)
2642 {
2643   debug_updates = setting;
2644 }
2645
2646 /**
2647  * gdk_window_constrain_size:
2648  * @geometry: a #GdkGeometry structure
2649  * @flags: a mask indicating what portions of @geometry are set
2650  * @width: desired width of window
2651  * @height: desired height of the window
2652  * @new_width: location to store resulting width
2653  * @new_height: location to store resulting height
2654  * 
2655  * Constrains a desired width and height according to a 
2656  * set of geometry hints (such as minimum and maximum size).
2657  */
2658 void
2659 gdk_window_constrain_size (GdkGeometry *geometry,
2660                            guint        flags,
2661                            gint         width,
2662                            gint         height,
2663                            gint        *new_width,
2664                            gint        *new_height)
2665 {
2666   /* This routine is partially borrowed from fvwm.
2667    *
2668    * Copyright 1993, Robert Nation
2669    *     You may use this code for any purpose, as long as the original
2670    *     copyright remains in the source code and all documentation
2671    *
2672    * which in turn borrows parts of the algorithm from uwm
2673    */
2674   gint min_width = 0;
2675   gint min_height = 0;
2676   gint base_width = 0;
2677   gint base_height = 0;
2678   gint xinc = 1;
2679   gint yinc = 1;
2680   gint max_width = G_MAXINT;
2681   gint max_height = G_MAXINT;
2682   
2683 #define FLOOR(value, base)      ( ((gint) ((value) / (base))) * (base) )
2684
2685   if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
2686     {
2687       base_width = geometry->base_width;
2688       base_height = geometry->base_height;
2689       min_width = geometry->min_width;
2690       min_height = geometry->min_height;
2691     }
2692   else if (flags & GDK_HINT_BASE_SIZE)
2693     {
2694       base_width = geometry->base_width;
2695       base_height = geometry->base_height;
2696       min_width = geometry->base_width;
2697       min_height = geometry->base_height;
2698     }
2699   else if (flags & GDK_HINT_MIN_SIZE)
2700     {
2701       base_width = geometry->min_width;
2702       base_height = geometry->min_height;
2703       min_width = geometry->min_width;
2704       min_height = geometry->min_height;
2705     }
2706
2707   if (flags & GDK_HINT_MAX_SIZE)
2708     {
2709       max_width = geometry->max_width ;
2710       max_height = geometry->max_height;
2711     }
2712
2713   if (flags & GDK_HINT_RESIZE_INC)
2714     {
2715       xinc = MAX (xinc, geometry->width_inc);
2716       yinc = MAX (yinc, geometry->height_inc);
2717     }
2718   
2719   /* clamp width and height to min and max values
2720    */
2721   width = CLAMP (width, min_width, max_width);
2722   height = CLAMP (height, min_height, max_height);
2723   
2724   /* shrink to base + N * inc
2725    */
2726   width = base_width + FLOOR (width - base_width, xinc);
2727   height = base_height + FLOOR (height - base_height, yinc);
2728
2729   /* constrain aspect ratio, according to:
2730    *
2731    *                width     
2732    * min_aspect <= -------- <= max_aspect
2733    *                height    
2734    */
2735   
2736   if (flags & GDK_HINT_ASPECT &&
2737       geometry->min_aspect > 0 &&
2738       geometry->max_aspect > 0)
2739     {
2740       gint delta;
2741
2742       if (geometry->min_aspect * height > width)
2743         {
2744           delta = FLOOR (height - width / geometry->min_aspect, yinc);
2745           if (height - delta >= min_height)
2746             height -= delta;
2747           else
2748             { 
2749               delta = FLOOR (height * geometry->min_aspect - width, xinc);
2750               if (width + delta <= max_width) 
2751                 width += delta;
2752             }
2753         }
2754       
2755       if (geometry->max_aspect * height < width)
2756         {
2757           delta = FLOOR (width - height * geometry->max_aspect, xinc);
2758           if (width - delta >= min_width) 
2759             width -= delta;
2760           else
2761             {
2762               delta = FLOOR (width / geometry->max_aspect - height, yinc);
2763               if (height + delta <= max_height)
2764                 height += delta;
2765             }
2766         }
2767     }
2768
2769 #undef FLOOR
2770   
2771   *new_width = width;
2772   *new_height = height;
2773 }
2774
2775 /**
2776  * gdk_window_get_pointer:
2777  * @window: a #GdkWindow
2778  * @x: return location for X coordinate of pointer
2779  * @y: return location for Y coordinate of pointer
2780  * @mask: return location for modifier mask
2781  *
2782  * Obtains the current pointer position and modifier state.
2783  * The position is given in coordinates relative to @window.
2784  * 
2785  * Return value: the window containing the pointer (as with
2786  * gdk_window_at_pointer()), or %NULL if the window containing the
2787  * pointer isn't known to GDK
2788  **/
2789 GdkWindow*
2790 gdk_window_get_pointer (GdkWindow         *window,
2791                         gint              *x,
2792                         gint              *y,
2793                         GdkModifierType   *mask)
2794 {
2795   GdkDisplay *display;
2796   gint tmp_x, tmp_y;
2797   GdkModifierType tmp_mask;
2798   GdkWindow *child;
2799   
2800   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2801
2802   if (window)
2803     {
2804       display = gdk_drawable_get_display (window);
2805     }
2806   else
2807     {
2808       GdkScreen *screen = gdk_screen_get_default ();
2809
2810       display = gdk_screen_get_display (screen);
2811       window = gdk_screen_get_root_window (screen);
2812       
2813       GDK_NOTE (MULTIHEAD,
2814                 g_message ("Passing NULL for window to gdk_window_get_pointer()\n"
2815                            "is not multihead safe"));
2816     }
2817
2818   child = display->pointer_hooks->window_get_pointer (display, window, &tmp_x, &tmp_y, &tmp_mask);
2819
2820   if (x)
2821     *x = tmp_x;
2822   if (y)
2823     *y = tmp_y;
2824   if (mask)
2825     *mask = tmp_mask;
2826
2827   return child;
2828 }
2829
2830 /**
2831  * gdk_window_at_pointer:
2832  * @win_x: return location for origin of the window under the pointer
2833  * @win_y: return location for origin of the window under the pointer
2834  * 
2835  * Obtains the window underneath the mouse pointer, returning the
2836  * location of that window in @win_x, @win_y. Returns %NULL if the
2837  * window under the mouse pointer is not known to GDK (if the window
2838  * belongs to another application and a #GdkWindow hasn't been created
2839  * for it with gdk_window_foreign_new())
2840  *
2841  * NOTE: For multihead-aware widgets or applications use
2842  * gdk_display_get_window_at_pointer() instead.
2843  * 
2844  * Return value: window under the mouse pointer
2845  **/
2846 GdkWindow*
2847 gdk_window_at_pointer (gint *win_x,
2848                        gint *win_y)
2849 {
2850   return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
2851 }
2852
2853 /**
2854  * gdk_get_default_root_window:
2855  * 
2856  * Obtains the root window (parent all other windows are inside)
2857  * for the default display and screen.
2858  * 
2859  * Return value: the default root window
2860  **/
2861 GdkWindow *
2862 gdk_get_default_root_window (void)
2863 {
2864   return gdk_screen_get_root_window (gdk_screen_get_default ());
2865 }
2866
2867 /**
2868  * gdk_window_foreign_new:
2869  * @anid: a native window handle.
2870  * 
2871  * Wraps a native window for the default display in a #GdkWindow.
2872  * This may fail if the window has been destroyed.
2873  *
2874  * For example in the X backend, a native window handle is an Xlib
2875  * <type>XID</type>.
2876  * 
2877  * Return value: the newly-created #GdkWindow wrapper for the 
2878  *    native window or %NULL if the window has been destroyed.
2879  **/
2880 GdkWindow *
2881 gdk_window_foreign_new (GdkNativeWindow anid)
2882 {
2883   return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
2884 }
2885
2886 #define __GDK_WINDOW_C__
2887 #include "gdkaliasdef.c"