]> Pileus Git - ~andy/gtk/blob - gdk/gdkwindow.c
Translation updated by Ivar Smolin.
[~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   cairo_surface_t *surface;
48 };
49
50 static GdkGC *gdk_window_create_gc      (GdkDrawable     *drawable,
51                                          GdkGCValues     *values,
52                                          GdkGCValuesMask  mask);
53 static void   gdk_window_draw_rectangle (GdkDrawable     *drawable,
54                                          GdkGC           *gc,
55                                          gboolean         filled,
56                                          gint             x,
57                                          gint             y,
58                                          gint             width,
59                                          gint             height);
60 static void   gdk_window_draw_arc       (GdkDrawable     *drawable,
61                                          GdkGC           *gc,
62                                          gboolean         filled,
63                                          gint             x,
64                                          gint             y,
65                                          gint             width,
66                                          gint             height,
67                                          gint             angle1,
68                                          gint             angle2);
69 static void   gdk_window_draw_polygon   (GdkDrawable     *drawable,
70                                          GdkGC           *gc,
71                                          gboolean         filled,
72                                          GdkPoint        *points,
73                                          gint             npoints);
74 static void   gdk_window_draw_text      (GdkDrawable     *drawable,
75                                          GdkFont         *font,
76                                          GdkGC           *gc,
77                                          gint             x,
78                                          gint             y,
79                                          const gchar     *text,
80                                          gint             text_length);
81 static void   gdk_window_draw_text_wc   (GdkDrawable     *drawable,
82                                          GdkFont         *font,
83                                          GdkGC           *gc,
84                                          gint             x,
85                                          gint             y,
86                                          const GdkWChar  *text,
87                                          gint             text_length);
88 static void   gdk_window_draw_drawable  (GdkDrawable     *drawable,
89                                          GdkGC           *gc,
90                                          GdkPixmap       *src,
91                                          gint             xsrc,
92                                          gint             ysrc,
93                                          gint             xdest,
94                                          gint             ydest,
95                                          gint             width,
96                                          gint             height);
97 static void   gdk_window_draw_points    (GdkDrawable     *drawable,
98                                          GdkGC           *gc,
99                                          GdkPoint        *points,
100                                          gint             npoints);
101 static void   gdk_window_draw_segments  (GdkDrawable     *drawable,
102                                          GdkGC           *gc,
103                                          GdkSegment      *segs,
104                                          gint             nsegs);
105 static void   gdk_window_draw_lines     (GdkDrawable     *drawable,
106                                          GdkGC           *gc,
107                                          GdkPoint        *points,
108                                          gint             npoints);
109
110 static void gdk_window_draw_glyphs             (GdkDrawable      *drawable,
111                                                 GdkGC            *gc,
112                                                 PangoFont        *font,
113                                                 gint              x,
114                                                 gint              y,
115                                                 PangoGlyphString *glyphs);
116 static void gdk_window_draw_glyphs_transformed (GdkDrawable      *drawable,
117                                                 GdkGC            *gc,
118                                                 PangoMatrix      *matrix,
119                                                 PangoFont        *font,
120                                                 gint              x,
121                                                 gint              y,
122                                                 PangoGlyphString *glyphs);
123
124 static void   gdk_window_draw_image     (GdkDrawable     *drawable,
125                                          GdkGC           *gc,
126                                          GdkImage        *image,
127                                          gint             xsrc,
128                                          gint             ysrc,
129                                          gint             xdest,
130                                          gint             ydest,
131                                          gint             width,
132                                          gint             height);
133
134 static void gdk_window_draw_pixbuf (GdkDrawable     *drawable,
135                                     GdkGC           *gc,
136                                     GdkPixbuf       *pixbuf,
137                                     gint             src_x,
138                                     gint             src_y,
139                                     gint             dest_x,
140                                     gint             dest_y,
141                                     gint             width,
142                                     gint             height,
143                                     GdkRgbDither     dither,
144                                     gint             x_dither,
145                                     gint             y_dither);
146
147 static void gdk_window_draw_trapezoids (GdkDrawable   *drawable,
148                                         GdkGC         *gc,
149                                         GdkTrapezoid  *trapezoids,
150                                         gint           n_trapezoids);
151
152 static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
153                                            GdkImage    *image,
154                                            gint         src_x,
155                                            gint         src_y,
156                                            gint         dest_x,
157                                            gint         dest_y,
158                                            gint         width,
159                                            gint         height);
160
161 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
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->ref_cairo_surface = gdk_window_ref_cairo_surface;
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   paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap);
977   cairo_surface_set_device_offset (paint->surface,
978                                    - paint->x_offset, - paint->y_offset);
979   
980   for (list = private->paint_stack; list != NULL; list = list->next)
981     {
982       GdkWindowPaint *tmp_paint = list->data;
983
984       gdk_region_subtract (tmp_paint->region, paint->region);
985     }
986   
987   private->paint_stack = g_slist_prepend (private->paint_stack, paint);
988
989   if (!gdk_region_empty (region))
990     {
991       gdk_window_clear_backing_rect (window,
992                                      clip_box.x, clip_box.y,
993                                      clip_box.width, clip_box.height);
994     }
995 #endif /* USE_BACKING_STORE */
996 }
997
998 /**
999  * gdk_window_end_paint:
1000  * @window: a #GdkWindow
1001  *
1002  * Indicates that the backing store created by the most recent call to
1003  * gdk_window_begin_paint_region() should be copied onscreen and
1004  * deleted, leaving the next-most-recent backing store or no backing
1005  * store at all as the active paint region. See
1006  * gdk_window_begin_paint_region() for full details. It is an error to
1007  * call this function without a matching
1008  * gdk_window_begin_paint_region() first.
1009  * 
1010  **/
1011 void
1012 gdk_window_end_paint (GdkWindow *window)
1013 {
1014 #ifdef USE_BACKING_STORE
1015   GdkWindowObject *private = (GdkWindowObject *)window;
1016   GdkWindowPaint *paint;
1017   GdkGC *tmp_gc;
1018   GdkRectangle clip_box;
1019   gint x_offset, y_offset;
1020
1021   g_return_if_fail (window != NULL);
1022   g_return_if_fail (GDK_IS_WINDOW (window));
1023
1024   if (GDK_WINDOW_DESTROYED (window))
1025     return;
1026
1027   if (private->paint_stack == NULL)
1028     {
1029       g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
1030       return;
1031     }
1032
1033   paint = private->paint_stack->data;
1034   private->paint_stack = g_slist_delete_link (private->paint_stack, 
1035                                               private->paint_stack);
1036
1037   gdk_region_get_clipbox (paint->region, &clip_box);
1038
1039   tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE);
1040
1041   _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset);
1042
1043   gdk_gc_set_clip_region (tmp_gc, paint->region);
1044   gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset);
1045
1046   gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
1047                      clip_box.x - paint->x_offset,
1048                      clip_box.y - paint->y_offset,
1049                      clip_box.x - x_offset, clip_box.y - y_offset,
1050                      clip_box.width, clip_box.height);
1051
1052   /* Reset clip region of the cached GdkGC */
1053   gdk_gc_set_clip_region (tmp_gc, NULL);
1054
1055   cairo_surface_destroy (paint->surface);
1056   g_object_unref (paint->pixmap);
1057   gdk_region_destroy (paint->region);
1058   g_free (paint);
1059 #endif /* USE_BACKING_STORE */
1060 }
1061
1062 static void
1063 gdk_window_free_paint_stack (GdkWindow *window)
1064 {
1065   GdkWindowObject *private = (GdkWindowObject *)window;
1066   
1067   if (private->paint_stack)
1068     {
1069       GSList *tmp_list = private->paint_stack;
1070
1071       while (tmp_list)
1072         {
1073           GdkWindowPaint *paint = tmp_list->data;
1074
1075           if (tmp_list == private->paint_stack)
1076             g_object_unref (paint->pixmap);
1077                   
1078           gdk_region_destroy (paint->region);
1079           g_free (paint);
1080
1081           tmp_list = tmp_list->next;
1082         }
1083
1084       g_slist_free (private->paint_stack);
1085       private->paint_stack = NULL;
1086     }
1087 }
1088
1089 static void
1090 gdk_window_get_offsets (GdkWindow *window,
1091                         gint      *x_offset,
1092                         gint      *y_offset)
1093 {
1094   GdkWindowObject *private = (GdkWindowObject *)window;
1095   
1096   if (private->paint_stack)
1097     {
1098       GdkWindowPaint *paint = private->paint_stack->data;
1099       *x_offset = paint->x_offset;
1100       *y_offset = paint->y_offset;
1101     }
1102   else
1103     _gdk_windowing_window_get_offsets (window, x_offset, y_offset);
1104 }
1105
1106 /**
1107  * gdk_window_get_internal_paint_info:
1108  * @window: a #GdkWindow
1109  * @real_drawable: location to store the drawable to which drawing should be 
1110  *            done.
1111  * @x_offset: location to store the X offset between coordinates in @window,
1112  *            and the underlying window system primitive coordinates for 
1113  *            *@real_drawable.
1114  * @y_offset: location to store the Y offset between coordinates in @window,
1115  *            and the underlying window system primitive coordinates for
1116  *            *@real_drawable.
1117  * 
1118  * If you bypass the GDK layer and use windowing system primitives to
1119  * draw directly onto a #GdkWindow, then you need to deal with two
1120  * details: there may be an offset between GDK coordinates and windowing
1121  * system coordinates, and GDK may have redirected drawing to a offscreen
1122  * pixmap as the result of a gdk_window_begin_paint_region() calls.
1123  * This function allows retrieving the information you need to compensate
1124  * for these effects.
1125  *
1126  * This function exposes details of the GDK implementation, and is thus
1127  * likely to change in future releases of GDK.
1128  **/
1129 void
1130 gdk_window_get_internal_paint_info (GdkWindow    *window,
1131                                     GdkDrawable **real_drawable,
1132                                     gint         *x_offset,
1133                                     gint         *y_offset)
1134 {
1135   gint x_off, y_off;
1136   
1137   GdkWindowObject *private;
1138
1139   g_return_if_fail (GDK_IS_WINDOW (window));
1140
1141   private = (GdkWindowObject *)window;
1142
1143   if (real_drawable)
1144     {
1145       if (private->paint_stack)
1146         {
1147           GdkWindowPaint *paint = private->paint_stack->data;
1148           *real_drawable = paint->pixmap;
1149         }
1150       else
1151         *real_drawable = window;
1152     }
1153
1154   gdk_window_get_offsets (window, &x_off, &y_off);
1155
1156   if (x_offset)
1157     *x_offset = x_off;
1158   if (y_offset)
1159     *y_offset = y_off;
1160 }
1161
1162 #define OFFSET_GC(gc)                                         \
1163     gint x_offset, y_offset;                                  \
1164     gint old_clip_x = gc->clip_x_origin;    \
1165     gint old_clip_y = gc->clip_y_origin;    \
1166     gint old_ts_x = gc->ts_x_origin;        \
1167     gint old_ts_y = gc->ts_y_origin;        \
1168     gdk_window_get_offsets (drawable, &x_offset, &y_offset);  \
1169     if (x_offset != 0 || y_offset != 0)                       \
1170       {                                                       \
1171         gdk_gc_set_clip_origin (gc, old_clip_x - x_offset,    \
1172                                 old_clip_y - y_offset);       \
1173         gdk_gc_set_ts_origin (gc, old_ts_x - x_offset,        \
1174                               old_ts_y - y_offset);           \
1175       }
1176
1177 #define RESTORE_GC(gc)                                      \
1178     if (x_offset != 0 || y_offset != 0)                     \
1179      {                                                      \
1180        gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \
1181        gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y);       \
1182      }
1183
1184 static GdkGC *
1185 gdk_window_create_gc (GdkDrawable     *drawable,
1186                       GdkGCValues     *values,
1187                       GdkGCValuesMask  mask)
1188 {
1189   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
1190   
1191   if (GDK_WINDOW_DESTROYED (drawable))
1192     return NULL;
1193
1194   return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl,
1195                                  values, mask);
1196 }
1197
1198 static void
1199 gdk_window_draw_rectangle (GdkDrawable *drawable,
1200                            GdkGC       *gc,
1201                            gboolean     filled,
1202                            gint         x,
1203                            gint         y,
1204                            gint         width,
1205                            gint         height)
1206 {
1207   GdkWindowObject *private = (GdkWindowObject *)drawable;
1208   OFFSET_GC (gc);
1209
1210   if (GDK_WINDOW_DESTROYED (drawable))
1211     return;
1212   
1213   if (private->paint_stack)
1214     {
1215       GdkWindowPaint *paint = private->paint_stack->data;
1216       gdk_draw_rectangle (paint->pixmap, gc, filled,
1217                           x - x_offset, y - y_offset, width, height);
1218     }
1219   else
1220     gdk_draw_rectangle (private->impl, gc, filled,
1221                         x - x_offset, y - y_offset, width, height);
1222
1223   RESTORE_GC (gc);
1224 }
1225
1226 static void
1227 gdk_window_draw_arc (GdkDrawable *drawable,
1228                      GdkGC       *gc,
1229                      gboolean     filled,
1230                      gint         x,
1231                      gint         y,
1232                      gint         width,
1233                      gint         height,
1234                      gint         angle1,
1235                      gint         angle2)
1236 {
1237   GdkWindowObject *private = (GdkWindowObject *)drawable;
1238   OFFSET_GC (gc);
1239
1240   if (GDK_WINDOW_DESTROYED (drawable))
1241     return;
1242   
1243   if (private->paint_stack)
1244     {
1245       GdkWindowPaint *paint = private->paint_stack->data;
1246       gdk_draw_arc (paint->pixmap, gc, filled,
1247                     x - x_offset, y - y_offset,
1248                     width, height, angle1, angle2);
1249     }
1250   else
1251     gdk_draw_arc (private->impl, gc, filled,
1252                   x - x_offset, y - y_offset,
1253                   width, height, angle1, angle2);
1254   RESTORE_GC (gc);
1255 }
1256
1257 static void
1258 gdk_window_draw_polygon (GdkDrawable *drawable,
1259                          GdkGC       *gc,
1260                          gboolean     filled,
1261                          GdkPoint    *points,
1262                          gint         npoints)
1263 {
1264   GdkWindowObject *private = (GdkWindowObject *)drawable;
1265   GdkPoint *new_points;
1266   
1267   OFFSET_GC (gc);
1268
1269   if (GDK_WINDOW_DESTROYED (drawable))
1270     return;
1271   
1272   if (x_offset != 0 || y_offset != 0)
1273     {
1274       int i;
1275       
1276       new_points = g_new (GdkPoint, npoints);
1277       for (i=0; i<npoints; i++)
1278         {
1279           new_points[i].x = points[i].x - x_offset;
1280           new_points[i].y = points[i].y - y_offset;
1281         }
1282     }
1283   else
1284     new_points = points;
1285
1286   if (private->paint_stack)
1287     {
1288       GdkWindowPaint *paint = private->paint_stack->data;
1289       gdk_draw_polygon (paint->pixmap, gc, filled, new_points, npoints);
1290
1291     }
1292   else
1293     gdk_draw_polygon (private->impl, gc, filled, new_points, npoints);
1294   
1295   if (new_points != points)
1296     g_free (new_points);
1297
1298   RESTORE_GC (gc);
1299 }
1300
1301 static void
1302 gdk_window_draw_text (GdkDrawable *drawable,
1303                       GdkFont     *font,
1304                       GdkGC       *gc,
1305                       gint         x,
1306                       gint         y,
1307                       const gchar *text,
1308                       gint         text_length)
1309 {
1310   GdkWindowObject *private = (GdkWindowObject *)drawable;
1311   OFFSET_GC (gc);
1312
1313   if (GDK_WINDOW_DESTROYED (drawable))
1314     return;
1315   
1316   if (private->paint_stack)
1317     {
1318       GdkWindowPaint *paint = private->paint_stack->data;
1319       gdk_draw_text (paint->pixmap, font, gc, 
1320                      x - x_offset, y - y_offset, text, text_length);
1321
1322     }
1323   else
1324     gdk_draw_text (private->impl, font, gc,
1325                    x - x_offset, y - y_offset, text, text_length);
1326
1327   RESTORE_GC (gc);
1328 }
1329
1330 static void
1331 gdk_window_draw_text_wc (GdkDrawable    *drawable,
1332                          GdkFont        *font,
1333                          GdkGC          *gc,
1334                          gint            x,
1335                          gint            y,
1336                          const GdkWChar *text,
1337                          gint            text_length)
1338 {
1339   GdkWindowObject *private = (GdkWindowObject *)drawable;
1340   OFFSET_GC (gc);
1341
1342   if (GDK_WINDOW_DESTROYED (drawable))
1343     return;
1344   
1345   if (private->paint_stack)
1346     {
1347       GdkWindowPaint *paint = private->paint_stack->data;
1348       gdk_draw_text_wc (paint->pixmap, font, gc, 
1349                         x - x_offset, y - y_offset, text, text_length);
1350     }
1351   else
1352     gdk_draw_text_wc (private->impl, font, gc,
1353                       x - x_offset, y - y_offset, text, text_length);
1354   
1355   RESTORE_GC (gc);
1356 }
1357
1358 static GdkDrawable*
1359 gdk_window_get_composite_drawable (GdkDrawable *drawable,
1360                                    gint         x,
1361                                    gint         y,
1362                                    gint         width,
1363                                    gint         height,
1364                                    gint        *composite_x_offset,
1365                                    gint        *composite_y_offset)
1366 {
1367   GdkWindowObject *private = (GdkWindowObject *)drawable;
1368   GSList *list;
1369   GdkPixmap *tmp_pixmap;
1370   GdkRectangle rect;
1371   GdkGC *tmp_gc;
1372   gboolean overlap_buffer;
1373
1374   _gdk_windowing_window_get_offsets (drawable,
1375                                      composite_x_offset,
1376                                      composite_y_offset);
1377   
1378   if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
1379       || private->paint_stack == NULL)
1380     {
1381       /* No backing store */
1382       return g_object_ref (drawable);
1383     }
1384
1385   /* See if the buffered part is overlapping the part we want
1386    * to get
1387    */
1388   rect.x = x;
1389   rect.y = y;
1390   rect.width = width;
1391   rect.height = height;
1392
1393   overlap_buffer = FALSE;
1394   
1395   for (list = private->paint_stack; list != NULL; list = list->next)
1396     {
1397       GdkWindowPaint *paint = list->data;
1398       GdkOverlapType overlap;
1399
1400       overlap = gdk_region_rect_in (paint->region, &rect);
1401
1402       if (overlap == GDK_OVERLAP_RECTANGLE_IN)
1403         {
1404           *composite_x_offset = paint->x_offset;
1405           *composite_y_offset = paint->y_offset;
1406           
1407           return g_object_ref (paint->pixmap);
1408         }
1409       else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
1410         {
1411           overlap_buffer = TRUE;
1412           break;
1413         }
1414     }
1415
1416   if (!overlap_buffer)
1417     return g_object_ref (drawable);
1418
1419   tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1);
1420   tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE);
1421
1422   /* Copy the current window contents */
1423   gdk_draw_drawable (tmp_pixmap,
1424                      tmp_gc,
1425                      private->impl,
1426                      x - *composite_x_offset,
1427                      y - *composite_y_offset,
1428                      0, 0,
1429                      width, height);
1430
1431   /* paint the backing stores */
1432   for (list = private->paint_stack; list != NULL; list = list->next)
1433     {
1434       GdkWindowPaint *paint = list->data;
1435
1436       gdk_gc_set_clip_region (tmp_gc, paint->region);
1437       gdk_gc_set_clip_origin (tmp_gc, -x, -y);
1438       
1439       gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
1440                          x - paint->x_offset,
1441                          y - paint->y_offset,
1442                          0, 0, width, height);
1443     }
1444
1445   /* Reset clip region of the cached GdkGC */
1446   gdk_gc_set_clip_region (tmp_gc, NULL);
1447
1448   /* Set these to location of tmp_pixmap within the window */
1449   *composite_x_offset = x;
1450   *composite_y_offset = y;
1451
1452   return tmp_pixmap;
1453 }
1454
1455 static GdkRegion*
1456 gdk_window_get_clip_region (GdkDrawable *drawable)
1457 {
1458   GdkWindowObject *private = (GdkWindowObject *)drawable;
1459   GdkRegion *result;
1460
1461   result = gdk_drawable_get_clip_region (private->impl);
1462
1463   if (private->paint_stack)
1464     {
1465       GdkRegion *paint_region = gdk_region_new ();
1466       GSList *tmp_list = private->paint_stack;
1467
1468       while (tmp_list)
1469         {
1470           GdkWindowPaint *paint = tmp_list->data;
1471           
1472           gdk_region_union (paint_region, paint->region);
1473
1474           tmp_list = tmp_list->next;
1475         }
1476
1477       gdk_region_intersect (result, paint_region);
1478       gdk_region_destroy (paint_region);
1479     }
1480
1481   return result;
1482 }
1483
1484 static GdkRegion*
1485 gdk_window_get_visible_region (GdkDrawable *drawable)
1486 {
1487   GdkWindowObject *private = (GdkWindowObject*) drawable;
1488   
1489   return gdk_drawable_get_visible_region (private->impl);
1490 }
1491
1492 static void
1493 gdk_window_draw_drawable (GdkDrawable *drawable,
1494                           GdkGC       *gc,
1495                           GdkPixmap   *src,
1496                           gint         xsrc,
1497                           gint         ysrc,
1498                           gint         xdest,
1499                           gint         ydest,
1500                           gint         width,
1501                           gint         height)
1502 {
1503   GdkWindowObject *private = (GdkWindowObject *)drawable;
1504   OFFSET_GC (gc);
1505   
1506   if (GDK_WINDOW_DESTROYED (drawable))
1507     return;
1508
1509   /* If we have a backing pixmap draw to that */
1510   if (private->paint_stack)
1511     {
1512       GdkWindowPaint *paint = private->paint_stack->data;
1513       gdk_draw_drawable (paint->pixmap, gc,
1514                          src, xsrc, ysrc,
1515                          xdest - x_offset, ydest - y_offset, width, height);
1516
1517     }
1518   else
1519     gdk_draw_drawable (private->impl, gc,
1520                        src, xsrc, ysrc,
1521                        xdest - x_offset, ydest - y_offset,
1522                        width, height);
1523
1524   RESTORE_GC (gc);
1525 }
1526
1527 static void
1528 gdk_window_draw_points (GdkDrawable *drawable,
1529                         GdkGC       *gc,
1530                         GdkPoint    *points,
1531                         gint         npoints)
1532 {
1533   GdkWindowObject *private = (GdkWindowObject *)drawable;
1534   GdkPoint *new_points;
1535   
1536   OFFSET_GC (gc);
1537
1538   if (GDK_WINDOW_DESTROYED (drawable))
1539     return;
1540   
1541   if (x_offset != 0 || y_offset != 0)
1542     {
1543       gint i;
1544
1545       new_points = g_new (GdkPoint, npoints);
1546       for (i=0; i<npoints; i++)
1547         {
1548           new_points[i].x = points[i].x - x_offset;
1549           new_points[i].y = points[i].y - y_offset;
1550         }
1551     }
1552   else
1553     new_points = points;
1554
1555   if (private->paint_stack)
1556     {
1557       GdkWindowPaint *paint = private->paint_stack->data;
1558       gdk_draw_points (paint->pixmap, gc, new_points, npoints);
1559     }
1560   else
1561     gdk_draw_points (private->impl, gc, points, npoints);
1562
1563   if (new_points != points)
1564     g_free (new_points);
1565
1566   RESTORE_GC (gc);
1567 }
1568
1569 static void
1570 gdk_window_draw_segments (GdkDrawable *drawable,
1571                           GdkGC       *gc,
1572                           GdkSegment  *segs,
1573                           gint         nsegs)
1574 {
1575   GdkWindowObject *private = (GdkWindowObject *)drawable;
1576   GdkSegment *new_segs;
1577
1578   OFFSET_GC (gc);
1579
1580   if (GDK_WINDOW_DESTROYED (drawable))
1581     return;
1582   
1583   if (x_offset != 0 || y_offset != 0)
1584     {
1585       gint i;
1586
1587       new_segs = g_new (GdkSegment, nsegs);
1588       for (i=0; i<nsegs; i++)
1589         {
1590           new_segs[i].x1 = segs[i].x1 - x_offset;
1591           new_segs[i].y1 = segs[i].y1 - y_offset;
1592           new_segs[i].x2 = segs[i].x2 - x_offset;
1593           new_segs[i].y2 = segs[i].y2 - y_offset;
1594         }
1595     }
1596   else
1597     new_segs = segs;
1598
1599   if (private->paint_stack)
1600     {
1601       GdkWindowPaint *paint = private->paint_stack->data;
1602       gdk_draw_segments (paint->pixmap, gc, new_segs, nsegs);
1603     }
1604   else
1605     gdk_draw_segments (private->impl, gc, new_segs, nsegs);
1606   
1607   if (new_segs != segs)
1608     g_free (new_segs);
1609
1610   RESTORE_GC (gc);
1611 }
1612
1613 static void
1614 gdk_window_draw_lines (GdkDrawable *drawable,
1615                        GdkGC       *gc,
1616                        GdkPoint    *points,
1617                        gint         npoints)
1618 {
1619   GdkWindowObject *private = (GdkWindowObject *)drawable;
1620   GdkPoint *new_points;
1621
1622   OFFSET_GC (gc);
1623
1624   if (GDK_WINDOW_DESTROYED (drawable))
1625     return;
1626   
1627   if (x_offset != 0 || y_offset != 0)
1628     {
1629       gint i;
1630
1631       new_points = g_new (GdkPoint, npoints);
1632       for (i=0; i<npoints; i++)
1633         {
1634           new_points[i].x = points[i].x - x_offset;
1635           new_points[i].y = points[i].y - y_offset;
1636         }
1637     }
1638   else
1639     new_points = points;
1640
1641   if (private->paint_stack)
1642     {
1643       GdkWindowPaint *paint = private->paint_stack->data;
1644       gdk_draw_lines (paint->pixmap, gc, new_points, npoints);
1645     }
1646   else
1647     gdk_draw_lines (private->impl, gc, new_points, npoints);
1648
1649   if (new_points != points)
1650     g_free (new_points);
1651
1652   RESTORE_GC (gc);
1653 }
1654
1655 static void
1656 gdk_window_draw_glyphs (GdkDrawable      *drawable,
1657                         GdkGC            *gc,
1658                         PangoFont        *font,
1659                         gint              x,
1660                         gint              y,
1661                         PangoGlyphString *glyphs)
1662 {
1663   GdkWindowObject *private = (GdkWindowObject *)drawable;
1664
1665   OFFSET_GC (gc);
1666
1667   if (GDK_WINDOW_DESTROYED (drawable))
1668     return;
1669   
1670   if (private->paint_stack)
1671     {
1672       GdkWindowPaint *paint = private->paint_stack->data;
1673
1674       gdk_draw_glyphs (paint->pixmap, gc, font, x - x_offset, y - y_offset, glyphs);
1675     }
1676   else
1677     gdk_draw_glyphs (private->impl, gc, font,
1678                      x - x_offset, y - y_offset, glyphs);
1679
1680   RESTORE_GC (gc);
1681 }
1682
1683 static void
1684 gdk_window_draw_glyphs_transformed (GdkDrawable      *drawable,
1685                                     GdkGC            *gc,
1686                                     PangoMatrix      *matrix,
1687                                     PangoFont        *font,
1688                                     gint              x,
1689                                     gint              y,
1690                                     PangoGlyphString *glyphs)
1691 {
1692   GdkWindowObject *private = (GdkWindowObject *)drawable;
1693   PangoMatrix tmp_matrix;
1694
1695   OFFSET_GC (gc);
1696
1697   if (GDK_WINDOW_DESTROYED (drawable))
1698     return;
1699
1700   if (x_offset != 0 || y_offset != 0)
1701     {
1702       if (matrix)
1703         {
1704           tmp_matrix = *matrix;
1705           tmp_matrix.x0 -= x_offset;
1706           tmp_matrix.y0 -= y_offset;
1707           matrix = &tmp_matrix;
1708         }
1709       else
1710         {
1711           x -= x_offset * PANGO_SCALE;
1712           y -= y_offset * PANGO_SCALE;
1713         }
1714     }
1715   
1716   if (private->paint_stack)
1717     {
1718       GdkWindowPaint *paint = private->paint_stack->data;
1719
1720       gdk_draw_glyphs_transformed (paint->pixmap, gc, matrix, font, x, y, glyphs);
1721     }
1722   else
1723     gdk_draw_glyphs_transformed (private->impl, gc, matrix, font, x, y, glyphs);
1724
1725   RESTORE_GC (gc);
1726 }
1727
1728 static void
1729 gdk_window_set_bg_pattern (GdkWindow      *window,
1730                            cairo_t        *cr,
1731                            int             x_offset,
1732                            int             y_offset)
1733 {
1734   GdkWindowObject *private = (GdkWindowObject *)window;
1735
1736   if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
1737     {
1738       x_offset += private->x;
1739       y_offset += private->y;
1740       gdk_window_set_bg_pattern (GDK_WINDOW (private->parent), cr,
1741                                  x_offset, y_offset);
1742     }
1743   else if (private->bg_pixmap && 
1744            private->bg_pixmap != GDK_PARENT_RELATIVE_BG && 
1745            private->bg_pixmap != GDK_NO_BG)
1746     {
1747       cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
1748       cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
1749       cairo_surface_destroy (surface);
1750
1751       if (x_offset != 0 || y_offset != 0)
1752         {
1753           cairo_matrix_t matrix;
1754           cairo_matrix_init_translate (&matrix, x_offset, y_offset);
1755           cairo_pattern_set_matrix (pattern, &matrix);
1756         }
1757
1758       cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
1759       cairo_set_source (cr, pattern);
1760       cairo_pattern_destroy (pattern);
1761     }
1762   else
1763     {
1764       gdk_cairo_set_source_color (cr, &private->bg_color);
1765     }
1766 }
1767
1768 static void
1769 gdk_window_clear_backing_rect (GdkWindow *window,
1770                                gint       x,
1771                                gint       y,
1772                                gint       width,
1773                                gint       height)
1774 {
1775   GdkWindowObject *private = (GdkWindowObject *)window;
1776   GdkWindowPaint *paint = private->paint_stack->data;
1777   cairo_t *cr;
1778
1779   if (GDK_WINDOW_DESTROYED (window))
1780     return;
1781
1782   cr = cairo_create (paint->surface);
1783
1784   gdk_window_set_bg_pattern (window, cr, 0, 0);
1785
1786   cairo_rectangle (cr, x, y, width, height);
1787   cairo_clip (cr);
1788
1789   gdk_cairo_region (cr, paint->region);
1790   cairo_fill (cr);
1791
1792   cairo_destroy (cr);
1793 }
1794
1795 /**
1796  * gdk_window_clear:
1797  * @window: a #GdkWindow
1798  * 
1799  * Clears an entire @window to the background color or background pixmap.
1800  **/
1801 void
1802 gdk_window_clear (GdkWindow *window)
1803 {
1804   gint width, height;
1805   
1806   g_return_if_fail (window != NULL);
1807   g_return_if_fail (GDK_IS_WINDOW (window));
1808
1809   gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
1810   
1811   gdk_window_clear_area (window, 0, 0,
1812                          width, height);
1813 }
1814
1815 /**
1816  * gdk_window_clear_area:
1817  * @window: a #GdkWindow
1818  * @x: x coordinate of rectangle to clear
1819  * @y: y coordinate of rectangle to clear
1820  * @width: width of rectangle to clear
1821  * @height: height of rectangle to clear
1822  *
1823  * Clears an area of @window to the background color or background pixmap.
1824  * 
1825  **/
1826 void
1827 gdk_window_clear_area (GdkWindow *window,
1828                        gint       x,
1829                        gint       y,
1830                        gint       width,
1831                        gint       height)
1832 {
1833   GdkWindowObject *private = (GdkWindowObject *)window;
1834
1835   g_return_if_fail (window != NULL);
1836   g_return_if_fail (GDK_IS_WINDOW (window));
1837   
1838   if (private->paint_stack)
1839     gdk_window_clear_backing_rect (window, x, y, width, height);
1840   else
1841     _gdk_windowing_window_clear_area (window, x, y, width, height);
1842 }
1843
1844 /**
1845  * gdk_window_clear_area_e:
1846  * @window: a #GdkWindow
1847  * @x: x coordinate of rectangle to clear
1848  * @y: y coordinate of rectangle to clear
1849  * @width: width of rectangle to clear
1850  * @height: height of rectangle to clear
1851  *
1852  * Like gdk_window_clear_area(), but also generates an expose event for
1853  * the cleared area.
1854  *
1855  * This function has a stupid name because it dates back to the mists
1856  * time, pre-GDK-1.0.
1857  * 
1858  **/
1859 void
1860 gdk_window_clear_area_e (GdkWindow *window,
1861                          gint       x,
1862                          gint       y,
1863                          gint       width,
1864                          gint       height)
1865 {
1866   GdkWindowObject *private = (GdkWindowObject *)window;
1867
1868   g_return_if_fail (window != NULL);
1869   g_return_if_fail (GDK_IS_WINDOW (window));
1870   
1871   if (private->paint_stack)
1872     gdk_window_clear_backing_rect (window, x, y, width, height);
1873
1874   _gdk_windowing_window_clear_area_e (window, x, y, width, height);
1875 }
1876
1877 static void
1878 gdk_window_draw_image (GdkDrawable *drawable,
1879                        GdkGC       *gc,
1880                        GdkImage    *image,
1881                        gint         xsrc,
1882                        gint         ysrc,
1883                        gint         xdest,
1884                        gint         ydest,
1885                        gint         width,
1886                        gint         height)
1887 {
1888   GdkWindowObject *private = (GdkWindowObject *)drawable;
1889
1890   OFFSET_GC (gc);
1891
1892   if (GDK_WINDOW_DESTROYED (drawable))
1893     return;
1894   
1895   if (private->paint_stack)
1896     {
1897       GdkWindowPaint *paint = private->paint_stack->data;
1898       gdk_draw_image (paint->pixmap, gc, image, xsrc, ysrc,
1899                       xdest - x_offset, ydest - y_offset,
1900                       width, height);
1901
1902     }
1903   else
1904     gdk_draw_image (private->impl, gc, image, xsrc, ysrc,
1905                     xdest - x_offset, ydest - y_offset,
1906                     width, height);
1907
1908   RESTORE_GC (gc);
1909 }
1910
1911 static void
1912 gdk_window_draw_pixbuf (GdkDrawable     *drawable,
1913                         GdkGC           *gc,
1914                         GdkPixbuf       *pixbuf,
1915                         gint             src_x,
1916                         gint             src_y,
1917                         gint             dest_x,
1918                         gint             dest_y,
1919                         gint             width,
1920                         gint             height,
1921                         GdkRgbDither     dither,
1922                         gint             x_dither,
1923                         gint             y_dither)
1924 {
1925   GdkWindowObject *private = (GdkWindowObject *)drawable;
1926
1927   if (GDK_WINDOW_DESTROYED (drawable))
1928     return;
1929   
1930   if (gc)
1931     {
1932       OFFSET_GC (gc);
1933   
1934       if (private->paint_stack)
1935         {
1936           GdkWindowPaint *paint = private->paint_stack->data;
1937           gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y,
1938                            dest_x - x_offset, dest_y - y_offset,
1939                            width, height,
1940                            dither, x_dither - x_offset, y_dither - y_offset);
1941         }
1942       else
1943         gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y,
1944                          dest_x - x_offset, dest_y - y_offset,
1945                          width, height,
1946                          dither, x_dither, y_dither);
1947       
1948       RESTORE_GC (gc);
1949     }
1950   else
1951     {
1952       gint x_offset, y_offset;
1953       gdk_window_get_offsets (drawable, &x_offset, &y_offset);
1954       
1955       if (private->paint_stack)
1956         {
1957           GdkWindowPaint *paint = private->paint_stack->data;
1958           gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y,
1959                            dest_x - x_offset, dest_y - y_offset,
1960                            width, height,
1961                             dither, x_dither - x_offset, y_dither - y_offset);
1962         }
1963       else
1964         gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y,
1965                          dest_x - x_offset, dest_y - y_offset,
1966                          width, height,
1967                          dither, x_dither, y_dither);
1968     }
1969 }
1970
1971 static void
1972 gdk_window_draw_trapezoids (GdkDrawable   *drawable,
1973                             GdkGC         *gc,
1974                             GdkTrapezoid  *trapezoids,
1975                             gint           n_trapezoids)
1976 {
1977   GdkWindowObject *private = (GdkWindowObject *)drawable;
1978   GdkTrapezoid *new_trapezoids = NULL;
1979
1980   OFFSET_GC (gc);
1981
1982   if (GDK_WINDOW_DESTROYED (drawable))
1983     return;
1984   
1985   if (x_offset != 0 || y_offset != 0)
1986     {
1987       gint i;
1988
1989       new_trapezoids = g_new (GdkTrapezoid, n_trapezoids);
1990       for (i=0; i < n_trapezoids; i++)
1991         {
1992           new_trapezoids[i].y1 = trapezoids[i].y1 - y_offset;
1993           new_trapezoids[i].x11 = trapezoids[i].x11 - x_offset;
1994           new_trapezoids[i].x21 = trapezoids[i].x21 - x_offset;
1995           new_trapezoids[i].y2 = trapezoids[i].y2 - y_offset;
1996           new_trapezoids[i].x12 = trapezoids[i].x12 - x_offset;
1997           new_trapezoids[i].x22 = trapezoids[i].x22 - x_offset;
1998         }
1999
2000       trapezoids = new_trapezoids;
2001     }
2002
2003   if (private->paint_stack)
2004     {
2005       GdkWindowPaint *paint = private->paint_stack->data;
2006       gdk_draw_trapezoids (paint->pixmap, gc, trapezoids, n_trapezoids);
2007     }
2008   else
2009     gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids);
2010   
2011   if (new_trapezoids)
2012     g_free (new_trapezoids);
2013
2014   RESTORE_GC (gc);
2015 }
2016
2017 static void
2018 gdk_window_real_get_size (GdkDrawable *drawable,
2019                           gint *width,
2020                           gint *height)
2021 {
2022   g_return_if_fail (GDK_IS_WINDOW (drawable));
2023
2024   gdk_drawable_get_size (GDK_WINDOW_OBJECT (drawable)->impl,
2025                          width, height);
2026 }
2027
2028 static GdkVisual*
2029 gdk_window_real_get_visual (GdkDrawable *drawable)
2030 {
2031   GdkColormap *colormap;
2032
2033   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2034
2035   colormap = gdk_drawable_get_colormap (drawable);
2036   return colormap ? gdk_colormap_get_visual (colormap) : NULL;
2037 }
2038
2039 static gint
2040 gdk_window_real_get_depth (GdkDrawable *drawable)
2041 {
2042   g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
2043
2044   return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
2045 }
2046
2047 static GdkScreen*
2048 gdk_window_real_get_screen (GdkDrawable *drawable)
2049 {
2050   return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
2051 }
2052
2053 static void
2054 gdk_window_real_set_colormap (GdkDrawable *drawable,
2055                               GdkColormap *cmap)
2056 {
2057   g_return_if_fail (GDK_IS_WINDOW (drawable));  
2058
2059   if (GDK_WINDOW_DESTROYED (drawable))
2060     return;
2061   
2062   gdk_drawable_set_colormap (((GdkWindowObject*)drawable)->impl, cmap);
2063 }
2064
2065 static GdkColormap*
2066 gdk_window_real_get_colormap (GdkDrawable *drawable)
2067 {
2068   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2069
2070   if (GDK_WINDOW_DESTROYED (drawable))
2071     return NULL;
2072   
2073   return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
2074 }
2075                       
2076 static GdkImage*
2077 gdk_window_copy_to_image (GdkDrawable     *drawable,
2078                           GdkImage        *image,
2079                           gint             src_x,
2080                           gint             src_y,
2081                           gint             dest_x,
2082                           gint             dest_y,
2083                           gint             width,
2084                           gint             height)
2085 {
2086   gint x_offset, y_offset;
2087   
2088   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2089   
2090   if (GDK_WINDOW_DESTROYED (drawable))
2091     return NULL;
2092
2093   /* If we're here, a composite image was not necessary, so
2094    * we can ignore the paint stack.
2095    */
2096   
2097   _gdk_windowing_window_get_offsets (drawable, &x_offset, &y_offset);
2098   
2099   return gdk_drawable_copy_to_image (((GdkWindowObject*)drawable)->impl,
2100                                      image,
2101                                      src_x - x_offset,
2102                                      src_y - y_offset,
2103                                      dest_x, dest_y,
2104                                      width, height);
2105 }
2106
2107 static cairo_surface_t *
2108 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
2109 {
2110   GdkWindowObject *private = (GdkWindowObject*) drawable;
2111   cairo_surface_t *surface;
2112   gint x_offset, y_offset;
2113   
2114   gdk_window_get_offsets (GDK_WINDOW (drawable), &x_offset, &y_offset);
2115
2116   if (private->paint_stack)
2117     {
2118       GdkWindowPaint *paint = private->paint_stack->data;
2119
2120       surface = paint->surface;
2121       cairo_surface_reference (surface);
2122     }
2123   else
2124     surface = _gdk_drawable_ref_cairo_surface (private->impl);
2125
2126   return surface;
2127 }
2128
2129 /* Code for dirty-region queueing
2130  */
2131 static GSList *update_windows = NULL;
2132 static guint update_idle = 0;
2133 static gboolean debug_updates = FALSE;
2134
2135 static gboolean
2136 gdk_window_update_idle (gpointer data)
2137 {
2138   GDK_THREADS_ENTER ();
2139   gdk_window_process_all_updates ();
2140   GDK_THREADS_LEAVE ();
2141   
2142   return FALSE;
2143 }
2144
2145 static void
2146 gdk_window_schedule_update (GdkWindow *window)
2147 {
2148   if (window && GDK_WINDOW_OBJECT (window)->update_freeze_count)
2149     return;
2150
2151   if (!update_idle)
2152     {
2153       update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
2154                                      gdk_window_update_idle, NULL, NULL);
2155     }
2156 }
2157
2158 static void
2159 gdk_window_process_updates_internal (GdkWindow *window)
2160 {
2161   GdkWindowObject *private = (GdkWindowObject *)window;
2162   gboolean save_region = FALSE;
2163
2164   /* If an update got queued during update processing, we can get a
2165    * window in the update queue that has an empty update_area.
2166    * just ignore it.
2167    */
2168   if (private->update_area)
2169     {
2170       GdkRegion *update_area = private->update_area;
2171       private->update_area = NULL;
2172       
2173       if (_gdk_event_func && gdk_window_is_viewable (window))
2174         {
2175           GdkRectangle window_rect;
2176           GdkRegion *expose_region;
2177           GdkRegion *window_region;
2178           gint width, height;
2179
2180           if (debug_updates)
2181             {
2182               /* Make sure we see the red invalid area before redrawing. */
2183               gdk_display_sync (gdk_drawable_get_display (window));
2184               g_usleep (70000);
2185             }
2186           
2187           save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
2188
2189           if (save_region)
2190             expose_region = gdk_region_copy (update_area);
2191           else
2192             expose_region = update_area;
2193           
2194           gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
2195
2196           window_rect.x = 0;
2197           window_rect.y = 0;
2198           window_rect.width = width;
2199           window_rect.height = height;
2200
2201           window_region = gdk_region_rectangle (&window_rect);
2202           gdk_region_intersect (expose_region,
2203                                 window_region);
2204           gdk_region_destroy (window_region);
2205           
2206           if (!gdk_region_empty (expose_region) &&
2207               (private->event_mask & GDK_EXPOSURE_MASK))
2208             {
2209               GdkEvent event;
2210               
2211               event.expose.type = GDK_EXPOSE;
2212               event.expose.window = g_object_ref (window);
2213               event.expose.send_event = FALSE;
2214               event.expose.count = 0;
2215               event.expose.region = expose_region;
2216               gdk_region_get_clipbox (expose_region, &event.expose.area);
2217               
2218               (*_gdk_event_func) (&event, _gdk_event_data);
2219               
2220               g_object_unref (window);
2221             }
2222
2223           if (expose_region != update_area)
2224             gdk_region_destroy (expose_region);
2225         }
2226       if (!save_region)
2227         gdk_region_destroy (update_area);
2228     }
2229 }
2230
2231 static void
2232 flush_all_displays (void)
2233 {
2234   GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
2235   GSList *tmp_list;
2236
2237   for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
2238     gdk_display_flush (tmp_list->data);
2239
2240   g_slist_free (displays);
2241 }
2242
2243 /**
2244  * gdk_window_process_all_updates:
2245  *
2246  * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
2247  * in the application.
2248  * 
2249  **/
2250 void
2251 gdk_window_process_all_updates (void)
2252 {
2253   GSList *old_update_windows = update_windows;
2254   GSList *tmp_list = update_windows;
2255
2256   if (update_idle)
2257     g_source_remove (update_idle);
2258   
2259   update_windows = NULL;
2260   update_idle = 0;
2261
2262   g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
2263   
2264   while (tmp_list)
2265     {
2266       GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
2267       
2268       if (private->update_freeze_count)
2269         update_windows = g_slist_prepend (update_windows, private);
2270       else
2271         gdk_window_process_updates_internal (tmp_list->data);
2272       
2273       g_object_unref (tmp_list->data);
2274       tmp_list = tmp_list->next;
2275     }
2276
2277   g_slist_free (old_update_windows);
2278
2279   flush_all_displays ();
2280 }
2281
2282 /**
2283  * gdk_window_process_updates:
2284  * @window: a #GdkWindow
2285  * @update_children: whether to also process updates for child windows
2286  *
2287  * Sends one or more expose events to @window. The areas in each 
2288  * expose event will cover the entire update area for the window (see
2289  * gdk_window_invalidate_region() for details). Normally GDK calls
2290  * gdk_window_process_all_updates() on your behalf, so there's no
2291  * need to call this function unless you want to force expose events
2292  * to be delivered immediately and synchronously (vs. the usual
2293  * case, where GDK delivers them in an idle handler). Occasionally
2294  * this is useful to produce nicer scrolling behavior, for example.
2295  * 
2296  **/
2297 void
2298 gdk_window_process_updates (GdkWindow *window,
2299                             gboolean   update_children)
2300 {
2301   GdkWindowObject *private = (GdkWindowObject *)window;
2302
2303   g_return_if_fail (window != NULL);
2304   g_return_if_fail (GDK_IS_WINDOW (window));
2305   
2306   if (private->update_area && !private->update_freeze_count)
2307     {      
2308       gdk_window_process_updates_internal (window);
2309       update_windows = g_slist_remove (update_windows, window);
2310     }
2311
2312   if (update_children)
2313     {
2314       GList *tmp_list = private->children;
2315       while (tmp_list)
2316         {
2317           gdk_window_process_updates (tmp_list->data, TRUE);
2318           tmp_list = tmp_list->next;
2319         }
2320     }
2321 }
2322
2323 /**
2324  * gdk_window_invalidate_rect:
2325  * @window: a #GdkWindow
2326  * @rect: rectangle to invalidate
2327  * @invalidate_children: whether to also invalidate child windows
2328  *
2329  * A convenience wrapper around gdk_window_invalidate_region() which
2330  * invalidates a rectangular region. See
2331  * gdk_window_invalidate_region() for details.
2332  * 
2333  **/
2334 void
2335 gdk_window_invalidate_rect   (GdkWindow    *window,
2336                               GdkRectangle *rect,
2337                               gboolean      invalidate_children)
2338 {
2339   GdkRectangle window_rect;
2340   GdkRegion *region;
2341   GdkWindowObject *private = (GdkWindowObject *)window;
2342
2343   g_return_if_fail (window != NULL);
2344   g_return_if_fail (GDK_IS_WINDOW (window));
2345
2346   if (GDK_WINDOW_DESTROYED (window))
2347     return;
2348   
2349   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
2350     return;
2351
2352   if (!rect)
2353     {
2354       window_rect.x = 0;
2355       window_rect.y = 0;
2356       gdk_drawable_get_size (GDK_DRAWABLE (window),
2357                              &window_rect.width,
2358                              &window_rect.height);
2359       rect = &window_rect;
2360     }
2361
2362   region = gdk_region_rectangle (rect);
2363   gdk_window_invalidate_region (window, region, invalidate_children);
2364   gdk_region_destroy (region);
2365 }
2366
2367 static void
2368 draw_ugly_color (GdkWindow *window,
2369                 GdkRegion *region)
2370 {
2371   /* Draw ugly color all over the newly-invalid region */
2372   GdkColor ugly_color = { 0, 50000, 10000, 10000 };
2373   GdkGC *ugly_gc;
2374   GdkRectangle clipbox;
2375     
2376   ugly_gc = gdk_gc_new (window);
2377   gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
2378   gdk_gc_set_clip_region (ugly_gc, region);
2379
2380   gdk_region_get_clipbox (region, &clipbox);
2381   
2382   gdk_draw_rectangle (window,
2383                       ugly_gc,
2384                       TRUE,
2385                       clipbox.x, clipbox.y,
2386                       clipbox.width, clipbox.height);
2387   
2388   g_object_unref (ugly_gc);
2389 }
2390
2391 /**
2392  * gdk_window_invalidate_maybe_recurse:
2393  * @window: a #GdkWindow
2394  * @region: a #GdkRegion
2395  * @child_func: function to use to decide if to recurse to a child,
2396  *              %NULL means never recurse.
2397  * @user_data: data passed to @child_func
2398  *
2399  * Adds @region to the update area for @window. The update area is the
2400  * region that needs to be redrawn, or "dirty region." The call
2401  * gdk_window_process_updates() sends one or more expose events to the
2402  * window, which together cover the entire update area. An
2403  * application would normally redraw the contents of @window in
2404  * response to those expose events.
2405  *
2406  * GDK will call gdk_window_process_all_updates() on your behalf
2407  * whenever your program returns to the main loop and becomes idle, so
2408  * normally there's no need to do that manually, you just need to
2409  * invalidate regions that you know should be redrawn.
2410  *
2411  * The @child_func parameter controls whether the region of
2412  * each child window that intersects @region will also be invalidated.
2413  * Only children for which @child_func returns TRUE will have the area
2414  * invalidated.
2415  **/
2416 void
2417 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
2418                                      GdkRegion *region,
2419                                      gboolean (*child_func) (GdkWindow *, gpointer),
2420                                      gpointer   user_data)
2421 {
2422   GdkWindowObject *private = (GdkWindowObject *)window;
2423   GdkRegion *visible_region;
2424   GList *tmp_list;
2425
2426   g_return_if_fail (window != NULL);
2427   g_return_if_fail (GDK_IS_WINDOW (window));
2428
2429   if (GDK_WINDOW_DESTROYED (window))
2430     return;
2431   
2432   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
2433     return;
2434
2435   visible_region = gdk_drawable_get_visible_region (window);
2436   gdk_region_intersect (visible_region, region);
2437
2438   tmp_list = private->children;
2439   while (tmp_list)
2440     {
2441       GdkWindowObject *child = tmp_list->data;
2442       
2443       if (!child->input_only)
2444         {
2445           GdkRegion *child_region;
2446           GdkRectangle child_rect;
2447           
2448           gdk_window_get_position ((GdkWindow *)child,
2449                                    &child_rect.x, &child_rect.y);
2450           gdk_drawable_get_size ((GdkDrawable *)child,
2451                                  &child_rect.width, &child_rect.height);
2452
2453           child_region = gdk_region_rectangle (&child_rect);
2454           
2455           /* remove child area from the invalid area of the parent */
2456           if (GDK_WINDOW_IS_MAPPED (child))
2457             gdk_region_subtract (visible_region, child_region);
2458           
2459           if (child_func && (*child_func) ((GdkWindow *)child, user_data))
2460             {
2461               gdk_region_offset (region, - child_rect.x, - child_rect.y);
2462               gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
2463               gdk_region_intersect (child_region, region);
2464               
2465               gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
2466                                                    child_region, child_func, user_data);
2467               
2468               gdk_region_offset (region, child_rect.x, child_rect.y);
2469             }
2470
2471           gdk_region_destroy (child_region);
2472         }
2473
2474       tmp_list = tmp_list->next;
2475     }
2476   
2477   if (!gdk_region_empty (visible_region))
2478     {
2479       if (debug_updates)
2480         draw_ugly_color (window, region);
2481       
2482       if (private->update_area)
2483         {
2484           gdk_region_union (private->update_area, visible_region);
2485         }
2486       else
2487         {
2488           update_windows = g_slist_prepend (update_windows, window);
2489           private->update_area = gdk_region_copy (visible_region);
2490           
2491           gdk_window_schedule_update (window);
2492         }
2493     }
2494   
2495   gdk_region_destroy (visible_region);
2496 }
2497
2498 static gboolean
2499 true_predicate (GdkWindow *window,
2500                 gpointer   user_data)
2501 {
2502   return TRUE;
2503 }
2504
2505 /**
2506  * gdk_window_invalidate_region:
2507  * @window: a #GdkWindow
2508  * @region: a #GdkRegion
2509  * @invalidate_children: %TRUE to also invalidate child windows 
2510  *
2511  * Adds @region to the update area for @window. The update area is the
2512  * region that needs to be redrawn, or "dirty region." The call
2513  * gdk_window_process_updates() sends one or more expose events to the
2514  * window, which together cover the entire update area. An
2515  * application would normally redraw the contents of @window in
2516  * response to those expose events.
2517  *
2518  * GDK will call gdk_window_process_all_updates() on your behalf
2519  * whenever your program returns to the main loop and becomes idle, so
2520  * normally there's no need to do that manually, you just need to
2521  * invalidate regions that you know should be redrawn.
2522  *
2523  * The @invalidate_children parameter controls whether the region of
2524  * each child window that intersects @region will also be invalidated.
2525  * If %FALSE, then the update area for child windows will remain
2526  * unaffected. See gdk_window_invalidate_maybe_recurse if you need
2527  * fine grained control over which children are invalidated.
2528  **/
2529 void
2530 gdk_window_invalidate_region (GdkWindow *window,
2531                               GdkRegion *region,
2532                               gboolean   invalidate_children)
2533 {
2534   gdk_window_invalidate_maybe_recurse (window, region,
2535                                        invalidate_children ?
2536                                          true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
2537                                        NULL);
2538 }
2539
2540 /**
2541  * gdk_window_get_update_area:
2542  * @window: a #GdkWindow
2543  * 
2544  * Transfers ownership of the update area from @window to the caller
2545  * of the function. That is, after calling this function, @window will
2546  * no longer have an invalid/dirty region; the update area is removed
2547  * from @window and handed to you. If a window has no update area,
2548  * gdk_window_get_update_area() returns %NULL. You are responsible for
2549  * calling gdk_region_destroy() on the returned region if it's non-%NULL.
2550  * 
2551  * Return value: the update area for @window
2552  **/
2553 GdkRegion *
2554 gdk_window_get_update_area (GdkWindow *window)
2555 {
2556   GdkWindowObject *private = (GdkWindowObject *)window;
2557   GdkRegion *tmp_region;
2558
2559   g_return_val_if_fail (window != NULL, NULL);
2560   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2561
2562   if (private->update_area)
2563     {
2564       tmp_region = private->update_area;
2565       private->update_area = NULL;
2566
2567       update_windows = g_slist_remove (update_windows, window);
2568       
2569       return tmp_region;
2570     }
2571   else
2572     return NULL;
2573 }
2574
2575 /**
2576  * _gdk_window_clear_update_area:
2577  * @window: a #GdkWindow.
2578  * 
2579  * Internal function to clear the update area for a window. This
2580  * is called when the window is hidden or destroyed.
2581  **/
2582 void
2583 _gdk_window_clear_update_area (GdkWindow *window)
2584 {
2585   GdkWindowObject *private = (GdkWindowObject *)window;
2586
2587   g_return_if_fail (window != NULL);
2588   g_return_if_fail (GDK_IS_WINDOW (window));
2589
2590   if (private->update_area)
2591     {
2592       update_windows = g_slist_remove (update_windows, window);
2593       
2594       gdk_region_destroy (private->update_area);
2595       private->update_area = NULL;
2596     }
2597 }
2598
2599 /**
2600  * gdk_window_freeze_updates:
2601  * @window: a #GdkWindow
2602  * 
2603  * Temporarily freezes a window such that it won't receive expose
2604  * events.  The window will begin receiving expose events again when
2605  * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
2606  * has been called more than once, gdk_window_thaw_updates() must be called
2607  * an equal number of times to begin processing exposes.
2608  **/
2609 void
2610 gdk_window_freeze_updates (GdkWindow *window)
2611 {
2612   GdkWindowObject *private = (GdkWindowObject *)window;
2613
2614   g_return_if_fail (window != NULL);
2615   g_return_if_fail (GDK_IS_WINDOW (window));
2616
2617   private->update_freeze_count++;
2618 }
2619
2620 /**
2621  * gdk_window_thaw_updates:
2622  * @window: a #GdkWindow
2623  * 
2624  * Thaws a window frozen with gdk_window_freeze_updates().
2625  **/
2626 void
2627 gdk_window_thaw_updates (GdkWindow *window)
2628 {
2629   GdkWindowObject *private = (GdkWindowObject *)window;
2630
2631   g_return_if_fail (window != NULL);
2632   g_return_if_fail (GDK_IS_WINDOW (window));
2633   g_return_if_fail (private->update_freeze_count > 0);
2634
2635   if (--private->update_freeze_count == 0)
2636     gdk_window_schedule_update (window);
2637 }
2638
2639 /**
2640  * gdk_window_set_debug_updates:
2641  * @setting: %TRUE to turn on update debugging
2642  *
2643  * With update debugging enabled, calls to
2644  * gdk_window_invalidate_region() clear the invalidated region of the
2645  * screen to a noticeable color, and GDK pauses for a short time
2646  * before sending exposes to windows during
2647  * gdk_window_process_updates().  The net effect is that you can see
2648  * the invalid region for each window and watch redraws as they
2649  * occur. This allows you to diagnose inefficiencies in your application.
2650  *
2651  * In essence, because the GDK rendering model prevents all flicker,
2652  * if you are redrawing the same region 400 times you may never
2653  * notice, aside from noticing a speed problem. Enabling update
2654  * debugging causes GTK to flicker slowly and noticeably, so you can
2655  * see exactly what's being redrawn when, in what order.
2656  *
2657  * The --gtk-debug=updates command line option passed to GTK+ programs
2658  * enables this debug option at application startup time. That's
2659  * usually more useful than calling gdk_window_set_debug_updates()
2660  * yourself, though you might want to use this function to enable
2661  * updates sometime after application startup time.
2662  * 
2663  **/
2664 void
2665 gdk_window_set_debug_updates (gboolean setting)
2666 {
2667   debug_updates = setting;
2668 }
2669
2670 /**
2671  * gdk_window_constrain_size:
2672  * @geometry: a #GdkGeometry structure
2673  * @flags: a mask indicating what portions of @geometry are set
2674  * @width: desired width of window
2675  * @height: desired height of the window
2676  * @new_width: location to store resulting width
2677  * @new_height: location to store resulting height
2678  * 
2679  * Constrains a desired width and height according to a 
2680  * set of geometry hints (such as minimum and maximum size).
2681  */
2682 void
2683 gdk_window_constrain_size (GdkGeometry *geometry,
2684                            guint        flags,
2685                            gint         width,
2686                            gint         height,
2687                            gint        *new_width,
2688                            gint        *new_height)
2689 {
2690   /* This routine is partially borrowed from fvwm.
2691    *
2692    * Copyright 1993, Robert Nation
2693    *     You may use this code for any purpose, as long as the original
2694    *     copyright remains in the source code and all documentation
2695    *
2696    * which in turn borrows parts of the algorithm from uwm
2697    */
2698   gint min_width = 0;
2699   gint min_height = 0;
2700   gint base_width = 0;
2701   gint base_height = 0;
2702   gint xinc = 1;
2703   gint yinc = 1;
2704   gint max_width = G_MAXINT;
2705   gint max_height = G_MAXINT;
2706   
2707 #define FLOOR(value, base)      ( ((gint) ((value) / (base))) * (base) )
2708
2709   if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
2710     {
2711       base_width = geometry->base_width;
2712       base_height = geometry->base_height;
2713       min_width = geometry->min_width;
2714       min_height = geometry->min_height;
2715     }
2716   else if (flags & GDK_HINT_BASE_SIZE)
2717     {
2718       base_width = geometry->base_width;
2719       base_height = geometry->base_height;
2720       min_width = geometry->base_width;
2721       min_height = geometry->base_height;
2722     }
2723   else if (flags & GDK_HINT_MIN_SIZE)
2724     {
2725       base_width = geometry->min_width;
2726       base_height = geometry->min_height;
2727       min_width = geometry->min_width;
2728       min_height = geometry->min_height;
2729     }
2730
2731   if (flags & GDK_HINT_MAX_SIZE)
2732     {
2733       max_width = geometry->max_width ;
2734       max_height = geometry->max_height;
2735     }
2736
2737   if (flags & GDK_HINT_RESIZE_INC)
2738     {
2739       xinc = MAX (xinc, geometry->width_inc);
2740       yinc = MAX (yinc, geometry->height_inc);
2741     }
2742   
2743   /* clamp width and height to min and max values
2744    */
2745   width = CLAMP (width, min_width, max_width);
2746   height = CLAMP (height, min_height, max_height);
2747   
2748   /* shrink to base + N * inc
2749    */
2750   width = base_width + FLOOR (width - base_width, xinc);
2751   height = base_height + FLOOR (height - base_height, yinc);
2752
2753   /* constrain aspect ratio, according to:
2754    *
2755    *                width     
2756    * min_aspect <= -------- <= max_aspect
2757    *                height    
2758    */
2759   
2760   if (flags & GDK_HINT_ASPECT &&
2761       geometry->min_aspect > 0 &&
2762       geometry->max_aspect > 0)
2763     {
2764       gint delta;
2765
2766       if (geometry->min_aspect * height > width)
2767         {
2768           delta = FLOOR (height - width / geometry->min_aspect, yinc);
2769           if (height - delta >= min_height)
2770             height -= delta;
2771           else
2772             { 
2773               delta = FLOOR (height * geometry->min_aspect - width, xinc);
2774               if (width + delta <= max_width) 
2775                 width += delta;
2776             }
2777         }
2778       
2779       if (geometry->max_aspect * height < width)
2780         {
2781           delta = FLOOR (width - height * geometry->max_aspect, xinc);
2782           if (width - delta >= min_width) 
2783             width -= delta;
2784           else
2785             {
2786               delta = FLOOR (width / geometry->max_aspect - height, yinc);
2787               if (height + delta <= max_height)
2788                 height += delta;
2789             }
2790         }
2791     }
2792
2793 #undef FLOOR
2794   
2795   *new_width = width;
2796   *new_height = height;
2797 }
2798
2799 /**
2800  * gdk_window_get_pointer:
2801  * @window: a #GdkWindow
2802  * @x: return location for X coordinate of pointer
2803  * @y: return location for Y coordinate of pointer
2804  * @mask: return location for modifier mask
2805  *
2806  * Obtains the current pointer position and modifier state.
2807  * The position is given in coordinates relative to @window.
2808  * 
2809  * Return value: the window containing the pointer (as with
2810  * gdk_window_at_pointer()), or %NULL if the window containing the
2811  * pointer isn't known to GDK
2812  **/
2813 GdkWindow*
2814 gdk_window_get_pointer (GdkWindow         *window,
2815                         gint              *x,
2816                         gint              *y,
2817                         GdkModifierType   *mask)
2818 {
2819   GdkDisplay *display;
2820   gint tmp_x, tmp_y;
2821   GdkModifierType tmp_mask;
2822   GdkWindow *child;
2823   
2824   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2825
2826   if (window)
2827     {
2828       display = gdk_drawable_get_display (window);
2829     }
2830   else
2831     {
2832       GdkScreen *screen = gdk_screen_get_default ();
2833
2834       display = gdk_screen_get_display (screen);
2835       window = gdk_screen_get_root_window (screen);
2836       
2837       GDK_NOTE (MULTIHEAD,
2838                 g_message ("Passing NULL for window to gdk_window_get_pointer()\n"
2839                            "is not multihead safe"));
2840     }
2841
2842   child = display->pointer_hooks->window_get_pointer (display, window, &tmp_x, &tmp_y, &tmp_mask);
2843
2844   if (x)
2845     *x = tmp_x;
2846   if (y)
2847     *y = tmp_y;
2848   if (mask)
2849     *mask = tmp_mask;
2850
2851   return child;
2852 }
2853
2854 /**
2855  * gdk_window_at_pointer:
2856  * @win_x: return location for origin of the window under the pointer
2857  * @win_y: return location for origin of the window under the pointer
2858  * 
2859  * Obtains the window underneath the mouse pointer, returning the
2860  * location of that window in @win_x, @win_y. Returns %NULL if the
2861  * window under the mouse pointer is not known to GDK (if the window
2862  * belongs to another application and a #GdkWindow hasn't been created
2863  * for it with gdk_window_foreign_new())
2864  *
2865  * NOTE: For multihead-aware widgets or applications use
2866  * gdk_display_get_window_at_pointer() instead.
2867  * 
2868  * Return value: window under the mouse pointer
2869  **/
2870 GdkWindow*
2871 gdk_window_at_pointer (gint *win_x,
2872                        gint *win_y)
2873 {
2874   return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
2875 }
2876
2877 /**
2878  * gdk_get_default_root_window:
2879  * 
2880  * Obtains the root window (parent all other windows are inside)
2881  * for the default display and screen.
2882  * 
2883  * Return value: the default root window
2884  **/
2885 GdkWindow *
2886 gdk_get_default_root_window (void)
2887 {
2888   return gdk_screen_get_root_window (gdk_screen_get_default ());
2889 }
2890
2891 /**
2892  * gdk_window_foreign_new:
2893  * @anid: a native window handle.
2894  * 
2895  * Wraps a native window for the default display in a #GdkWindow.
2896  * This may fail if the window has been destroyed.
2897  *
2898  * For example in the X backend, a native window handle is an Xlib
2899  * <type>XID</type>.
2900  * 
2901  * Return value: the newly-created #GdkWindow wrapper for the 
2902  *    native window or %NULL if the window has been destroyed.
2903  **/
2904 GdkWindow *
2905 gdk_window_foreign_new (GdkNativeWindow anid)
2906 {
2907   return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
2908 }
2909
2910 #define __GDK_WINDOW_C__
2911 #include "gdkaliasdef.c"