]> Pileus Git - ~andy/gtk/blob - gdk/gdkwindow.c
Use cairo_set_device_offset().
[~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       gdk_window_set_bg_pattern (GDK_WINDOW (private->parent), cr,
1739                                  private->x, private->y);
1740     }
1741   else if (private->bg_pixmap && 
1742            private->bg_pixmap != GDK_PARENT_RELATIVE_BG && 
1743            private->bg_pixmap != GDK_NO_BG)
1744     {
1745       cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
1746       cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
1747       cairo_surface_destroy (surface);
1748
1749       if (x_offset != 0 || y_offset)
1750         {
1751           cairo_matrix_t *matrix = cairo_matrix_create ();
1752           cairo_matrix_translate (matrix, x_offset, y_offset);
1753           cairo_pattern_set_matrix (pattern, matrix);
1754           cairo_matrix_destroy (matrix);
1755         }
1756
1757       cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
1758       cairo_set_pattern (cr, pattern);
1759       cairo_pattern_destroy (pattern);
1760     }
1761   else
1762     {
1763       gdk_cairo_set_source_color (cr, &private->bg_color);
1764     }
1765 }
1766
1767 static void
1768 region_path (cairo_t   *cr,
1769              GdkRegion *region)
1770 {
1771   GdkRectangle *rectangles;
1772   int n_rectangles, i;
1773   
1774   gdk_region_get_rectangles (region, &rectangles, &n_rectangles);
1775   for (i = 0; i < n_rectangles; i++)
1776     {
1777       cairo_rectangle (cr,
1778                        rectangles[i].x, rectangles[i].y,
1779                        rectangles[i].width, rectangles[i].height);
1780     }
1781   g_free (rectangles);
1782 }
1783
1784 static void
1785 gdk_window_clear_backing_rect (GdkWindow *window,
1786                                gint       x,
1787                                gint       y,
1788                                gint       width,
1789                                gint       height)
1790 {
1791   GdkWindowObject *private = (GdkWindowObject *)window;
1792   GdkWindowPaint *paint = private->paint_stack->data;
1793   cairo_t *cr;
1794
1795   if (GDK_WINDOW_DESTROYED (window))
1796     return;
1797
1798   cr = cairo_create ();
1799   cairo_set_target_surface (cr, paint->surface);
1800
1801   gdk_window_set_bg_pattern (window, cr, 0, 0);
1802
1803   cairo_save (cr);
1804
1805   cairo_rectangle (cr, x, y, width, height);
1806   cairo_clip (cr);
1807
1808   region_path (cr, paint->region);
1809   cairo_fill (cr);
1810
1811   cairo_restore (cr);
1812
1813   cairo_destroy (cr);
1814 }
1815
1816 /**
1817  * gdk_window_clear:
1818  * @window: a #GdkWindow
1819  * 
1820  * Clears an entire @window to the background color or background pixmap.
1821  **/
1822 void
1823 gdk_window_clear (GdkWindow *window)
1824 {
1825   gint width, height;
1826   
1827   g_return_if_fail (window != NULL);
1828   g_return_if_fail (GDK_IS_WINDOW (window));
1829
1830   gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
1831   
1832   gdk_window_clear_area (window, 0, 0,
1833                          width, height);
1834 }
1835
1836 /**
1837  * gdk_window_clear_area:
1838  * @window: a #GdkWindow
1839  * @x: x coordinate of rectangle to clear
1840  * @y: y coordinate of rectangle to clear
1841  * @width: width of rectangle to clear
1842  * @height: height of rectangle to clear
1843  *
1844  * Clears an area of @window to the background color or background pixmap.
1845  * 
1846  **/
1847 void
1848 gdk_window_clear_area (GdkWindow *window,
1849                        gint       x,
1850                        gint       y,
1851                        gint       width,
1852                        gint       height)
1853 {
1854   GdkWindowObject *private = (GdkWindowObject *)window;
1855
1856   g_return_if_fail (window != NULL);
1857   g_return_if_fail (GDK_IS_WINDOW (window));
1858   
1859   if (private->paint_stack)
1860     gdk_window_clear_backing_rect (window, x, y, width, height);
1861   else
1862     _gdk_windowing_window_clear_area (window, x, y, width, height);
1863 }
1864
1865 /**
1866  * gdk_window_clear_area_e:
1867  * @window: a #GdkWindow
1868  * @x: x coordinate of rectangle to clear
1869  * @y: y coordinate of rectangle to clear
1870  * @width: width of rectangle to clear
1871  * @height: height of rectangle to clear
1872  *
1873  * Like gdk_window_clear_area(), but also generates an expose event for
1874  * the cleared area.
1875  *
1876  * This function has a stupid name because it dates back to the mists
1877  * time, pre-GDK-1.0.
1878  * 
1879  **/
1880 void
1881 gdk_window_clear_area_e (GdkWindow *window,
1882                          gint       x,
1883                          gint       y,
1884                          gint       width,
1885                          gint       height)
1886 {
1887   GdkWindowObject *private = (GdkWindowObject *)window;
1888
1889   g_return_if_fail (window != NULL);
1890   g_return_if_fail (GDK_IS_WINDOW (window));
1891   
1892   if (private->paint_stack)
1893     gdk_window_clear_backing_rect (window, x, y, width, height);
1894
1895   _gdk_windowing_window_clear_area_e (window, x, y, width, height);
1896 }
1897
1898 static void
1899 gdk_window_draw_image (GdkDrawable *drawable,
1900                        GdkGC       *gc,
1901                        GdkImage    *image,
1902                        gint         xsrc,
1903                        gint         ysrc,
1904                        gint         xdest,
1905                        gint         ydest,
1906                        gint         width,
1907                        gint         height)
1908 {
1909   GdkWindowObject *private = (GdkWindowObject *)drawable;
1910
1911   OFFSET_GC (gc);
1912
1913   if (GDK_WINDOW_DESTROYED (drawable))
1914     return;
1915   
1916   if (private->paint_stack)
1917     {
1918       GdkWindowPaint *paint = private->paint_stack->data;
1919       gdk_draw_image (paint->pixmap, gc, image, xsrc, ysrc,
1920                       xdest - x_offset, ydest - y_offset,
1921                       width, height);
1922
1923     }
1924   else
1925     gdk_draw_image (private->impl, gc, image, xsrc, ysrc,
1926                     xdest - x_offset, ydest - y_offset,
1927                     width, height);
1928
1929   RESTORE_GC (gc);
1930 }
1931
1932 static void
1933 gdk_window_draw_pixbuf (GdkDrawable     *drawable,
1934                         GdkGC           *gc,
1935                         GdkPixbuf       *pixbuf,
1936                         gint             src_x,
1937                         gint             src_y,
1938                         gint             dest_x,
1939                         gint             dest_y,
1940                         gint             width,
1941                         gint             height,
1942                         GdkRgbDither     dither,
1943                         gint             x_dither,
1944                         gint             y_dither)
1945 {
1946   GdkWindowObject *private = (GdkWindowObject *)drawable;
1947
1948   if (GDK_WINDOW_DESTROYED (drawable))
1949     return;
1950   
1951   if (gc)
1952     {
1953       OFFSET_GC (gc);
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       RESTORE_GC (gc);
1970     }
1971   else
1972     {
1973       gint x_offset, y_offset;
1974       gdk_window_get_offsets (drawable, &x_offset, &y_offset);
1975       
1976       if (private->paint_stack)
1977         {
1978           GdkWindowPaint *paint = private->paint_stack->data;
1979           gdk_draw_pixbuf (paint->pixmap, gc, pixbuf, src_x, src_y,
1980                            dest_x - x_offset, dest_y - y_offset,
1981                            width, height,
1982                             dither, x_dither - x_offset, y_dither - y_offset);
1983         }
1984       else
1985         gdk_draw_pixbuf (private->impl, gc, pixbuf, src_x, src_y,
1986                          dest_x - x_offset, dest_y - y_offset,
1987                          width, height,
1988                          dither, x_dither, y_dither);
1989     }
1990 }
1991
1992 static void
1993 gdk_window_draw_trapezoids (GdkDrawable   *drawable,
1994                             GdkGC         *gc,
1995                             GdkTrapezoid  *trapezoids,
1996                             gint           n_trapezoids)
1997 {
1998   GdkWindowObject *private = (GdkWindowObject *)drawable;
1999   GdkTrapezoid *new_trapezoids = NULL;
2000
2001   OFFSET_GC (gc);
2002
2003   if (GDK_WINDOW_DESTROYED (drawable))
2004     return;
2005   
2006   if (x_offset != 0 || y_offset != 0)
2007     {
2008       gint i;
2009
2010       new_trapezoids = g_new (GdkTrapezoid, n_trapezoids);
2011       for (i=0; i < n_trapezoids; i++)
2012         {
2013           new_trapezoids[i].y1 = trapezoids[i].y1 - y_offset;
2014           new_trapezoids[i].x11 = trapezoids[i].x11 - x_offset;
2015           new_trapezoids[i].x21 = trapezoids[i].x21 - x_offset;
2016           new_trapezoids[i].y2 = trapezoids[i].y2 - y_offset;
2017           new_trapezoids[i].x12 = trapezoids[i].x12 - x_offset;
2018           new_trapezoids[i].x22 = trapezoids[i].x22 - x_offset;
2019         }
2020
2021       trapezoids = new_trapezoids;
2022     }
2023
2024   if (private->paint_stack)
2025     {
2026       GdkWindowPaint *paint = private->paint_stack->data;
2027       gdk_draw_trapezoids (paint->pixmap, gc, trapezoids, n_trapezoids);
2028     }
2029   else
2030     gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids);
2031   
2032   if (new_trapezoids)
2033     g_free (new_trapezoids);
2034
2035   RESTORE_GC (gc);
2036 }
2037
2038 static void
2039 gdk_window_real_get_size (GdkDrawable *drawable,
2040                           gint *width,
2041                           gint *height)
2042 {
2043   g_return_if_fail (GDK_IS_WINDOW (drawable));
2044
2045   gdk_drawable_get_size (GDK_WINDOW_OBJECT (drawable)->impl,
2046                          width, height);
2047 }
2048
2049 static GdkVisual*
2050 gdk_window_real_get_visual (GdkDrawable *drawable)
2051 {
2052   GdkColormap *colormap;
2053
2054   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2055
2056   colormap = gdk_drawable_get_colormap (drawable);
2057   return colormap ? gdk_colormap_get_visual (colormap) : NULL;
2058 }
2059
2060 static gint
2061 gdk_window_real_get_depth (GdkDrawable *drawable)
2062 {
2063   g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
2064
2065   return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
2066 }
2067
2068 static GdkScreen*
2069 gdk_window_real_get_screen (GdkDrawable *drawable)
2070 {
2071   return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
2072 }
2073
2074 static void
2075 gdk_window_real_set_colormap (GdkDrawable *drawable,
2076                               GdkColormap *cmap)
2077 {
2078   g_return_if_fail (GDK_IS_WINDOW (drawable));  
2079
2080   if (GDK_WINDOW_DESTROYED (drawable))
2081     return;
2082   
2083   gdk_drawable_set_colormap (((GdkWindowObject*)drawable)->impl, cmap);
2084 }
2085
2086 static GdkColormap*
2087 gdk_window_real_get_colormap (GdkDrawable *drawable)
2088 {
2089   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2090
2091   if (GDK_WINDOW_DESTROYED (drawable))
2092     return NULL;
2093   
2094   return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
2095 }
2096                       
2097 static GdkImage*
2098 gdk_window_copy_to_image (GdkDrawable     *drawable,
2099                           GdkImage        *image,
2100                           gint             src_x,
2101                           gint             src_y,
2102                           gint             dest_x,
2103                           gint             dest_y,
2104                           gint             width,
2105                           gint             height)
2106 {
2107   gint x_offset, y_offset;
2108   
2109   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
2110   
2111   if (GDK_WINDOW_DESTROYED (drawable))
2112     return NULL;
2113
2114   /* If we're here, a composite image was not necessary, so
2115    * we can ignore the paint stack.
2116    */
2117   
2118   _gdk_windowing_window_get_offsets (drawable, &x_offset, &y_offset);
2119   
2120   return gdk_drawable_copy_to_image (((GdkWindowObject*)drawable)->impl,
2121                                      image,
2122                                      src_x - x_offset,
2123                                      src_y - y_offset,
2124                                      dest_x, dest_y,
2125                                      width, height);
2126 }
2127
2128 static cairo_surface_t *
2129 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
2130 {
2131   GdkWindowObject *private = (GdkWindowObject*) drawable;
2132   cairo_surface_t *surface;
2133   gint x_offset, y_offset;
2134   
2135   gdk_window_get_offsets (GDK_WINDOW (drawable), &x_offset, &y_offset);
2136
2137   if (private->paint_stack)
2138     {
2139       GdkWindowPaint *paint = private->paint_stack->data;
2140
2141       surface = paint->surface;
2142       cairo_surface_reference (surface);
2143     }
2144   else
2145     surface = _gdk_drawable_ref_cairo_surface (private->impl);
2146
2147   return surface;
2148 }
2149
2150 /* Code for dirty-region queueing
2151  */
2152 static GSList *update_windows = NULL;
2153 static guint update_idle = 0;
2154 static gboolean debug_updates = FALSE;
2155
2156 static gboolean
2157 gdk_window_update_idle (gpointer data)
2158 {
2159   GDK_THREADS_ENTER ();
2160   gdk_window_process_all_updates ();
2161   GDK_THREADS_LEAVE ();
2162   
2163   return FALSE;
2164 }
2165
2166 static void
2167 gdk_window_schedule_update (GdkWindow *window)
2168 {
2169   if (window && GDK_WINDOW_OBJECT (window)->update_freeze_count)
2170     return;
2171
2172   if (!update_idle)
2173     {
2174       update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
2175                                      gdk_window_update_idle, NULL, NULL);
2176     }
2177 }
2178
2179 static void
2180 gdk_window_process_updates_internal (GdkWindow *window)
2181 {
2182   GdkWindowObject *private = (GdkWindowObject *)window;
2183   gboolean save_region = FALSE;
2184
2185   /* If an update got queued during update processing, we can get a
2186    * window in the update queue that has an empty update_area.
2187    * just ignore it.
2188    */
2189   if (private->update_area)
2190     {
2191       GdkRegion *update_area = private->update_area;
2192       private->update_area = NULL;
2193       
2194       if (_gdk_event_func && gdk_window_is_viewable (window))
2195         {
2196           GdkRectangle window_rect;
2197           GdkRegion *expose_region;
2198           GdkRegion *window_region;
2199           gint width, height;
2200
2201           if (debug_updates)
2202             {
2203               /* Make sure we see the red invalid area before redrawing. */
2204               gdk_display_sync (gdk_drawable_get_display (window));
2205               g_usleep (70000);
2206             }
2207           
2208           save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
2209
2210           if (save_region)
2211             expose_region = gdk_region_copy (update_area);
2212           else
2213             expose_region = update_area;
2214           
2215           gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
2216
2217           window_rect.x = 0;
2218           window_rect.y = 0;
2219           window_rect.width = width;
2220           window_rect.height = height;
2221
2222           window_region = gdk_region_rectangle (&window_rect);
2223           gdk_region_intersect (expose_region,
2224                                 window_region);
2225           gdk_region_destroy (window_region);
2226           
2227           if (!gdk_region_empty (expose_region) &&
2228               (private->event_mask & GDK_EXPOSURE_MASK))
2229             {
2230               GdkEvent event;
2231               
2232               event.expose.type = GDK_EXPOSE;
2233               event.expose.window = g_object_ref (window);
2234               event.expose.count = 0;
2235               event.expose.region = expose_region;
2236               gdk_region_get_clipbox (expose_region, &event.expose.area);
2237               
2238               (*_gdk_event_func) (&event, _gdk_event_data);
2239               
2240               g_object_unref (window);
2241             }
2242
2243           if (expose_region != update_area)
2244             gdk_region_destroy (expose_region);
2245         }
2246       if (!save_region)
2247         gdk_region_destroy (update_area);
2248     }
2249 }
2250
2251 static void
2252 flush_all_displays (void)
2253 {
2254   GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
2255   GSList *tmp_list;
2256
2257   for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
2258     gdk_display_flush (tmp_list->data);
2259
2260   g_slist_free (displays);
2261 }
2262
2263 /**
2264  * gdk_window_process_all_updates:
2265  *
2266  * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
2267  * in the application.
2268  * 
2269  **/
2270 void
2271 gdk_window_process_all_updates (void)
2272 {
2273   GSList *old_update_windows = update_windows;
2274   GSList *tmp_list = update_windows;
2275
2276   if (update_idle)
2277     g_source_remove (update_idle);
2278   
2279   update_windows = NULL;
2280   update_idle = 0;
2281
2282   g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
2283   
2284   while (tmp_list)
2285     {
2286       GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
2287       
2288       if (private->update_freeze_count)
2289         update_windows = g_slist_prepend (update_windows, private);
2290       else
2291         gdk_window_process_updates_internal (tmp_list->data);
2292       
2293       g_object_unref (tmp_list->data);
2294       tmp_list = tmp_list->next;
2295     }
2296
2297   g_slist_free (old_update_windows);
2298
2299   flush_all_displays ();
2300 }
2301
2302 /**
2303  * gdk_window_process_updates:
2304  * @window: a #GdkWindow
2305  * @update_children: whether to also process updates for child windows
2306  *
2307  * Sends one or more expose events to @window. The areas in each 
2308  * expose event will cover the entire update area for the window (see
2309  * gdk_window_invalidate_region() for details). Normally GDK calls
2310  * gdk_window_process_all_updates() on your behalf, so there's no
2311  * need to call this function unless you want to force expose events
2312  * to be delivered immediately and synchronously (vs. the usual
2313  * case, where GDK delivers them in an idle handler). Occasionally
2314  * this is useful to produce nicer scrolling behavior, for example.
2315  * 
2316  **/
2317 void
2318 gdk_window_process_updates (GdkWindow *window,
2319                             gboolean   update_children)
2320 {
2321   GdkWindowObject *private = (GdkWindowObject *)window;
2322
2323   g_return_if_fail (window != NULL);
2324   g_return_if_fail (GDK_IS_WINDOW (window));
2325   
2326   if (private->update_area && !private->update_freeze_count)
2327     {      
2328       gdk_window_process_updates_internal (window);
2329       update_windows = g_slist_remove (update_windows, window);
2330     }
2331
2332   if (update_children)
2333     {
2334       GList *tmp_list = private->children;
2335       while (tmp_list)
2336         {
2337           gdk_window_process_updates (tmp_list->data, TRUE);
2338           tmp_list = tmp_list->next;
2339         }
2340     }
2341 }
2342
2343 /**
2344  * gdk_window_invalidate_rect:
2345  * @window: a #GdkWindow
2346  * @rect: rectangle to invalidate
2347  * @invalidate_children: whether to also invalidate child windows
2348  *
2349  * A convenience wrapper around gdk_window_invalidate_region() which
2350  * invalidates a rectangular region. See
2351  * gdk_window_invalidate_region() for details.
2352  * 
2353  **/
2354 void
2355 gdk_window_invalidate_rect   (GdkWindow    *window,
2356                               GdkRectangle *rect,
2357                               gboolean      invalidate_children)
2358 {
2359   GdkRectangle window_rect;
2360   GdkRegion *region;
2361   GdkWindowObject *private = (GdkWindowObject *)window;
2362
2363   g_return_if_fail (window != NULL);
2364   g_return_if_fail (GDK_IS_WINDOW (window));
2365
2366   if (GDK_WINDOW_DESTROYED (window))
2367     return;
2368   
2369   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
2370     return;
2371
2372   if (!rect)
2373     {
2374       window_rect.x = 0;
2375       window_rect.y = 0;
2376       gdk_drawable_get_size (GDK_DRAWABLE (window),
2377                              &window_rect.width,
2378                              &window_rect.height);
2379       rect = &window_rect;
2380     }
2381
2382   region = gdk_region_rectangle (rect);
2383   gdk_window_invalidate_region (window, region, invalidate_children);
2384   gdk_region_destroy (region);
2385 }
2386
2387 static void
2388 draw_ugly_color (GdkWindow *window,
2389                 GdkRegion *region)
2390 {
2391   /* Draw ugly color all over the newly-invalid region */
2392   GdkColor ugly_color = { 0, 50000, 10000, 10000 };
2393   GdkGC *ugly_gc;
2394   GdkRectangle clipbox;
2395     
2396   ugly_gc = gdk_gc_new (window);
2397   gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
2398   gdk_gc_set_clip_region (ugly_gc, region);
2399
2400   gdk_region_get_clipbox (region, &clipbox);
2401   
2402   gdk_draw_rectangle (window,
2403                       ugly_gc,
2404                       TRUE,
2405                       clipbox.x, clipbox.y,
2406                       clipbox.width, clipbox.height);
2407   
2408   g_object_unref (ugly_gc);
2409 }
2410
2411 /**
2412  * gdk_window_invalidate_maybe_recurse:
2413  * @window: a #GdkWindow
2414  * @region: a #GdkRegion
2415  * @child_func: function to use to decide if to recurse to a child,
2416  *              %NULL means never recurse.
2417  * @user_data: data passed to @child_func
2418  *
2419  * Adds @region to the update area for @window. The update area is the
2420  * region that needs to be redrawn, or "dirty region." The call
2421  * gdk_window_process_updates() sends one or more expose events to the
2422  * window, which together cover the entire update area. An
2423  * application would normally redraw the contents of @window in
2424  * response to those expose events.
2425  *
2426  * GDK will call gdk_window_process_all_updates() on your behalf
2427  * whenever your program returns to the main loop and becomes idle, so
2428  * normally there's no need to do that manually, you just need to
2429  * invalidate regions that you know should be redrawn.
2430  *
2431  * The @child_func parameter controls whether the region of
2432  * each child window that intersects @region will also be invalidated.
2433  * Only children for which @child_func returns TRUE will have the area
2434  * invalidated.
2435  **/
2436 void
2437 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
2438                                      GdkRegion *region,
2439                                      gboolean (*child_func) (GdkWindow *, gpointer),
2440                                      gpointer   user_data)
2441 {
2442   GdkWindowObject *private = (GdkWindowObject *)window;
2443   GdkRegion *visible_region;
2444
2445   g_return_if_fail (window != NULL);
2446   g_return_if_fail (GDK_IS_WINDOW (window));
2447
2448   if (GDK_WINDOW_DESTROYED (window))
2449     return;
2450   
2451   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
2452     return;
2453
2454   visible_region = gdk_drawable_get_visible_region (window);
2455   gdk_region_intersect (visible_region, region);
2456
2457   if (!gdk_region_empty (visible_region))
2458     {
2459       if (debug_updates)
2460         draw_ugly_color (window, region);
2461       
2462       if (private->update_area)
2463         {
2464           gdk_region_union (private->update_area, visible_region);
2465         }
2466       else
2467         {
2468           update_windows = g_slist_prepend (update_windows, window);
2469           private->update_area = gdk_region_copy (visible_region);
2470           
2471           gdk_window_schedule_update (window);
2472         }
2473       
2474       if (child_func)
2475         {
2476           GList *tmp_list;
2477           
2478           tmp_list = private->children;
2479           while (tmp_list)
2480             {
2481               GdkWindowObject *child = tmp_list->data;
2482               tmp_list = tmp_list->next;
2483
2484               if (!child->input_only && (*child_func) ((GdkWindow *)child, user_data))
2485                 {
2486                   GdkRegion *child_region;
2487                   gint x, y;
2488
2489                   gdk_window_get_position ((GdkWindow *)child, &x, &y);
2490
2491                   /* This copy could be saved with a little more complexity */
2492                   child_region = gdk_region_copy (visible_region);
2493                   gdk_region_offset (child_region, - x, - y);
2494                   
2495                   gdk_window_invalidate_maybe_recurse ((GdkWindow *)child, child_region, child_func, user_data);
2496                   
2497                   gdk_region_destroy (child_region);
2498                 }
2499             }
2500         }
2501     }
2502   
2503   gdk_region_destroy (visible_region);
2504 }
2505
2506 static gboolean
2507 true_predicate (GdkWindow *window,
2508                 gpointer   user_data)
2509 {
2510   return TRUE;
2511 }
2512
2513 /**
2514  * gdk_window_invalidate_region:
2515  * @window: a #GdkWindow
2516  * @region: a #GdkRegion
2517  * @invalidate_children: %TRUE to also invalidate child windows 
2518  *
2519  * Adds @region to the update area for @window. The update area is the
2520  * region that needs to be redrawn, or "dirty region." The call
2521  * gdk_window_process_updates() sends one or more expose events to the
2522  * window, which together cover the entire update area. An
2523  * application would normally redraw the contents of @window in
2524  * response to those expose events.
2525  *
2526  * GDK will call gdk_window_process_all_updates() on your behalf
2527  * whenever your program returns to the main loop and becomes idle, so
2528  * normally there's no need to do that manually, you just need to
2529  * invalidate regions that you know should be redrawn.
2530  *
2531  * The @invalidate_children parameter controls whether the region of
2532  * each child window that intersects @region will also be invalidated.
2533  * If %FALSE, then the update area for child windows will remain
2534  * unaffected. See gdk_window_invalidate_maybe_recurse if you need
2535  * fine grained control over which children are invalidated.
2536  **/
2537 void
2538 gdk_window_invalidate_region (GdkWindow *window,
2539                               GdkRegion *region,
2540                               gboolean   invalidate_children)
2541 {
2542   gdk_window_invalidate_maybe_recurse (window, region,
2543                                        invalidate_children ?
2544                                          true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
2545                                        NULL);
2546 }
2547
2548 /**
2549  * gdk_window_get_update_area:
2550  * @window: a #GdkWindow
2551  * 
2552  * Transfers ownership of the update area from @window to the caller
2553  * of the function. That is, after calling this function, @window will
2554  * no longer have an invalid/dirty region; the update area is removed
2555  * from @window and handed to you. If a window has no update area,
2556  * gdk_window_get_update_area() returns %NULL. You are responsible for
2557  * calling gdk_region_destroy() on the returned region if it's non-%NULL.
2558  * 
2559  * Return value: the update area for @window
2560  **/
2561 GdkRegion *
2562 gdk_window_get_update_area (GdkWindow *window)
2563 {
2564   GdkWindowObject *private = (GdkWindowObject *)window;
2565   GdkRegion *tmp_region;
2566
2567   g_return_val_if_fail (window != NULL, NULL);
2568   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2569
2570   if (private->update_area)
2571     {
2572       tmp_region = private->update_area;
2573       private->update_area = NULL;
2574
2575       update_windows = g_slist_remove (update_windows, window);
2576       
2577       return tmp_region;
2578     }
2579   else
2580     return NULL;
2581 }
2582
2583 /**
2584  * _gdk_window_clear_update_area:
2585  * @window: a #GdkWindow.
2586  * 
2587  * Internal function to clear the update area for a window. This
2588  * is called when the window is hidden or destroyed.
2589  **/
2590 void
2591 _gdk_window_clear_update_area (GdkWindow *window)
2592 {
2593   GdkWindowObject *private = (GdkWindowObject *)window;
2594
2595   g_return_if_fail (window != NULL);
2596   g_return_if_fail (GDK_IS_WINDOW (window));
2597
2598   if (private->update_area)
2599     {
2600       update_windows = g_slist_remove (update_windows, window);
2601       
2602       gdk_region_destroy (private->update_area);
2603       private->update_area = NULL;
2604     }
2605 }
2606
2607 /**
2608  * gdk_window_freeze_updates:
2609  * @window: a #GdkWindow
2610  * 
2611  * Temporarily freezes a window such that it won't receive expose
2612  * events.  The window will begin receiving expose events again when
2613  * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
2614  * has been called more than once, gdk_window_thaw_updates() must be called
2615  * an equal number of times to begin processing exposes.
2616  **/
2617 void
2618 gdk_window_freeze_updates (GdkWindow *window)
2619 {
2620   GdkWindowObject *private = (GdkWindowObject *)window;
2621
2622   g_return_if_fail (window != NULL);
2623   g_return_if_fail (GDK_IS_WINDOW (window));
2624
2625   private->update_freeze_count++;
2626 }
2627
2628 /**
2629  * gdk_window_thaw_updates:
2630  * @window: a #GdkWindow
2631  * 
2632  * Thaws a window frozen with gdk_window_freeze_updates().
2633  **/
2634 void
2635 gdk_window_thaw_updates (GdkWindow *window)
2636 {
2637   GdkWindowObject *private = (GdkWindowObject *)window;
2638
2639   g_return_if_fail (window != NULL);
2640   g_return_if_fail (GDK_IS_WINDOW (window));
2641   g_return_if_fail (private->update_freeze_count > 0);
2642
2643   if (--private->update_freeze_count == 0)
2644     gdk_window_schedule_update (window);
2645 }
2646
2647 /**
2648  * gdk_window_set_debug_updates:
2649  * @setting: %TRUE to turn on update debugging
2650  *
2651  * With update debugging enabled, calls to
2652  * gdk_window_invalidate_region() clear the invalidated region of the
2653  * screen to a noticeable color, and GDK pauses for a short time
2654  * before sending exposes to windows during
2655  * gdk_window_process_updates().  The net effect is that you can see
2656  * the invalid region for each window and watch redraws as they
2657  * occur. This allows you to diagnose inefficiencies in your application.
2658  *
2659  * In essence, because the GDK rendering model prevents all flicker,
2660  * if you are redrawing the same region 400 times you may never
2661  * notice, aside from noticing a speed problem. Enabling update
2662  * debugging causes GTK to flicker slowly and noticeably, so you can
2663  * see exactly what's being redrawn when, in what order.
2664  *
2665  * The --gtk-debug=updates command line option passed to GTK+ programs
2666  * enables this debug option at application startup time. That's
2667  * usually more useful than calling gdk_window_set_debug_updates()
2668  * yourself, though you might want to use this function to enable
2669  * updates sometime after application startup time.
2670  * 
2671  **/
2672 void
2673 gdk_window_set_debug_updates (gboolean setting)
2674 {
2675   debug_updates = setting;
2676 }
2677
2678 /**
2679  * gdk_window_constrain_size:
2680  * @geometry: a #GdkGeometry structure
2681  * @flags: a mask indicating what portions of @geometry are set
2682  * @width: desired width of window
2683  * @height: desired height of the window
2684  * @new_width: location to store resulting width
2685  * @new_height: location to store resulting height
2686  * 
2687  * Constrains a desired width and height according to a 
2688  * set of geometry hints (such as minimum and maximum size).
2689  */
2690 void
2691 gdk_window_constrain_size (GdkGeometry *geometry,
2692                            guint        flags,
2693                            gint         width,
2694                            gint         height,
2695                            gint        *new_width,
2696                            gint        *new_height)
2697 {
2698   /* This routine is partially borrowed from fvwm.
2699    *
2700    * Copyright 1993, Robert Nation
2701    *     You may use this code for any purpose, as long as the original
2702    *     copyright remains in the source code and all documentation
2703    *
2704    * which in turn borrows parts of the algorithm from uwm
2705    */
2706   gint min_width = 0;
2707   gint min_height = 0;
2708   gint base_width = 0;
2709   gint base_height = 0;
2710   gint xinc = 1;
2711   gint yinc = 1;
2712   gint max_width = G_MAXINT;
2713   gint max_height = G_MAXINT;
2714   
2715 #define FLOOR(value, base)      ( ((gint) ((value) / (base))) * (base) )
2716
2717   if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
2718     {
2719       base_width = geometry->base_width;
2720       base_height = geometry->base_height;
2721       min_width = geometry->min_width;
2722       min_height = geometry->min_height;
2723     }
2724   else if (flags & GDK_HINT_BASE_SIZE)
2725     {
2726       base_width = geometry->base_width;
2727       base_height = geometry->base_height;
2728       min_width = geometry->base_width;
2729       min_height = geometry->base_height;
2730     }
2731   else if (flags & GDK_HINT_MIN_SIZE)
2732     {
2733       base_width = geometry->min_width;
2734       base_height = geometry->min_height;
2735       min_width = geometry->min_width;
2736       min_height = geometry->min_height;
2737     }
2738
2739   if (flags & GDK_HINT_MAX_SIZE)
2740     {
2741       max_width = geometry->max_width ;
2742       max_height = geometry->max_height;
2743     }
2744
2745   if (flags & GDK_HINT_RESIZE_INC)
2746     {
2747       xinc = MAX (xinc, geometry->width_inc);
2748       yinc = MAX (yinc, geometry->height_inc);
2749     }
2750   
2751   /* clamp width and height to min and max values
2752    */
2753   width = CLAMP (width, min_width, max_width);
2754   height = CLAMP (height, min_height, max_height);
2755   
2756   /* shrink to base + N * inc
2757    */
2758   width = base_width + FLOOR (width - base_width, xinc);
2759   height = base_height + FLOOR (height - base_height, yinc);
2760
2761   /* constrain aspect ratio, according to:
2762    *
2763    *                width     
2764    * min_aspect <= -------- <= max_aspect
2765    *                height    
2766    */
2767   
2768   if (flags & GDK_HINT_ASPECT &&
2769       geometry->min_aspect > 0 &&
2770       geometry->max_aspect > 0)
2771     {
2772       gint delta;
2773
2774       if (geometry->min_aspect * height > width)
2775         {
2776           delta = FLOOR (height - width / geometry->min_aspect, yinc);
2777           if (height - delta >= min_height)
2778             height -= delta;
2779           else
2780             { 
2781               delta = FLOOR (height * geometry->min_aspect - width, xinc);
2782               if (width + delta <= max_width) 
2783                 width += delta;
2784             }
2785         }
2786       
2787       if (geometry->max_aspect * height < width)
2788         {
2789           delta = FLOOR (width - height * geometry->max_aspect, xinc);
2790           if (width - delta >= min_width) 
2791             width -= delta;
2792           else
2793             {
2794               delta = FLOOR (width / geometry->max_aspect - height, yinc);
2795               if (height + delta <= max_height)
2796                 height += delta;
2797             }
2798         }
2799     }
2800
2801 #undef FLOOR
2802   
2803   *new_width = width;
2804   *new_height = height;
2805 }
2806
2807 /**
2808  * gdk_window_get_pointer:
2809  * @window: a #GdkWindow
2810  * @x: return location for X coordinate of pointer
2811  * @y: return location for Y coordinate of pointer
2812  * @mask: return location for modifier mask
2813  *
2814  * Obtains the current pointer position and modifier state.
2815  * The position is given in coordinates relative to @window.
2816  * 
2817  * Return value: the window containing the pointer (as with
2818  * gdk_window_at_pointer()), or %NULL if the window containing the
2819  * pointer isn't known to GDK
2820  **/
2821 GdkWindow*
2822 gdk_window_get_pointer (GdkWindow         *window,
2823                         gint              *x,
2824                         gint              *y,
2825                         GdkModifierType   *mask)
2826 {
2827   GdkDisplay *display;
2828   gint tmp_x, tmp_y;
2829   GdkModifierType tmp_mask;
2830   GdkWindow *child;
2831   
2832   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2833
2834   if (window)
2835     {
2836       display = gdk_drawable_get_display (window);
2837     }
2838   else
2839     {
2840       GdkScreen *screen = gdk_screen_get_default ();
2841
2842       display = gdk_screen_get_display (screen);
2843       window = gdk_screen_get_root_window (screen);
2844       
2845       GDK_NOTE (MULTIHEAD,
2846                 g_message ("Passing NULL for window to gdk_window_get_pointer()\n"
2847                            "is not multihead safe"));
2848     }
2849
2850   child = display->pointer_hooks->window_get_pointer (display, window, &tmp_x, &tmp_y, &tmp_mask);
2851
2852   if (x)
2853     *x = tmp_x;
2854   if (y)
2855     *y = tmp_y;
2856   if (mask)
2857     *mask = tmp_mask;
2858
2859   return child;
2860 }
2861
2862 /**
2863  * gdk_window_at_pointer:
2864  * @win_x: return location for origin of the window under the pointer
2865  * @win_y: return location for origin of the window under the pointer
2866  * 
2867  * Obtains the window underneath the mouse pointer, returning the
2868  * location of that window in @win_x, @win_y. Returns %NULL if the
2869  * window under the mouse pointer is not known to GDK (if the window
2870  * belongs to another application and a #GdkWindow hasn't been created
2871  * for it with gdk_window_foreign_new())
2872  *
2873  * NOTE: For multihead-aware widgets or applications use
2874  * gdk_display_get_window_at_pointer() instead.
2875  * 
2876  * Return value: window under the mouse pointer
2877  **/
2878 GdkWindow*
2879 gdk_window_at_pointer (gint *win_x,
2880                        gint *win_y)
2881 {
2882   return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
2883 }
2884
2885 /**
2886  * gdk_get_default_root_window:
2887  * 
2888  * Obtains the root window (parent all other windows are inside)
2889  * for the default display and screen.
2890  * 
2891  * Return value: the default root window
2892  **/
2893 GdkWindow *
2894 gdk_get_default_root_window (void)
2895 {
2896   return gdk_screen_get_root_window (gdk_screen_get_default ());
2897 }
2898
2899 /**
2900  * gdk_window_foreign_new:
2901  * @anid: a native window handle.
2902  * 
2903  * Wraps a native window for the default display in a #GdkWindow.
2904  * This may fail if the window has been destroyed.
2905  *
2906  * For example in the X backend, a native window handle is an Xlib
2907  * <type>XID</type>.
2908  * 
2909  * Return value: the newly-created #GdkWindow wrapper for the 
2910  *    native window or %NULL if the window has been destroyed.
2911  **/
2912 GdkWindow *
2913 gdk_window_foreign_new (GdkNativeWindow anid)
2914 {
2915   return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
2916 }
2917
2918 #define __GDK_WINDOW_C__
2919 #include "gdkaliasdef.c"