]> Pileus Git - ~andy/gtk/blob - gdk/gdkwindow.c
Add allow-none to gdk_window_set_cursor()
[~andy/gtk] / gdk / gdkwindow.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3  * Josh MacDonald, Ryan Lortie
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
26  */
27
28 #include "config.h"
29
30 #include "gdkwindow.h"
31
32 #ifdef GDK_WINDOWING_X11
33 #include "x11/gdkx.h"           /* For workaround */
34 #endif
35 #include "math.h"
36
37 #include "gdk.h"                /* For gdk_rectangle_union() */
38 #include "gdkinternals.h"
39 #include "gdkintl.h"
40 #include "gdkscreen.h"
41 #include "gdkdeviceprivate.h"
42 #include "gdkdrawable.h"
43 #include "gdkmarshalers.h"
44 #include "gdkpixmap.h"
45 #include "gdkscreen.h"
46 #include "gdkwindowimpl.h"
47
48 #include "gdkalias.h"
49
50 #undef DEBUG_WINDOW_PRINTING
51
52
53 /**
54  * SECTION:windows
55  * @Short_description: Onscreen display areas in the target window system
56  * @Title: Windows
57  *
58  * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
59  * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
60  * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
61  * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
62  * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
63  * with it.
64  *
65  * <refsect2 id="COMPOSITED-WINDOWS">
66  * <title>Composited Windows</title>
67  * <para>
68  * Normally, the windowing system takes care of rendering the contents of a
69  * child window onto its parent window. This mechanism can be intercepted by
70  * calling gdk_window_set_composited() on the child window. For a
71  * <firstterm>composited</firstterm> window it is the responsibility of the
72  * application to render the window contents at the right spot.
73  * </para>
74  * <example id="composited-window-example">
75  * <title>Composited windows</title>
76  * <programlisting>
77  * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../examples/gdk/composited-window-example.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include>
78  * </programlisting></example>
79  * <para>
80  * In the example <xref linkend="composited-window-example"/>, a button is
81  * placed inside of an event box inside of a window. The event box is set as
82  * composited and therefore is no longer automatically drawn to the screen.
83  *
84  * When the contents of the event box change, an expose event is generated on
85  * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
86  * The expose handler for this widget is responsible for merging the changes
87  * back on the screen in the way that it wishes.
88  *
89  * In our case, we merge the contents with a 50% transparency. We also set the
90  * background colour of the window to red. The effect is that the background
91  * shows through the button.
92  * </para>
93  * </refsect2>
94  * <refsect2 id="OFFSCREEN-WINDOWS">
95  * <title>Offscreen Windows</title>
96  * <para>
97  * Offscreen windows are more general than composited windows, since they allow
98  * not only to modify the rendering of the child window onto its parent, but
99  * also to apply coordinate transformations.
100  *
101  * To integrate an offscreen window into a window hierarchy, one has to call
102  * gdk_offscreen_window_set_embedder() and handle a number of signals. The
103  * #GdkWindow::pick-embedded-child signal on the embedder window is used to
104  * select an offscreen child at given coordinates, and the
105  * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
106  * offscreen window are used to translate coordinates between the embedder and
107  * the offscreen window.
108  *
109  * For rendering an offscreen window onto its embedder, the contents of the
110  * offscreen window are available as a pixmap, via
111  * gdk_offscreen_window_get_pixmap().
112  * </para>
113  * </refsect2>
114  */
115
116
117 /* Historically a GdkWindow always matches a platform native window,
118  * be it a toplevel window or a child window. In this setup the
119  * GdkWindow (and other GdkDrawables) were platform independent classes,
120  * and the actual platform specific implementation was in a delegate
121  * object availible as "impl" in the window object.
122  *
123  * With the addition of client side windows and offscreen windows this
124  * changes a bit. The application-visible GdkWindow object behaves as
125  * it did before, but not all such windows now have a corresponding native
126  * window. Instead windows that are "client side" are emulated by the gdk
127  * code such that clipping, drawing, moving, events etc work as expected.
128  *
129  * For GdkWindows that have a native window the "impl" object is the
130  * same as before. However, for all client side windows the impl object
131  * is shared with its parent (i.e. all client windows descendants of one
132  * native window has the same impl.
133  *
134  * Additionally there is a new type of platform independent impl object,
135  * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
136  * of this type (while their children are generally GDK_WINDOW_CHILD virtual
137  * windows). Such windows work by allocating a GdkPixmap as the backing store
138  * for drawing operations, which is resized with the window.
139  *
140  * GdkWindows have a pointer to the "impl window" they are in, i.e.
141  * the topmost GdkWindow which have the same "impl" value. This is stored
142  * in impl_window, which is different from the window itself only for client
143  * side windows.
144  * All GdkWindows (native or not) track the position of the window in the parent
145  * (x, y), the size of the window (width, height), the position of the window
146  * with respect to the impl window (abs_x, abs_y). We also track the clip
147  * region of the window wrt parent windows and siblings, in window-relative
148  * coordinates with and without child windows included (clip_region,
149  * clip_region_with_children).
150  *
151  * All toplevel windows are native windows, but also child windows can be
152  * native (although not children of offscreens). We always listen to
153  * a basic set of events (see get_native_event_mask) for these windows
154  * so that we can emulate events for any client side children.
155  *
156  * For native windows we apply the calculated clip region as a window shape
157  * so that eg. client side siblings that overlap the native child properly
158  * draws over the native child window.
159  *
160  * In order to minimize flicker and for performance we use a couple of cacheing
161  * tricks. First of all, every time we do a window to window copy area, for instance
162  * when moving a client side window or when scrolling/moving a region in a window
163  * we store this in outstanding_moves instead of applying immediately. We then
164  * delay this move until we really need it (because something depends on being
165  * able to read it), or until we're handing a redraw from an expose/invalidation
166  * (actually we delay it past redraw, but before blitting the double buffer pixmap
167  * to the window). This gives us two advantages. First of all it minimizes the time
168  * from the window is moved to the exposes related to that move, secondly it allows
169  * us to be smart about how to do the copy. We combine multiple moves into one (when
170  * possible) and we don't actually do copies to anything that is or will be
171  * invalidated and exposed anyway.
172  *
173  * Secondly, we use something called a "implicit paint" during repaint handling.
174  * An implicit paint is similar to a regular paint for the paint stack, but it is
175  * not put on the stack. Instead, it is set on the impl window, and later when
176  * regular gdk_window_begin_paint_region()  happen on a window of this impl window
177  * we reuse the pixmap from the implicit paint. During repaint we create and at the
178  * end flush an implicit paint, which means we can collect all the paints on
179  * multiple client side windows in the same backing store pixmap.
180  *
181  * All drawing to windows are wrapped with macros that set up the GC such that
182  * the offsets and clip region is right for drawing to the paint object or
183  * directly to the emulated window. It also automatically handles any flushing
184  * needed when drawing directly to a window. Adding window/paint clipping is
185  * done using _gdk_gc_add_drawable_clip which lets us efficiently add and then
186  * remove a custom clip region.
187  */
188
189 #define USE_BACKING_STORE       /* Appears to work on Win32, too, now. */
190
191 /* This adds a local value to the GdkVisibilityState enum */
192 #define GDK_VISIBILITY_NOT_VIEWABLE 3
193
194 enum {
195   PICK_EMBEDDED_CHILD, /* only called if children are embedded */
196   TO_EMBEDDER,
197   FROM_EMBEDDER,
198   LAST_SIGNAL
199 };
200
201 enum {
202   PROP_0,
203   PROP_CURSOR
204 };
205
206 typedef enum {
207   CLEAR_BG_NONE,
208   CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
209   CLEAR_BG_ALL
210 } ClearBg;
211
212 struct _GdkWindowPaint
213 {
214   GdkRegion *region;
215   GdkPixmap *pixmap;
216   gint x_offset;
217   gint y_offset;
218   cairo_surface_t *surface;
219   guint uses_implicit : 1;
220   guint flushed : 1;
221   guint32 region_tag;
222 };
223
224 typedef struct {
225   GdkRegion *dest_region; /* The destination region */
226   int dx, dy; /* The amount that the source was moved to reach dest_region */
227 } GdkWindowRegionMove;
228
229 /* Global info */
230
231 static GdkGC *gdk_window_create_gc      (GdkDrawable     *drawable,
232                                          GdkGCValues     *values,
233                                          GdkGCValuesMask  mask);
234 static void   gdk_window_draw_rectangle (GdkDrawable     *drawable,
235                                          GdkGC           *gc,
236                                          gboolean         filled,
237                                          gint             x,
238                                          gint             y,
239                                          gint             width,
240                                          gint             height);
241 static void   gdk_window_draw_arc       (GdkDrawable     *drawable,
242                                          GdkGC           *gc,
243                                          gboolean         filled,
244                                          gint             x,
245                                          gint             y,
246                                          gint             width,
247                                          gint             height,
248                                          gint             angle1,
249                                          gint             angle2);
250 static void   gdk_window_draw_polygon   (GdkDrawable     *drawable,
251                                          GdkGC           *gc,
252                                          gboolean         filled,
253                                          GdkPoint        *points,
254                                          gint             npoints);
255 static void   gdk_window_draw_drawable  (GdkDrawable     *drawable,
256                                          GdkGC           *gc,
257                                          GdkPixmap       *src,
258                                          gint             xsrc,
259                                          gint             ysrc,
260                                          gint             xdest,
261                                          gint             ydest,
262                                          gint             width,
263                                          gint             height,
264                                          GdkDrawable     *original_src);
265 static void   gdk_window_draw_points    (GdkDrawable     *drawable,
266                                          GdkGC           *gc,
267                                          GdkPoint        *points,
268                                          gint             npoints);
269 static void   gdk_window_draw_segments  (GdkDrawable     *drawable,
270                                          GdkGC           *gc,
271                                          GdkSegment      *segs,
272                                          gint             nsegs);
273 static void   gdk_window_draw_lines     (GdkDrawable     *drawable,
274                                          GdkGC           *gc,
275                                          GdkPoint        *points,
276                                          gint             npoints);
277
278 static void gdk_window_draw_glyphs             (GdkDrawable      *drawable,
279                                                 GdkGC            *gc,
280                                                 PangoFont        *font,
281                                                 gint              x,
282                                                 gint              y,
283                                                 PangoGlyphString *glyphs);
284 static void gdk_window_draw_glyphs_transformed (GdkDrawable      *drawable,
285                                                 GdkGC            *gc,
286                                                 PangoMatrix      *matrix,
287                                                 PangoFont        *font,
288                                                 gint              x,
289                                                 gint              y,
290                                                 PangoGlyphString *glyphs);
291
292 static void   gdk_window_draw_image     (GdkDrawable     *drawable,
293                                          GdkGC           *gc,
294                                          GdkImage        *image,
295                                          gint             xsrc,
296                                          gint             ysrc,
297                                          gint             xdest,
298                                          gint             ydest,
299                                          gint             width,
300                                          gint             height);
301
302 static void gdk_window_draw_pixbuf (GdkDrawable     *drawable,
303                                     GdkGC           *gc,
304                                     GdkPixbuf       *pixbuf,
305                                     gint             src_x,
306                                     gint             src_y,
307                                     gint             dest_x,
308                                     gint             dest_y,
309                                     gint             width,
310                                     gint             height,
311                                     GdkRgbDither     dither,
312                                     gint             x_dither,
313                                     gint             y_dither);
314
315 static void gdk_window_draw_trapezoids (GdkDrawable   *drawable,
316                                         GdkGC         *gc,
317                                         GdkTrapezoid  *trapezoids,
318                                         gint           n_trapezoids);
319
320 static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
321                                            GdkImage    *image,
322                                            gint         src_x,
323                                            gint         src_y,
324                                            gint         dest_x,
325                                            gint         dest_y,
326                                            gint         width,
327                                            gint         height);
328
329 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
330 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
331                                                          int width,
332                                                          int height);
333 static void             gdk_window_drop_cairo_surface (GdkWindowObject *private);
334 static void             gdk_window_set_cairo_clip    (GdkDrawable *drawable,
335                                                       cairo_t *cr);
336
337 static void   gdk_window_real_get_size  (GdkDrawable     *drawable,
338                                          gint            *width,
339                                          gint            *height);
340
341 static GdkVisual*   gdk_window_real_get_visual   (GdkDrawable *drawable);
342 static gint         gdk_window_real_get_depth    (GdkDrawable *drawable);
343 static GdkScreen*   gdk_window_real_get_screen   (GdkDrawable *drawable);
344 static void         gdk_window_real_set_colormap (GdkDrawable *drawable,
345                                                   GdkColormap *cmap);
346 static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
347
348 static GdkDrawable* gdk_window_get_source_drawable    (GdkDrawable *drawable);
349 static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable,
350                                                        gint         x,
351                                                        gint         y,
352                                                        gint         width,
353                                                        gint         height,
354                                                        gint        *composite_x_offset,
355                                                        gint        *composite_y_offset);
356 static GdkRegion*   gdk_window_get_clip_region        (GdkDrawable *drawable);
357 static GdkRegion*   gdk_window_get_visible_region     (GdkDrawable *drawable);
358
359 static void gdk_window_free_paint_stack (GdkWindow *window);
360
361 static void gdk_window_init       (GdkWindowObject      *window);
362 static void gdk_window_class_init (GdkWindowObjectClass *klass);
363 static void gdk_window_finalize   (GObject              *object);
364
365 static void gdk_window_set_property (GObject      *object,
366                                      guint         prop_id,
367                                      const GValue *value,
368                                      GParamSpec   *pspec);
369 static void gdk_window_get_property (GObject      *object,
370                                      guint         prop_id,
371                                      GValue       *value,
372                                      GParamSpec   *pspec);
373
374 static void gdk_window_clear_backing_region (GdkWindow *window,
375                                              GdkRegion *region);
376 static void gdk_window_redirect_free      (GdkWindowRedirect *redirect);
377 static void apply_redirect_to_children    (GdkWindowObject   *private,
378                                            GdkWindowRedirect *redirect);
379 static void remove_redirect_from_children (GdkWindowObject   *private,
380                                            GdkWindowRedirect *redirect);
381
382 static void recompute_visible_regions   (GdkWindowObject *private,
383                                          gboolean recalculate_siblings,
384                                          gboolean recalculate_children);
385 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
386 static void gdk_window_flush_recursive  (GdkWindowObject *window);
387 static void do_move_region_bits_on_impl (GdkWindowObject *private,
388                                          GdkRegion *region, /* In impl window coords */
389                                          int dx, int dy);
390 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
391 static void move_native_children        (GdkWindowObject *private);
392 static void update_cursor               (GdkDisplay *display,
393                                          GdkDevice  *device);
394 static void impl_window_add_update_area (GdkWindowObject *impl_window,
395                                          GdkRegion *region);
396 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
397 static void gdk_window_invalidate_region_full (GdkWindow       *window,
398                                                const GdkRegion *region,
399                                                gboolean         invalidate_children,
400                                                ClearBg          clear_bg);
401 static void gdk_window_invalidate_rect_full (GdkWindow          *window,
402                                              const GdkRectangle *rect,
403                                              gboolean            invalidate_children,
404                                              ClearBg             clear_bg);
405
406 static guint signals[LAST_SIGNAL] = { 0 };
407
408 static gpointer parent_class = NULL;
409
410 static const cairo_user_data_key_t gdk_window_cairo_key;
411
412 static guint32
413 new_region_tag (void)
414 {
415   static guint32 tag = 0;
416
417   return ++tag;
418 }
419
420 GType
421 gdk_window_object_get_type (void)
422 {
423   static GType object_type = 0;
424
425   if (!object_type)
426     object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
427                                                  "GdkWindow",
428                                                  sizeof (GdkWindowObjectClass),
429                                                  (GClassInitFunc) gdk_window_class_init,
430                                                  sizeof (GdkWindowObject),
431                                                  (GInstanceInitFunc) gdk_window_init,
432                                                  0);
433
434   return object_type;
435 }
436
437 GType
438 _gdk_paintable_get_type (void)
439 {
440   static GType paintable_type = 0;
441
442   if (!paintable_type)
443     {
444       const GTypeInfo paintable_info =
445       {
446         sizeof (GdkPaintableIface),  /* class_size */
447         NULL,                        /* base_init */
448         NULL,                        /* base_finalize */
449       };
450
451       paintable_type = g_type_register_static (G_TYPE_INTERFACE,
452                                                g_intern_static_string ("GdkPaintable"),
453                                                &paintable_info, 0);
454
455       g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
456     }
457
458   return paintable_type;
459 }
460
461 static void
462 gdk_window_init (GdkWindowObject *window)
463 {
464   /* 0-initialization is good for all other fields. */
465
466   window->window_type = GDK_WINDOW_CHILD;
467
468   window->state = GDK_WINDOW_STATE_WITHDRAWN;
469   window->width = 1;
470   window->height = 1;
471   window->toplevel_window_type = -1;
472   /* starts hidden */
473   window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
474   window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
475   /* Default to unobscured since some backends don't send visibility events */
476   window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
477 }
478
479 /* Stop and return on the first non-NULL parent */
480 static gboolean
481 accumulate_get_window (GSignalInvocationHint *ihint,
482                        GValue                  *return_accu,
483                        const GValue            *handler_return,
484                        gpointer               data)
485 {
486   g_value_copy (handler_return, return_accu);
487   /* Continue while returning NULL */
488   return g_value_get_object (handler_return) == NULL;
489 }
490
491 static GQuark quark_pointer_window = 0;
492
493 static void
494 gdk_window_class_init (GdkWindowObjectClass *klass)
495 {
496   GObjectClass *object_class = G_OBJECT_CLASS (klass);
497   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
498
499   parent_class = g_type_class_peek_parent (klass);
500
501   object_class->finalize = gdk_window_finalize;
502   object_class->set_property = gdk_window_set_property;
503   object_class->get_property = gdk_window_get_property;
504
505   drawable_class->create_gc = gdk_window_create_gc;
506   drawable_class->draw_rectangle = gdk_window_draw_rectangle;
507   drawable_class->draw_arc = gdk_window_draw_arc;
508   drawable_class->draw_polygon = gdk_window_draw_polygon;
509   drawable_class->draw_drawable_with_src = gdk_window_draw_drawable;
510   drawable_class->draw_points = gdk_window_draw_points;
511   drawable_class->draw_segments = gdk_window_draw_segments;
512   drawable_class->draw_lines = gdk_window_draw_lines;
513   drawable_class->draw_glyphs = gdk_window_draw_glyphs;
514   drawable_class->draw_glyphs_transformed = gdk_window_draw_glyphs_transformed;
515   drawable_class->draw_image = gdk_window_draw_image;
516   drawable_class->draw_pixbuf = gdk_window_draw_pixbuf;
517   drawable_class->draw_trapezoids = gdk_window_draw_trapezoids;
518   drawable_class->get_depth = gdk_window_real_get_depth;
519   drawable_class->get_screen = gdk_window_real_get_screen;
520   drawable_class->get_size = gdk_window_real_get_size;
521   drawable_class->set_colormap = gdk_window_real_set_colormap;
522   drawable_class->get_colormap = gdk_window_real_get_colormap;
523   drawable_class->get_visual = gdk_window_real_get_visual;
524   drawable_class->_copy_to_image = gdk_window_copy_to_image;
525   drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
526   drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
527   drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
528   drawable_class->get_clip_region = gdk_window_get_clip_region;
529   drawable_class->get_visible_region = gdk_window_get_visible_region;
530   drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
531   drawable_class->get_source_drawable = gdk_window_get_source_drawable;
532
533   quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
534
535
536   /* Properties */
537
538   /**
539    * GdkWindow:cursor:
540    *
541    * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
542    * gdk_window_get_cursor() for details.
543    *
544    * Since: 2.18
545    */
546   g_object_class_install_property (object_class,
547                                    PROP_CURSOR,
548                                    g_param_spec_boxed ("cursor",
549                                                        P_("Cursor"),
550                                                        P_("Cursor"),
551                                                        GDK_TYPE_CURSOR,
552                                                        G_PARAM_READWRITE));
553
554   /**
555    * GdkWindow::pick-embedded-child:
556    * @window: the window on which the signal is emitted
557    * @x: x coordinate in the window
558    * @y: y coordinate in the window
559    *
560    * The ::pick-embedded-child signal is emitted to find an embedded
561    * child at the given position.
562    *
563    * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
564    *
565    * Since: 2.18
566    */
567   signals[PICK_EMBEDDED_CHILD] =
568     g_signal_new (g_intern_static_string ("pick-embedded-child"),
569                   G_OBJECT_CLASS_TYPE (object_class),
570                   G_SIGNAL_RUN_LAST,
571                   0,
572                   accumulate_get_window, NULL,
573                   _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
574                   GDK_TYPE_WINDOW,
575                   2,
576                   G_TYPE_DOUBLE,
577                   G_TYPE_DOUBLE);
578
579   /**
580    * GdkWindow::to-embedder:
581    * @window: the offscreen window on which the signal is emitted
582    * @offscreen-x: x coordinate in the offscreen window
583    * @offscreen-y: y coordinate in the offscreen window
584    * @embedder-x: return location for the x coordinate in the embedder window
585    * @embedder-y: return location for the y coordinate in the embedder window
586    *
587    * The ::to-embedder signal is emitted to translate coordinates
588    * in an offscreen window to its embedder.
589    *
590    * See also #GtkWindow::from-embedder.
591    *
592    * Since: 2.18
593    */
594   signals[TO_EMBEDDER] =
595     g_signal_new (g_intern_static_string ("to-embedder"),
596                   G_OBJECT_CLASS_TYPE (object_class),
597                   G_SIGNAL_RUN_LAST,
598                   0,
599                   NULL, NULL,
600                   _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
601                   G_TYPE_NONE,
602                   4,
603                   G_TYPE_DOUBLE,
604                   G_TYPE_DOUBLE,
605                   G_TYPE_POINTER,
606                   G_TYPE_POINTER);
607
608   /**
609    * GdkWindow::from-embedder:
610    * @window: the offscreen window on which the signal is emitted
611    * @embedder-x: x coordinate in the embedder window
612    * @embedder-y: y coordinate in the embedder window
613    * @offscreen-x: return location for the x coordinate in the offscreen window
614    * @offscreen-y: return location for the y coordinate in the offscreen window
615    *
616    * The ::from-embedder signal is emitted to translate coordinates
617    * in the embedder of an offscreen window to the offscreen window.
618    *
619    * See also #GtkWindow::to-embedder.
620    *
621    * Since: 2.18
622    */
623   signals[FROM_EMBEDDER] =
624     g_signal_new (g_intern_static_string ("from-embedder"),
625                   G_OBJECT_CLASS_TYPE (object_class),
626                   G_SIGNAL_RUN_LAST,
627                   0,
628                   NULL, NULL,
629                   _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
630                   G_TYPE_NONE,
631                   4,
632                   G_TYPE_DOUBLE,
633                   G_TYPE_DOUBLE,
634                   G_TYPE_POINTER,
635                   G_TYPE_POINTER);
636 }
637
638 static void
639 device_removed_cb (GdkDeviceManager *device_manager,
640                    GdkDevice        *device,
641                    GdkWindow        *window)
642 {
643   GdkWindowObject *private;
644
645   private = (GdkWindowObject *) window;
646
647   private->devices_inside = g_list_remove (private->devices_inside, device);
648   g_hash_table_remove (private->device_cursor, device);
649
650   if (private->device_events)
651     g_hash_table_remove (private->device_events, device);
652 }
653
654 static void
655 gdk_window_finalize (GObject *object)
656 {
657   GdkWindow *window = GDK_WINDOW (object);
658   GdkWindowObject *obj = (GdkWindowObject *) object;
659   GdkDeviceManager *device_manager;
660
661   device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (window)));
662   g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
663
664   if (!GDK_WINDOW_DESTROYED (window))
665     {
666       if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
667         {
668           g_warning ("losing last reference to undestroyed window\n");
669           _gdk_window_destroy (window, FALSE);
670         }
671       else
672         /* We use TRUE here, to keep us from actually calling
673          * XDestroyWindow() on the window
674          */
675         _gdk_window_destroy (window, TRUE);
676     }
677
678   if (obj->impl)
679     {
680       g_object_unref (obj->impl);
681       obj->impl = NULL;
682     }
683
684   if (obj->impl_window != obj)
685     {
686       g_object_unref (obj->impl_window);
687       obj->impl_window = NULL;
688     }
689
690   if (obj->shape)
691     gdk_region_destroy (obj->shape);
692
693   if (obj->input_shape)
694     gdk_region_destroy (obj->input_shape);
695
696   if (obj->cursor)
697     gdk_cursor_unref (obj->cursor);
698
699   if (obj->device_cursor)
700     g_hash_table_destroy (obj->device_cursor);
701
702   if (obj->device_events)
703     g_hash_table_destroy (obj->device_events);
704
705   if (obj->devices_inside)
706     g_list_free (obj->devices_inside);
707
708   G_OBJECT_CLASS (parent_class)->finalize (object);
709 }
710
711 static void
712 gdk_window_set_property (GObject      *object,
713                          guint         prop_id,
714                          const GValue *value,
715                          GParamSpec   *pspec)
716 {
717   GdkWindow *window = (GdkWindow *)object;
718
719   switch (prop_id)
720     {
721     case PROP_CURSOR:
722       gdk_window_set_cursor (window, g_value_get_boxed (value));
723       break;
724
725     default:
726       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
727       break;
728     }
729 }
730
731 static void
732 gdk_window_get_property (GObject    *object,
733                          guint       prop_id,
734                          GValue     *value,
735                          GParamSpec *pspec)
736 {
737   GdkWindow *window = (GdkWindow *) object;
738
739   switch (prop_id)
740     {
741     case PROP_CURSOR:
742       g_value_set_boxed (value, gdk_window_get_cursor (window));
743       break;
744
745     default:
746       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
747       break;
748     }
749 }
750
751 static gboolean
752 gdk_window_is_offscreen (GdkWindowObject *window)
753 {
754   return window->window_type == GDK_WINDOW_OFFSCREEN;
755 }
756
757 static GdkWindowObject *
758 gdk_window_get_impl_window (GdkWindowObject *window)
759 {
760   return window->impl_window;
761 }
762
763 GdkWindow *
764 _gdk_window_get_impl_window (GdkWindow *window)
765 {
766   return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
767 }
768
769 static gboolean
770 gdk_window_has_impl (GdkWindowObject *window)
771 {
772   return window->impl_window == window;
773 }
774
775 static gboolean
776 gdk_window_is_toplevel (GdkWindowObject *window)
777 {
778   return
779     window->parent == NULL ||
780     window->parent->window_type == GDK_WINDOW_ROOT;
781 }
782
783 gboolean
784 _gdk_window_has_impl (GdkWindow *window)
785 {
786   return gdk_window_has_impl ((GdkWindowObject *)window);
787 }
788
789 static gboolean
790 gdk_window_has_no_impl (GdkWindowObject *window)
791 {
792   return window->impl_window != window;
793 }
794
795 static void
796 remove_child_area (GdkWindowObject *private,
797                    GdkWindowObject *until,
798                    gboolean for_input,
799                    GdkRegion *region)
800 {
801   GdkWindowObject *child;
802   GdkRegion *child_region;
803   GdkRectangle r;
804   GList *l;
805   GdkRegion *shape;
806
807   for (l = private->children; l; l = l->next)
808     {
809       child = l->data;
810
811       if (child == until)
812         break;
813
814       /* If region is empty already, no need to do
815          anything potentially costly */
816       if (gdk_region_empty (region))
817         break;
818
819       if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
820         continue;
821
822       /* Ignore offscreen children, as they don't draw in their parent and
823        * don't take part in the clipping */
824       if (gdk_window_is_offscreen (child))
825         continue;
826
827       r.x = child->x;
828       r.y = child->y;
829       r.width = child->width;
830       r.height = child->height;
831
832       /* Bail early if child totally outside region */
833       if (gdk_region_rect_in (region, &r) == GDK_OVERLAP_RECTANGLE_OUT)
834         continue;
835
836       child_region = gdk_region_rectangle (&r);
837
838       if (child->shape)
839         {
840           /* Adjust shape region to parent window coords */
841           gdk_region_offset (child->shape, child->x, child->y);
842           gdk_region_intersect (child_region, child->shape);
843           gdk_region_offset (child->shape, -child->x, -child->y);
844         }
845       else if (private->window_type == GDK_WINDOW_FOREIGN)
846         {
847           shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
848           if (shape)
849             {
850               gdk_region_intersect (child_region, shape);
851               gdk_region_destroy (shape);
852             }
853         }
854
855       if (for_input)
856         {
857           if (child->input_shape)
858             gdk_region_intersect (child_region, child->input_shape);
859           else if (private->window_type == GDK_WINDOW_FOREIGN)
860             {
861               shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
862               if (shape)
863                 {
864                   gdk_region_intersect (child_region, shape);
865                   gdk_region_destroy (shape);
866                 }
867             }
868         }
869
870       gdk_region_subtract (region, child_region);
871       gdk_region_destroy (child_region);
872
873     }
874 }
875
876 static GdkVisibilityState
877 effective_visibility (GdkWindowObject *private)
878 {
879   GdkVisibilityState native;
880
881   if (!gdk_window_is_viewable ((GdkWindow *)private))
882     return GDK_VISIBILITY_NOT_VIEWABLE;
883
884   native = private->impl_window->native_visibility;
885
886   if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
887       private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
888     return GDK_VISIBILITY_FULLY_OBSCURED;
889   else if (native == GDK_VISIBILITY_UNOBSCURED)
890     return private->visibility;
891   else /* native PARTIAL, private partial or unobscured  */
892     return GDK_VISIBILITY_PARTIAL;
893 }
894
895 static void
896 gdk_window_update_visibility (GdkWindowObject *private)
897 {
898   GdkVisibilityState new_visibility;
899   GdkEvent *event;
900
901   new_visibility = effective_visibility (private);
902
903   if (new_visibility != private->effective_visibility)
904     {
905       private->effective_visibility = new_visibility;
906
907       if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
908           private->event_mask & GDK_VISIBILITY_NOTIFY)
909         {
910           event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
911                                    NULL, FALSE);
912           event->visibility.state = new_visibility;
913         }
914     }
915 }
916
917 static void
918 gdk_window_update_visibility_recursively (GdkWindowObject *private,
919                                           GdkWindowObject *only_for_impl)
920 {
921   GdkWindowObject *child;
922   GList *l;
923
924   gdk_window_update_visibility (private);
925   for (l = private->children; l != NULL; l = l->next)
926     {
927       child = l->data;
928       if ((only_for_impl == NULL) ||
929           (only_for_impl == child->impl_window))
930         gdk_window_update_visibility_recursively (child, only_for_impl);
931     }
932 }
933
934 static gboolean
935 should_apply_clip_as_shape (GdkWindowObject *private)
936 {
937   return
938     gdk_window_has_impl (private) &&
939     /* Not for offscreens */
940     !gdk_window_is_offscreen (private) &&
941     /* or for toplevels */
942     !gdk_window_is_toplevel (private) &&
943     /* or for foreign windows */
944     private->window_type != GDK_WINDOW_FOREIGN &&
945     /* or for the root window */
946     private->window_type != GDK_WINDOW_ROOT;
947 }
948
949 static void
950 apply_shape (GdkWindowObject *private,
951              GdkRegion *region)
952 {
953   GdkWindowImplIface *impl_iface;
954
955   /* We trash whether we applied a shape so that
956      we can avoid unsetting it many times, which
957      could happen in e.g. apply_clip_as_shape as
958      windows get resized */
959   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
960   if (region)
961     impl_iface->shape_combine_region ((GdkWindow *)private,
962                                       region, 0, 0);
963   else if (private->applied_shape)
964     impl_iface->shape_combine_region ((GdkWindow *)private,
965                                       NULL, 0, 0);
966
967   private->applied_shape = region != NULL;
968 }
969
970 static void
971 apply_clip_as_shape (GdkWindowObject *private)
972 {
973   GdkRectangle r;
974
975   r.x = r.y = 0;
976   r.width = private->width;
977   r.height = private->height;
978
979   /* We only apply the clip region if would differ
980      from the actual clip region implied by the size
981      of the window. This is to avoid unneccessarily
982      adding meaningless shapes to all native subwindows */
983   if (!gdk_region_rect_equal (private->clip_region, &r))
984     apply_shape (private, private->clip_region);
985   else
986     apply_shape (private, NULL);
987 }
988
989 static void
990 recompute_visible_regions_internal (GdkWindowObject *private,
991                                     gboolean recalculate_clip,
992                                     gboolean recalculate_siblings,
993                                     gboolean recalculate_children)
994 {
995   GdkRectangle r;
996   GList *l;
997   GdkWindowObject *child;
998   GdkRegion *new_clip, *old_clip_region_with_children;
999   gboolean clip_region_changed;
1000   gboolean abs_pos_changed;
1001   int old_abs_x, old_abs_y;
1002
1003   old_abs_x = private->abs_x;
1004   old_abs_y = private->abs_y;
1005
1006   /* Update absolute position */
1007   if (gdk_window_has_impl (private))
1008     {
1009       /* Native window starts here */
1010       private->abs_x = 0;
1011       private->abs_y = 0;
1012     }
1013   else
1014     {
1015       private->abs_x = private->parent->abs_x + private->x;
1016       private->abs_y = private->parent->abs_y + private->y;
1017     }
1018
1019   abs_pos_changed =
1020     private->abs_x != old_abs_x ||
1021     private->abs_y != old_abs_y;
1022
1023   /* Update clip region based on:
1024    * parent clip
1025    * window size
1026    * siblings in parents above window
1027    */
1028   clip_region_changed = FALSE;
1029   if (recalculate_clip)
1030     {
1031       if (private->viewable)
1032         {
1033           /* Calculate visible region (sans children) in parent window coords */
1034           r.x = private->x;
1035           r.y = private->y;
1036           r.width = private->width;
1037           r.height = private->height;
1038           new_clip = gdk_region_rectangle (&r);
1039
1040           if (!gdk_window_is_toplevel (private))
1041             {
1042               gdk_region_intersect (new_clip, private->parent->clip_region);
1043
1044               /* Remove all overlapping children from parent.
1045                * Unless we're all native, because then we don't need to take
1046                * siblings into account since X does that clipping for us.
1047                * This makes things like SWT that modify the raw X stacking
1048                * order without GDKs knowledge work.
1049                */
1050               if (!_gdk_native_windows)
1051                 remove_child_area (private->parent, private, FALSE, new_clip);
1052             }
1053
1054           /* Convert from parent coords to window coords */
1055           gdk_region_offset (new_clip, -private->x, -private->y);
1056
1057           if (private->shape)
1058             gdk_region_intersect (new_clip, private->shape);
1059         }
1060       else
1061         new_clip = gdk_region_new ();
1062
1063       if (private->clip_region == NULL ||
1064           !gdk_region_equal (private->clip_region, new_clip))
1065         clip_region_changed = TRUE;
1066
1067       if (private->clip_region)
1068         gdk_region_destroy (private->clip_region);
1069       private->clip_region = new_clip;
1070
1071       old_clip_region_with_children = private->clip_region_with_children;
1072       private->clip_region_with_children = gdk_region_copy (private->clip_region);
1073       if (private->window_type != GDK_WINDOW_ROOT)
1074         remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
1075
1076       if (clip_region_changed ||
1077           !gdk_region_equal (private->clip_region_with_children, old_clip_region_with_children))
1078           private->clip_tag = new_region_tag ();
1079
1080       if (old_clip_region_with_children)
1081         gdk_region_destroy (old_clip_region_with_children);
1082     }
1083
1084   if (clip_region_changed)
1085     {
1086       GdkVisibilityState visibility;
1087       gboolean fully_visible;
1088
1089       if (gdk_region_empty (private->clip_region))
1090         visibility = GDK_VISIBILITY_FULLY_OBSCURED;
1091       else
1092         {
1093           if (private->shape)
1094             {
1095               fully_visible = gdk_region_equal (private->clip_region,
1096                                                 private->shape);
1097             }
1098           else
1099             {
1100               r.x = 0;
1101               r.y = 0;
1102               r.width = private->width;
1103               r.height = private->height;
1104               fully_visible = gdk_region_rect_equal (private->clip_region, &r);
1105             }
1106
1107           if (fully_visible)
1108             visibility = GDK_VISIBILITY_UNOBSCURED;
1109           else
1110             visibility = GDK_VISIBILITY_PARTIAL;
1111         }
1112
1113       if (private->visibility != visibility)
1114         {
1115           private->visibility = visibility;
1116           gdk_window_update_visibility (private);
1117         }
1118     }
1119
1120   /* Update all children, recursively (except for root, where children are not exact). */
1121   if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1122       private->window_type != GDK_WINDOW_ROOT)
1123     {
1124       for (l = private->children; l; l = l->next)
1125         {
1126           child = l->data;
1127           /* Only recalculate clip if the the clip region changed, otherwise
1128            * there is no way the child clip region could change (its has not e.g. moved)
1129            * Except if recalculate_children is set to force child updates
1130            */
1131           recompute_visible_regions_internal (child,
1132                                               recalculate_clip && (clip_region_changed || recalculate_children),
1133                                               FALSE, FALSE);
1134         }
1135     }
1136
1137   if (clip_region_changed &&
1138       should_apply_clip_as_shape (private))
1139     apply_clip_as_shape (private);
1140
1141   if (recalculate_siblings &&
1142       !gdk_window_is_toplevel (private))
1143     {
1144       /* If we moved a child window in parent or changed the stacking order, then we
1145        * need to recompute the visible area of all the other children in the parent
1146        */
1147       for (l = private->parent->children; l; l = l->next)
1148         {
1149           child = l->data;
1150
1151           if (child != private)
1152             recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1153         }
1154
1155       /* We also need to recompute the _with_children clip for the parent */
1156       recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1157     }
1158
1159   if (private->cairo_surface)
1160     {
1161       int width, height;
1162
1163       /* It would be nice if we had some cairo support here so we
1164          could set the clip rect on the cairo surface */
1165       width = private->abs_x + private->width;
1166       height = private->abs_y + private->height;
1167
1168       _gdk_windowing_set_cairo_surface_size (private->cairo_surface,
1169                                              width, height);
1170       cairo_surface_set_device_offset (private->cairo_surface,
1171                                        private->abs_x,
1172                                        private->abs_y);
1173     }
1174 }
1175
1176 /* Call this when private has changed in one or more of these ways:
1177  *  size changed
1178  *  window moved
1179  *  new window added
1180  *  stacking order of window changed
1181  *  child deleted
1182  *
1183  * It will recalculate abs_x/y and the clip regions
1184  *
1185  * Unless the window didn't change stacking order or size/pos, pass in TRUE
1186  * for recalculate_siblings. (Mostly used internally for the recursion)
1187  *
1188  * If a child window was removed (and you can't use that child for
1189  * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1190  */
1191 static void
1192 recompute_visible_regions (GdkWindowObject *private,
1193                            gboolean recalculate_siblings,
1194                            gboolean recalculate_children)
1195 {
1196   recompute_visible_regions_internal (private,
1197                                       TRUE,
1198                                       recalculate_siblings,
1199                                       recalculate_children);
1200 }
1201
1202 void
1203 _gdk_window_update_size (GdkWindow *window)
1204 {
1205   recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1206 }
1207
1208 /* Find the native window that would be just above "child"
1209  * in the native stacking order if "child" was a native window
1210  * (it doesn't have to be native). If there is no such native
1211  * window inside this native parent then NULL is returned.
1212  * If child is NULL, find lowest native window in parent.
1213  */
1214 static GdkWindowObject *
1215 find_native_sibling_above_helper (GdkWindowObject *parent,
1216                                   GdkWindowObject *child)
1217 {
1218   GdkWindowObject *w;
1219   GList *l;
1220
1221   if (child)
1222     {
1223       l = g_list_find (parent->children, child);
1224       g_assert (l != NULL); /* Better be a child of its parent... */
1225       l = l->prev; /* Start looking at the one above the child */
1226     }
1227   else
1228     l = g_list_last (parent->children);
1229
1230   for (; l != NULL; l = l->prev)
1231     {
1232       w = l->data;
1233
1234       if (gdk_window_has_impl (w))
1235         return w;
1236
1237       g_assert (parent != w);
1238       w = find_native_sibling_above_helper (w, NULL);
1239       if (w)
1240         return w;
1241     }
1242
1243   return NULL;
1244 }
1245
1246
1247 static GdkWindowObject *
1248 find_native_sibling_above (GdkWindowObject *parent,
1249                            GdkWindowObject *child)
1250 {
1251   GdkWindowObject *w;
1252
1253   w = find_native_sibling_above_helper (parent, child);
1254   if (w)
1255     return w;
1256
1257   if (gdk_window_has_impl (parent))
1258     return NULL;
1259   else
1260     return find_native_sibling_above (parent->parent, parent);
1261 }
1262
1263 static GdkEventMask
1264 get_native_device_event_mask (GdkWindowObject *private,
1265                               GdkDevice       *device)
1266 {
1267   GdkEventMask event_mask;
1268
1269   if (device)
1270     event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1271   else
1272     event_mask = private->event_mask;
1273
1274   if (_gdk_native_windows ||
1275       private->window_type == GDK_WINDOW_ROOT ||
1276       private->window_type == GDK_WINDOW_FOREIGN)
1277     return event_mask;
1278   else
1279     {
1280       GdkEventMask mask;
1281
1282       /* Do whatever the app asks to, since the app
1283        * may be asking for weird things for native windows,
1284        * but don't use motion hints as that may affect non-native
1285        * child windows that don't want it. Also, we need to
1286        * set all the app-specified masks since they will be picked
1287        * up by any implicit grabs (i.e. if they were not set as
1288        * native we would not get the events we need). */
1289       mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1290
1291       /* We need thse for all native windows so we can
1292          emulate events on children: */
1293       mask |=
1294         GDK_EXPOSURE_MASK |
1295         GDK_VISIBILITY_NOTIFY_MASK |
1296         GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1297
1298       /* Additionally we select for pointer and button events
1299        * for toplevels as we need to get these to emulate
1300        * them for non-native subwindows. Even though we don't
1301        * select on them for all native windows we will get them
1302        * as the events are propagated out to the first window
1303        * that select for them.
1304        * Not selecting for button press on all windows is an
1305        * important thing, because in X only one client can do
1306        * so, and we don't want to unexpectedly prevent another
1307        * client from doing it.
1308        *
1309        * We also need to do the same if the app selects for button presses
1310        * because then we will get implicit grabs for this window, and the
1311        * event mask used for that grab is based on the rest of the mask
1312        * for the window, but we might need more events than this window
1313        * lists due to some non-native child window.
1314        */
1315       if (gdk_window_is_toplevel (private) ||
1316           mask & GDK_BUTTON_PRESS_MASK)
1317         mask |=
1318           GDK_POINTER_MOTION_MASK |
1319           GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1320           GDK_SCROLL_MASK;
1321
1322       return mask;
1323     }
1324 }
1325
1326 static GdkEventMask
1327 get_native_grab_event_mask (GdkEventMask grab_mask)
1328 {
1329   /* Similar to the above but for pointer events only */
1330   return
1331     GDK_POINTER_MOTION_MASK |
1332     GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1333     GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1334     GDK_SCROLL_MASK |
1335     (grab_mask &
1336      ~GDK_POINTER_MOTION_HINT_MASK);
1337 }
1338
1339 static GdkEventMask
1340 get_native_event_mask (GdkWindowObject *private)
1341 {
1342   return get_native_device_event_mask (private, NULL);
1343 }
1344
1345 /* Puts the native window in the right order wrt the other native windows
1346  * in the hierarchy, given the position it has in the client side data.
1347  * This is useful if some operation changed the stacking order.
1348  * This calls assumes the native window is now topmost in its native parent.
1349  */
1350 static void
1351 sync_native_window_stack_position (GdkWindow *window)
1352 {
1353   GdkWindowObject *above;
1354   GdkWindowObject *private;
1355   GdkWindowImplIface *impl_iface;
1356   GList listhead = {0};
1357
1358   private = (GdkWindowObject *) window;
1359   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1360
1361   above = find_native_sibling_above (private->parent, private);
1362   if (above)
1363     {
1364       listhead.data = window;
1365       impl_iface->restack_under ((GdkWindow *)above,
1366                                  &listhead);
1367     }
1368 }
1369
1370 /**
1371  * gdk_window_new:
1372  * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1373  *   the default root window for the default display.
1374  * @attributes: attributes of the new window
1375  * @attributes_mask: mask indicating which fields in @attributes are valid
1376  *
1377  * Creates a new #GdkWindow using the attributes from
1378  * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1379  * more details.  Note: to use this on displays other than the default
1380  * display, @parent must be specified.
1381  *
1382  * Return value: (transfer none): the new #GdkWindow
1383  **/
1384 GdkWindow*
1385 gdk_window_new (GdkWindow     *parent,
1386                 GdkWindowAttr *attributes,
1387                 gint           attributes_mask)
1388 {
1389   GdkWindow *window;
1390   GdkWindowObject *private;
1391   GdkScreen *screen;
1392   GdkVisual *visual;
1393   int x, y;
1394   gboolean native;
1395   GdkEventMask event_mask;
1396   GdkWindow *real_parent;
1397   GdkDeviceManager *device_manager;
1398
1399   g_return_val_if_fail (attributes != NULL, NULL);
1400
1401   if (!parent)
1402     {
1403       GDK_NOTE (MULTIHEAD,
1404                 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1405
1406       screen = gdk_screen_get_default ();
1407       parent = gdk_screen_get_root_window (screen);
1408     }
1409   else
1410     screen = gdk_drawable_get_screen (parent);
1411
1412   g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1413
1414   if (GDK_WINDOW_DESTROYED (parent))
1415     {
1416       g_warning ("gdk_window_new(): parent is destroyed\n");
1417       return NULL;
1418     }
1419
1420   if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1421       _gdk_native_windows)
1422     {
1423       g_warning ("Offscreen windows not supported with native-windows gdk");
1424       return NULL;
1425     }
1426
1427   window = g_object_new (GDK_TYPE_WINDOW, NULL);
1428   private = (GdkWindowObject *) window;
1429
1430   /* Windows with a foreign parent are treated as if they are children
1431    * of the root window, except for actual creation.
1432    */
1433   real_parent = parent;
1434   if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1435     parent = gdk_screen_get_root_window (screen);
1436
1437   private->parent = (GdkWindowObject *)parent;
1438
1439   private->accept_focus = TRUE;
1440   private->focus_on_map = TRUE;
1441
1442   if (attributes_mask & GDK_WA_X)
1443     x = attributes->x;
1444   else
1445     x = 0;
1446
1447   if (attributes_mask & GDK_WA_Y)
1448     y = attributes->y;
1449   else
1450     y = 0;
1451
1452   private->x = x;
1453   private->y = y;
1454   private->width = (attributes->width > 1) ? (attributes->width) : (1);
1455   private->height = (attributes->height > 1) ? (attributes->height) : (1);
1456
1457 #ifdef GDK_WINDOWING_X11
1458   /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1459    * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1460    */
1461   if (attributes->wclass == GDK_INPUT_ONLY &&
1462       private->parent->window_type == GDK_WINDOW_ROOT &&
1463       !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1464     {
1465       g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1466       attributes->wclass = GDK_INPUT_OUTPUT;
1467     }
1468 #endif
1469
1470   if (attributes->wclass == GDK_INPUT_ONLY)
1471     {
1472       /* Backwards compatiblity - we've always ignored
1473        * attributes->window_type for input-only windows
1474        * before
1475        */
1476       if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1477         private->window_type = GDK_WINDOW_TEMP;
1478       else
1479         private->window_type = GDK_WINDOW_CHILD;
1480     }
1481   else
1482     private->window_type = attributes->window_type;
1483
1484   /* Sanity checks */
1485   switch (private->window_type)
1486     {
1487     case GDK_WINDOW_TOPLEVEL:
1488     case GDK_WINDOW_DIALOG:
1489     case GDK_WINDOW_TEMP:
1490     case GDK_WINDOW_OFFSCREEN:
1491       if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1492         g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1493                    "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1494     case GDK_WINDOW_CHILD:
1495       break;
1496       break;
1497     default:
1498       g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1499       return NULL;
1500     }
1501
1502   if (attributes_mask & GDK_WA_VISUAL)
1503     visual = attributes->visual;
1504   else
1505     visual = gdk_screen_get_system_visual (screen);
1506
1507   private->event_mask = attributes->event_mask;
1508
1509   if (attributes->wclass == GDK_INPUT_OUTPUT)
1510     {
1511       private->input_only = FALSE;
1512       private->depth = visual->depth;
1513
1514       private->bg_color.pixel = 0; /* TODO: BlackPixel (xdisplay, screen_x11->screen_num); */
1515       private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
1516
1517       private->bg_pixmap = NULL;
1518     }
1519   else
1520     {
1521       private->depth = 0;
1522       private->input_only = TRUE;
1523     }
1524
1525   if (private->parent)
1526     private->parent->children = g_list_prepend (private->parent->children, window);
1527
1528   native = _gdk_native_windows; /* Default */
1529   if (private->parent->window_type == GDK_WINDOW_ROOT)
1530     native = TRUE; /* Always use native windows for toplevels */
1531   else if (!private->input_only &&
1532            ((attributes_mask & GDK_WA_COLORMAP &&
1533              attributes->colormap != gdk_drawable_get_colormap ((GdkDrawable *)private->parent)) ||
1534             (attributes_mask & GDK_WA_VISUAL &&
1535              attributes->visual != gdk_drawable_get_visual ((GdkDrawable *)private->parent))))
1536     native = TRUE; /* InputOutput window with different colormap or visual than parent, needs native window */
1537
1538   if (gdk_window_is_offscreen (private))
1539     {
1540       _gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask);
1541       private->impl_window = private;
1542     }
1543   else if (native)
1544     {
1545       event_mask = get_native_event_mask (private);
1546
1547       /* Create the impl */
1548       _gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask);
1549       private->impl_window = private;
1550
1551       /* This will put the native window topmost in the native parent, which may
1552        * be wrong wrt other native windows in the non-native hierarchy, so restack */
1553       if (!_gdk_window_has_impl (real_parent))
1554         sync_native_window_stack_position (window);
1555     }
1556   else
1557     {
1558       private->impl_window = g_object_ref (private->parent->impl_window);
1559       private->impl = g_object_ref (private->impl_window->impl);
1560     }
1561
1562   recompute_visible_regions (private, TRUE, FALSE);
1563
1564   if (private->parent->window_type != GDK_WINDOW_ROOT)
1565     {
1566       /* Inherit redirection from parent */
1567       private->redirect = private->parent->redirect;
1568     }
1569
1570   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1571                                   (attributes->cursor) :
1572                                   NULL));
1573
1574   private->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1575                                                   (GDestroyNotify) gdk_cursor_unref);
1576
1577   device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (parent)));
1578   g_signal_connect (device_manager, "device-removed",
1579                     G_CALLBACK (device_removed_cb), window);
1580
1581   return window;
1582 }
1583
1584 static gboolean
1585 is_parent_of (GdkWindow *parent,
1586               GdkWindow *child)
1587 {
1588   GdkWindow *w;
1589
1590   w = child;
1591   while (w != NULL)
1592     {
1593       if (w == parent)
1594         return TRUE;
1595
1596       w = gdk_window_get_parent (w);
1597     }
1598
1599   return FALSE;
1600 }
1601
1602 static void
1603 change_impl (GdkWindowObject *private,
1604              GdkWindowObject *impl_window,
1605              GdkDrawable *new)
1606 {
1607   GList *l;
1608   GdkWindowObject *child;
1609   GdkDrawable *old_impl;
1610   GdkWindowObject *old_impl_window;
1611
1612   old_impl = private->impl;
1613   old_impl_window = private->impl_window;
1614   if (private != impl_window)
1615     private->impl_window = g_object_ref (impl_window);
1616   else
1617     private->impl_window = private;
1618   private->impl = g_object_ref (new);
1619   if (old_impl_window != private)
1620     g_object_unref (old_impl_window);
1621   g_object_unref (old_impl);
1622
1623   for (l = private->children; l != NULL; l = l->next)
1624     {
1625       child = l->data;
1626
1627       if (child->impl == old_impl)
1628         change_impl (child, impl_window, new);
1629     }
1630 }
1631
1632 static void
1633 reparent_to_impl (GdkWindowObject *private)
1634 {
1635   GList *l;
1636   GdkWindowObject *child;
1637   gboolean show;
1638   GdkWindowImplIface *impl_iface;
1639
1640   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1641
1642   /* Enumerate in reverse order so we get the right order for the native
1643      windows (first in childrens list is topmost, and reparent places on top) */
1644   for (l = g_list_last (private->children); l != NULL; l = l->prev)
1645     {
1646       child = l->data;
1647
1648       if (child->impl == private->impl)
1649         reparent_to_impl (child);
1650       else
1651         {
1652           show = impl_iface->reparent ((GdkWindow *)child,
1653                                        (GdkWindow *)private,
1654                                        child->x, child->y);
1655           if (show)
1656             gdk_window_show_unraised ((GdkWindow *)child);
1657         }
1658     }
1659 }
1660
1661
1662 /**
1663  * gdk_window_reparent:
1664  * @window: a #GdkWindow
1665  * @new_parent: new parent to move @window into
1666  * @x: X location inside the new parent
1667  * @y: Y location inside the new parent
1668  *
1669  * Reparents @window into the given @new_parent. The window being
1670  * reparented will be unmapped as a side effect.
1671  *
1672  **/
1673 void
1674 gdk_window_reparent (GdkWindow *window,
1675                      GdkWindow *new_parent,
1676                      gint       x,
1677                      gint       y)
1678 {
1679   GdkWindowObject *private;
1680   GdkWindowObject *new_parent_private;
1681   GdkWindowObject *old_parent;
1682   GdkScreen *screen;
1683   gboolean show, was_mapped, applied_clip_as_shape;
1684   gboolean do_reparent_to_impl;
1685   GdkEventMask old_native_event_mask;
1686   GdkWindowImplIface *impl_iface;
1687
1688   g_return_if_fail (GDK_IS_WINDOW (window));
1689   g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1690   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1691
1692   if (GDK_WINDOW_DESTROYED (window) ||
1693       (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1694     return;
1695
1696   screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
1697   if (!new_parent)
1698     new_parent = gdk_screen_get_root_window (screen);
1699
1700   private = (GdkWindowObject *) window;
1701   new_parent_private = (GdkWindowObject *)new_parent;
1702
1703   /* No input-output children of input-only windows */
1704   if (new_parent_private->input_only && !private->input_only)
1705     return;
1706
1707   /* Don't create loops in hierarchy */
1708   if (is_parent_of (window, new_parent))
1709     return;
1710
1711   /* This might be wrong in the new parent, e.g. for non-native surfaces.
1712      To make sure we're ok, just wipe it. */
1713   gdk_window_drop_cairo_surface (private);
1714
1715   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1716   old_parent = private->parent;
1717
1718   /* Break up redirection if inherited */
1719   if (private->redirect && private->redirect->redirected != private)
1720     {
1721       remove_redirect_from_children (private, private->redirect);
1722       private->redirect = NULL;
1723     }
1724
1725   was_mapped = GDK_WINDOW_IS_MAPPED (window);
1726   show = FALSE;
1727
1728   /* Reparenting to toplevel. Ensure we have a native window so this can work */
1729   if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1730       new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1731     gdk_window_ensure_native (window);
1732
1733   applied_clip_as_shape = should_apply_clip_as_shape (private);
1734
1735   old_native_event_mask = 0;
1736   do_reparent_to_impl = FALSE;
1737   if (gdk_window_has_impl (private))
1738     {
1739       old_native_event_mask = get_native_event_mask (private);
1740       /* Native window */
1741       show = impl_iface->reparent (window, new_parent, x, y);
1742     }
1743   else
1744     {
1745       /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1746       g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1747                 new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1748
1749       show = was_mapped;
1750       gdk_window_hide (window);
1751
1752       do_reparent_to_impl = TRUE;
1753       change_impl (private,
1754                    new_parent_private->impl_window,
1755                    new_parent_private->impl);
1756     }
1757
1758   /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1759    * the root window
1760    */
1761   if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1762     {
1763       new_parent = gdk_screen_get_root_window (screen);
1764       new_parent_private = (GdkWindowObject *)new_parent;
1765     }
1766
1767   if (old_parent)
1768     old_parent->children = g_list_remove (old_parent->children, window);
1769
1770   private->parent = new_parent_private;
1771   private->x = x;
1772   private->y = y;
1773
1774   new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1775
1776   /* Switch the window type as appropriate */
1777
1778   switch (GDK_WINDOW_TYPE (new_parent))
1779     {
1780     case GDK_WINDOW_ROOT:
1781     case GDK_WINDOW_FOREIGN:
1782       if (private->toplevel_window_type != -1)
1783         GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1784       else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1785         GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1786       break;
1787     case GDK_WINDOW_OFFSCREEN:
1788     case GDK_WINDOW_TOPLEVEL:
1789     case GDK_WINDOW_CHILD:
1790     case GDK_WINDOW_DIALOG:
1791     case GDK_WINDOW_TEMP:
1792       if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1793           GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1794         {
1795           /* Save the original window type so we can restore it if the
1796            * window is reparented back to be a toplevel
1797            */
1798           private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1799           GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1800         }
1801     }
1802
1803   /* We might have changed window type for a native windows, so we
1804      need to change the event mask too. */
1805   if (gdk_window_has_impl (private))
1806     {
1807       GdkEventMask native_event_mask = get_native_event_mask (private);
1808
1809       if (native_event_mask != old_native_event_mask)
1810         impl_iface->set_events (window, native_event_mask);
1811     }
1812
1813   /* Inherit parent redirect if we don't have our own */
1814   if (private->parent && private->redirect == NULL)
1815     {
1816       private->redirect = private->parent->redirect;
1817       apply_redirect_to_children (private, private->redirect);
1818     }
1819
1820   _gdk_window_update_viewable (window);
1821
1822   recompute_visible_regions (private, TRUE, FALSE);
1823   if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1824     recompute_visible_regions (old_parent, FALSE, TRUE);
1825
1826   /* We used to apply the clip as the shape, but no more.
1827      Reset this to the real shape */
1828   if (gdk_window_has_impl (private) &&
1829       applied_clip_as_shape &&
1830       !should_apply_clip_as_shape (private))
1831     apply_shape (private, private->shape);
1832
1833   if (do_reparent_to_impl)
1834     reparent_to_impl (private);
1835   else
1836     {
1837       /* The reparent will have put the native window topmost in the native parent,
1838        * which may be wrong wrt other native windows in the non-native hierarchy,
1839        * so restack */
1840       if (!gdk_window_has_impl (new_parent_private))
1841         sync_native_window_stack_position (window);
1842     }
1843
1844   if (show)
1845     gdk_window_show_unraised (window);
1846   else
1847     _gdk_synthesize_crossing_events_for_geometry_change (window);
1848 }
1849
1850 static gboolean
1851 temporary_disable_extension_events (GdkWindowObject *window)
1852 {
1853   GdkWindowObject *child;
1854   GList *l;
1855   gboolean res;
1856
1857   if (window->extension_events != 0)
1858     {
1859       g_object_set_data (G_OBJECT (window),
1860                          "gdk-window-extension-events",
1861                          GINT_TO_POINTER (window->extension_events));
1862       gdk_input_set_extension_events ((GdkWindow *)window, 0,
1863                                       GDK_EXTENSION_EVENTS_NONE);
1864     }
1865   else
1866     res = FALSE;
1867
1868   for (l = window->children; l != NULL; l = l->next)
1869     {
1870       child = l->data;
1871
1872       if (window->impl_window == child->impl_window)
1873         res |= temporary_disable_extension_events (child);
1874     }
1875
1876   return res;
1877 }
1878
1879 static void
1880 reenable_extension_events (GdkWindowObject *window)
1881 {
1882   GdkWindowObject *child;
1883   GList *l;
1884   int mask;
1885
1886   mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1887                                               "gdk-window-extension-events"));
1888
1889   if (mask != 0)
1890     {
1891       /* We don't have the mode here, so we pass in cursor.
1892          This works with the current code since mode is not
1893          stored except as part of the mask, and cursor doesn't
1894          change the mask. */
1895       gdk_input_set_extension_events ((GdkWindow *)window, mask,
1896                                       GDK_EXTENSION_EVENTS_CURSOR);
1897       g_object_set_data (G_OBJECT (window),
1898                          "gdk-window-extension-events",
1899                          NULL);
1900     }
1901
1902   for (l = window->children; l != NULL; l = l->next)
1903     {
1904       child = l->data;
1905
1906       if (window->impl_window == child->impl_window)
1907         reenable_extension_events (window);
1908     }
1909 }
1910
1911 /**
1912  * gdk_window_ensure_native:
1913  * @window: a #GdkWindow
1914  *
1915  * Tries to ensure that there is a window-system native window for this
1916  * GdkWindow. This may fail in some situations, returning %FALSE.
1917  *
1918  * Offscreen window and children of them can never have native windows.
1919  *
1920  * Some backends may not support native child windows.
1921  *
1922  * Returns: %TRUE if the window has a native window, %FALSE otherwise
1923  *
1924  * Since: 2.18
1925  */
1926 gboolean
1927 gdk_window_ensure_native (GdkWindow *window)
1928 {
1929   GdkWindowObject *private;
1930   GdkWindowObject *impl_window;
1931   GdkDrawable *new_impl, *old_impl;
1932   GdkScreen *screen;
1933   GdkVisual *visual;
1934   GdkWindowAttr attributes;
1935   GdkWindowObject *above;
1936   GList listhead;
1937   GdkWindowImplIface *impl_iface;
1938   gboolean disabled_extension_events;
1939
1940   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1941
1942   if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1943       GDK_WINDOW_DESTROYED (window))
1944     return FALSE;
1945
1946   private = (GdkWindowObject *) window;
1947
1948   impl_window = gdk_window_get_impl_window (private);
1949
1950   if (gdk_window_is_offscreen (impl_window))
1951     return FALSE; /* native in offscreens not supported */
1952
1953   if (impl_window == private)
1954     /* Already has an impl, and its not offscreen . */
1955     return TRUE;
1956
1957   /* Need to create a native window */
1958
1959   /* First we disable any extension events on the window or its
1960      descendants to handle the native input window moving */
1961   disabled_extension_events = FALSE;
1962   if (impl_window->input_window)
1963     disabled_extension_events = temporary_disable_extension_events (private);
1964
1965   gdk_window_drop_cairo_surface (private);
1966
1967   screen = gdk_drawable_get_screen (window);
1968   visual = gdk_drawable_get_visual (window);
1969
1970   attributes.colormap = gdk_drawable_get_colormap (window);
1971
1972   old_impl = private->impl;
1973   _gdk_window_impl_new (window, (GdkWindow *)private->parent,
1974                         screen, visual,
1975                         get_native_event_mask (private),
1976                         &attributes, GDK_WA_COLORMAP);
1977   new_impl = private->impl;
1978
1979   private->impl = old_impl;
1980   change_impl (private, private, new_impl);
1981
1982   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1983
1984   /* Native window creation will put the native window topmost in the
1985    * native parent, which may be wrong wrt the position of the previous
1986    * non-native window wrt to the other non-native children, so correct this.
1987    */
1988   above = find_native_sibling_above (private->parent, private);
1989   if (above)
1990     {
1991       listhead.data = window;
1992       listhead.prev = NULL;
1993       listhead.next = NULL;
1994       impl_iface->restack_under ((GdkWindow *)above, &listhead);
1995     }
1996
1997   recompute_visible_regions (private, FALSE, FALSE);
1998
1999   /* The shape may not have been set, as the clip region doesn't actually
2000      change, so do it here manually */
2001   if (should_apply_clip_as_shape (private))
2002     apply_clip_as_shape (private);
2003
2004   reparent_to_impl (private);
2005
2006   if (!private->input_only)
2007     {
2008       impl_iface->set_background (window, &private->bg_color);
2009       if (private->bg_pixmap != NULL)
2010         impl_iface->set_back_pixmap (window, private->bg_pixmap);
2011     }
2012
2013   impl_iface->input_shape_combine_region (window,
2014                                           private->input_shape,
2015                                           0, 0);
2016
2017   if (gdk_window_is_viewable (window))
2018     impl_iface->show (window, FALSE);
2019
2020   if (disabled_extension_events)
2021     reenable_extension_events (private);
2022
2023   return TRUE;
2024 }
2025
2026 static void
2027 window_remove_filters (GdkWindow *window)
2028 {
2029   GdkWindowObject *obj = (GdkWindowObject*) window;
2030
2031   if (obj->filters)
2032     {
2033       GList *tmp_list;
2034
2035       for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
2036         g_free (tmp_list->data);
2037
2038       g_list_free (obj->filters);
2039       obj->filters = NULL;
2040     }
2041 }
2042
2043 static void
2044 update_pointer_info_foreach (GdkDisplay           *display,
2045                              GdkDevice            *device,
2046                              GdkPointerWindowInfo *pointer_info,
2047                              gpointer              user_data)
2048 {
2049   GdkWindow *window = user_data;
2050
2051   if (pointer_info->toplevel_under_pointer == window)
2052     {
2053       g_object_unref (pointer_info->toplevel_under_pointer);
2054       pointer_info->toplevel_under_pointer = NULL;
2055     }
2056 }
2057
2058 static void
2059 window_remove_from_pointer_info (GdkWindow  *window,
2060                                  GdkDisplay *display)
2061 {
2062   _gdk_display_pointer_info_foreach (display,
2063                                      update_pointer_info_foreach,
2064                                      window);
2065 }
2066
2067 /**
2068  * _gdk_window_destroy_hierarchy:
2069  * @window: a #GdkWindow
2070  * @recursing: If TRUE, then this is being called because a parent
2071  *            was destroyed.
2072  * @recursing_native: If TRUE, then this is being called because a native parent
2073  *            was destroyed. This generally means that the call to the
2074  *            windowing system to destroy the window can be omitted, since
2075  *            it will be destroyed as a result of the parent being destroyed.
2076  *            Unless @foreign_destroy.
2077  * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2078  *            external agency. The window has already been destroyed and no
2079  *            windowing system calls should be made. (This may never happen
2080  *            for some windowing systems.)
2081  *
2082  * Internal function to destroy a window. Like gdk_window_destroy(),
2083  * but does not drop the reference count created by gdk_window_new().
2084  **/
2085 static void
2086 _gdk_window_destroy_hierarchy (GdkWindow *window,
2087                                gboolean   recursing,
2088                                gboolean   recursing_native,
2089                                gboolean   foreign_destroy)
2090 {
2091   GdkWindowObject *private;
2092   GdkWindowObject *temp_private;
2093   GdkWindowImplIface *impl_iface;
2094   GdkWindow *temp_window;
2095   GdkScreen *screen;
2096   GdkDisplay *display;
2097   GList *children;
2098   GList *tmp;
2099
2100   g_return_if_fail (GDK_IS_WINDOW (window));
2101
2102   private = (GdkWindowObject*) window;
2103
2104   if (GDK_WINDOW_DESTROYED (window))
2105     return;
2106
2107   display = gdk_drawable_get_display (GDK_DRAWABLE (window));
2108   screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
2109   temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
2110   if (temp_window == window)
2111     g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
2112
2113
2114   switch (private->window_type)
2115     {
2116     case GDK_WINDOW_ROOT:
2117       if (!screen->closed)
2118         {
2119           g_error ("attempted to destroy root window");
2120           break;
2121         }
2122       /* else fall thru */
2123     case GDK_WINDOW_TOPLEVEL:
2124     case GDK_WINDOW_CHILD:
2125     case GDK_WINDOW_DIALOG:
2126     case GDK_WINDOW_TEMP:
2127     case GDK_WINDOW_FOREIGN:
2128     case GDK_WINDOW_OFFSCREEN:
2129       if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
2130         {
2131           /* Logically, it probably makes more sense to send
2132            * a "destroy yourself" message to the foreign window
2133            * whether or not it's in our hierarchy; but for historical
2134            * reasons, we only send "destroy yourself" messages to
2135            * foreign windows in our hierarchy.
2136            */
2137           if (private->parent)
2138             _gdk_windowing_window_destroy_foreign (window);
2139
2140           /* Also for historical reasons, we remove any filters
2141            * on a foreign window when it or a parent is destroyed;
2142            * this likely causes problems if two separate portions
2143            * of code are maintaining filter lists on a foreign window.
2144            */
2145           window_remove_filters (window);
2146         }
2147       else
2148         {
2149           if (private->parent)
2150             {
2151               GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
2152
2153               if (parent_private->children)
2154                 parent_private->children = g_list_remove (parent_private->children, window);
2155
2156               if (!recursing &&
2157                   GDK_WINDOW_IS_MAPPED (window))
2158                 {
2159                   recompute_visible_regions (private, TRUE, FALSE);
2160                   gdk_window_invalidate_in_parent (private);
2161                 }
2162             }
2163
2164           gdk_window_free_paint_stack (window);
2165
2166           if (private->bg_pixmap &&
2167               private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2168               private->bg_pixmap != GDK_NO_BG)
2169             {
2170               g_object_unref (private->bg_pixmap);
2171               private->bg_pixmap = NULL;
2172             }
2173
2174           if (private->window_type == GDK_WINDOW_FOREIGN)
2175             g_assert (private->children == NULL);
2176           else
2177             {
2178               children = tmp = private->children;
2179               private->children = NULL;
2180
2181               while (tmp)
2182                 {
2183                   temp_window = tmp->data;
2184                   tmp = tmp->next;
2185
2186                   temp_private = (GdkWindowObject*) temp_window;
2187                   if (temp_private)
2188                     _gdk_window_destroy_hierarchy (temp_window,
2189                                                    TRUE,
2190                                                    recursing_native || gdk_window_has_impl (private),
2191                                                    foreign_destroy);
2192                 }
2193
2194               g_list_free (children);
2195             }
2196
2197           _gdk_window_clear_update_area (window);
2198
2199           gdk_window_drop_cairo_surface (private);
2200
2201           impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2202
2203           if (gdk_window_has_impl (private))
2204             impl_iface->destroy (window, recursing_native,
2205                                  foreign_destroy);
2206           else
2207             {
2208               /* hide to make sure we repaint and break grabs */
2209               gdk_window_hide (window);
2210             }
2211
2212           private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2213           private->parent = NULL;
2214           private->destroyed = TRUE;
2215
2216           window_remove_filters (window);
2217
2218           gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
2219
2220           /* If we own the redirect, free it */
2221           if (private->redirect && private->redirect->redirected == private)
2222             gdk_window_redirect_free (private->redirect);
2223
2224           private->redirect = NULL;
2225
2226           window_remove_from_pointer_info (window, display);
2227
2228           if (private->clip_region)
2229             {
2230               gdk_region_destroy (private->clip_region);
2231               private->clip_region = NULL;
2232             }
2233
2234           if (private->clip_region_with_children)
2235             {
2236               gdk_region_destroy (private->clip_region_with_children);
2237               private->clip_region_with_children = NULL;
2238             }
2239
2240           if (private->outstanding_moves)
2241             {
2242               g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2243               g_list_free (private->outstanding_moves);
2244               private->outstanding_moves = NULL;
2245             }
2246         }
2247       break;
2248     }
2249 }
2250
2251 /**
2252  * _gdk_window_destroy:
2253  * @window: a #GdkWindow
2254  * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2255  *            external agency. The window has already been destroyed and no
2256  *            windowing system calls should be made. (This may never happen
2257  *            for some windowing systems.)
2258  *
2259  * Internal function to destroy a window. Like gdk_window_destroy(),
2260  * but does not drop the reference count created by gdk_window_new().
2261  **/
2262 void
2263 _gdk_window_destroy (GdkWindow *window,
2264                      gboolean   foreign_destroy)
2265 {
2266   _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2267 }
2268
2269 /**
2270  * gdk_window_destroy:
2271  * @window: a #GdkWindow
2272  *
2273  * Destroys the window system resources associated with @window and decrements @window's
2274  * reference count. The window system resources for all children of @window are also
2275  * destroyed, but the children's reference counts are not decremented.
2276  *
2277  * Note that a window will not be destroyed automatically when its reference count
2278  * reaches zero. You must call this function yourself before that happens.
2279  *
2280  **/
2281 void
2282 gdk_window_destroy (GdkWindow *window)
2283 {
2284   _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2285   g_object_unref (window);
2286 }
2287
2288 /**
2289  * gdk_window_set_user_data:
2290  * @window: a #GdkWindow
2291  * @user_data: user data
2292  *
2293  * For most purposes this function is deprecated in favor of
2294  * g_object_set_data(). However, for historical reasons GTK+ stores
2295  * the #GtkWidget that owns a #GdkWindow as user data on the
2296  * #GdkWindow. So, custom widget implementations should use
2297  * this function for that. If GTK+ receives an event for a #GdkWindow,
2298  * and the user data for the window is non-%NULL, GTK+ will assume the
2299  * user data is a #GtkWidget, and forward the event to that widget.
2300  *
2301  **/
2302 void
2303 gdk_window_set_user_data (GdkWindow *window,
2304                           gpointer   user_data)
2305 {
2306   g_return_if_fail (GDK_IS_WINDOW (window));
2307
2308   ((GdkWindowObject*)window)->user_data = user_data;
2309 }
2310
2311 /**
2312  * gdk_window_get_user_data:
2313  * @window: a #GdkWindow
2314  * @data: return location for user data
2315  *
2316  * Retrieves the user data for @window, which is normally the widget
2317  * that @window belongs to. See gdk_window_set_user_data().
2318  *
2319  **/
2320 void
2321 gdk_window_get_user_data (GdkWindow *window,
2322                           gpointer  *data)
2323 {
2324   g_return_if_fail (GDK_IS_WINDOW (window));
2325
2326   *data = ((GdkWindowObject*)window)->user_data;
2327 }
2328
2329 /**
2330  * gdk_window_get_window_type:
2331  * @window: a #GdkWindow
2332  *
2333  * Gets the type of the window. See #GdkWindowType.
2334  *
2335  * Return value: type of window
2336  **/
2337 GdkWindowType
2338 gdk_window_get_window_type (GdkWindow *window)
2339 {
2340   g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2341
2342   return GDK_WINDOW_TYPE (window);
2343 }
2344
2345 /**
2346  * gdk_window_is_destroyed:
2347  * @window: a #GdkWindow
2348  *
2349  * Check to see if a window is destroyed..
2350  *
2351  * Return value: %TRUE if the window is destroyed
2352  *
2353  * Since: 2.18
2354  **/
2355 gboolean
2356 gdk_window_is_destroyed (GdkWindow *window)
2357 {
2358   return GDK_WINDOW_DESTROYED (window);
2359 }
2360
2361 static void
2362 to_embedder (GdkWindowObject *window,
2363              gdouble          offscreen_x,
2364              gdouble          offscreen_y,
2365              gdouble         *embedder_x,
2366              gdouble         *embedder_y)
2367 {
2368   g_signal_emit (window, signals[TO_EMBEDDER], 0,
2369                  offscreen_x, offscreen_y,
2370                  embedder_x, embedder_y);
2371 }
2372
2373 static void
2374 from_embedder (GdkWindowObject *window,
2375                gdouble          embedder_x,
2376                gdouble          embedder_y,
2377                gdouble         *offscreen_x,
2378                gdouble         *offscreen_y)
2379 {
2380   g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2381                  embedder_x, embedder_y,
2382                  offscreen_x, offscreen_y);
2383 }
2384
2385 /**
2386  * gdk_window_get_position:
2387  * @window: a #GdkWindow
2388  * @x: X coordinate of window
2389  * @y: Y coordinate of window
2390  *
2391  * Obtains the position of the window as reported in the
2392  * most-recently-processed #GdkEventConfigure. Contrast with
2393  * gdk_window_get_geometry() which queries the X server for the
2394  * current window position, regardless of which events have been
2395  * received or processed.
2396  *
2397  * The position coordinates are relative to the window's parent window.
2398  *
2399  **/
2400 void
2401 gdk_window_get_position (GdkWindow *window,
2402                          gint      *x,
2403                          gint      *y)
2404 {
2405   GdkWindowObject *obj;
2406
2407   g_return_if_fail (GDK_IS_WINDOW (window));
2408
2409   obj = (GdkWindowObject*) window;
2410
2411   if (x)
2412     *x = obj->x;
2413   if (y)
2414     *y = obj->y;
2415 }
2416
2417 /**
2418  * gdk_window_get_parent:
2419  * @window: a #GdkWindow
2420  *
2421  * Obtains the parent of @window, as known to GDK. Does not query the
2422  * X server; thus this returns the parent as passed to gdk_window_new(),
2423  * not the actual parent. This should never matter unless you're using
2424  * Xlib calls mixed with GDK calls on the X11 platform. It may also
2425  * matter for toplevel windows, because the window manager may choose
2426  * to reparent them.
2427  *
2428  * Note that you should use gdk_window_get_effective_parent() when
2429  * writing generic code that walks up a window hierarchy, because
2430  * gdk_window_get_parent() will most likely not do what you expect if
2431  * there are offscreen windows in the hierarchy.
2432  *
2433  * Return value: parent of @window
2434  **/
2435 GdkWindow*
2436 gdk_window_get_parent (GdkWindow *window)
2437 {
2438   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2439
2440   return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2441 }
2442
2443 /**
2444  * gdk_window_get_effective_parent:
2445  * @window: a #GdkWindow
2446  *
2447  * Obtains the parent of @window, as known to GDK. Works like
2448  * gdk_window_get_parent() for normal windows, but returns the
2449  * window's embedder for offscreen windows.
2450  *
2451  * See also: gdk_offscreen_window_get_embedder()
2452  *
2453  * Return value: effective parent of @window
2454  *
2455  * Since: 2.22
2456  **/
2457 GdkWindow *
2458 gdk_window_get_effective_parent (GdkWindow *window)
2459 {
2460   GdkWindowObject *obj;
2461
2462   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2463
2464   obj = (GdkWindowObject *)window;
2465
2466   if (gdk_window_is_offscreen (obj))
2467     return gdk_offscreen_window_get_embedder (window);
2468   else
2469     return (GdkWindow *) obj->parent;
2470 }
2471
2472 /**
2473  * gdk_window_get_toplevel:
2474  * @window: a #GdkWindow
2475  *
2476  * Gets the toplevel window that's an ancestor of @window.
2477  *
2478  * Any window type but %GDK_WINDOW_CHILD is considered a
2479  * toplevel window, as is a %GDK_WINDOW_CHILD window that
2480  * has a root window as parent.
2481  *
2482  * Note that you should use gdk_window_get_effective_toplevel() when
2483  * you want to get to a window's toplevel as seen on screen, because
2484  * gdk_window_get_toplevel() will most likely not do what you expect
2485  * if there are offscreen windows in the hierarchy.
2486  *
2487  * Return value: the toplevel window containing @window
2488  **/
2489 GdkWindow *
2490 gdk_window_get_toplevel (GdkWindow *window)
2491 {
2492   GdkWindowObject *obj;
2493
2494   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2495
2496   obj = (GdkWindowObject *)window;
2497
2498   while (obj->window_type == GDK_WINDOW_CHILD)
2499     {
2500       if (gdk_window_is_toplevel (obj))
2501         break;
2502       obj = obj->parent;
2503     }
2504
2505   return GDK_WINDOW (obj);
2506 }
2507
2508 /**
2509  * gdk_window_get_effective_toplevel:
2510  * @window: a #GdkWindow
2511  *
2512  * Gets the toplevel window that's an ancestor of @window.
2513  *
2514  * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2515  * embedder as its parent, using gdk_window_get_effective_parent().
2516  *
2517  * See also: gdk_offscreen_window_get_embedder()
2518  *
2519  * Return value: the effective toplevel window containing @window
2520  *
2521  * Since: 2.22
2522  **/
2523 GdkWindow *
2524 gdk_window_get_effective_toplevel (GdkWindow *window)
2525 {
2526   GdkWindow *parent;
2527
2528   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2529
2530   while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2531          (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2532     window = parent;
2533
2534   return window;
2535 }
2536
2537 /**
2538  * gdk_window_get_children:
2539  * @window: a #GdkWindow
2540  *
2541  * Gets the list of children of @window known to GDK.
2542  * This function only returns children created via GDK,
2543  * so for example it's useless when used with the root window;
2544  * it only returns windows an application created itself.
2545  *
2546  * The returned list must be freed, but the elements in the
2547  * list need not be.
2548  *
2549  * Return value: list of child windows inside @window
2550  **/
2551 GList*
2552 gdk_window_get_children (GdkWindow *window)
2553 {
2554   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2555
2556   if (GDK_WINDOW_DESTROYED (window))
2557     return NULL;
2558
2559   return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2560 }
2561
2562 /**
2563  * gdk_window_peek_children:
2564  * @window: a #GdkWindow
2565  *
2566  * Like gdk_window_get_children(), but does not copy the list of
2567  * children, so the list does not need to be freed.
2568  *
2569  * Return value: a reference to the list of child windows in @window
2570  **/
2571 GList *
2572 gdk_window_peek_children (GdkWindow *window)
2573 {
2574   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2575
2576   if (GDK_WINDOW_DESTROYED (window))
2577     return NULL;
2578
2579   return GDK_WINDOW_OBJECT (window)->children;
2580 }
2581
2582 /**
2583  * gdk_window_add_filter:
2584  * @window: a #GdkWindow
2585  * @function: filter callback
2586  * @data: data to pass to filter callback
2587  *
2588  * Adds an event filter to @window, allowing you to intercept events
2589  * before they reach GDK. This is a low-level operation and makes it
2590  * easy to break GDK and/or GTK+, so you have to know what you're
2591  * doing. Pass %NULL for @window to get all events for all windows,
2592  * instead of events for a specific window.
2593  *
2594  * See gdk_display_add_client_message_filter() if you are interested
2595  * in X ClientMessage events.
2596  **/
2597 void
2598 gdk_window_add_filter (GdkWindow     *window,
2599                        GdkFilterFunc  function,
2600                        gpointer       data)
2601 {
2602   GdkWindowObject *private;
2603   GList *tmp_list;
2604   GdkEventFilter *filter;
2605
2606   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2607
2608   private = (GdkWindowObject*) window;
2609   if (private && GDK_WINDOW_DESTROYED (window))
2610     return;
2611
2612   /* Filters are for the native events on the native window, so
2613      ensure there is a native window. */
2614   if (window)
2615     gdk_window_ensure_native (window);
2616
2617   if (private)
2618     tmp_list = private->filters;
2619   else
2620     tmp_list = _gdk_default_filters;
2621
2622   while (tmp_list)
2623     {
2624       filter = (GdkEventFilter *)tmp_list->data;
2625       if ((filter->function == function) && (filter->data == data))
2626         return;
2627       tmp_list = tmp_list->next;
2628     }
2629
2630   filter = g_new (GdkEventFilter, 1);
2631   filter->function = function;
2632   filter->data = data;
2633
2634   if (private)
2635     private->filters = g_list_append (private->filters, filter);
2636   else
2637     _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2638 }
2639
2640 /**
2641  * gdk_window_remove_filter:
2642  * @window: a #GdkWindow
2643  * @function: previously-added filter function
2644  * @data: user data for previously-added filter function
2645  *
2646  * Remove a filter previously added with gdk_window_add_filter().
2647  *
2648  **/
2649 void
2650 gdk_window_remove_filter (GdkWindow     *window,
2651                           GdkFilterFunc  function,
2652                           gpointer       data)
2653 {
2654   GdkWindowObject *private;
2655   GList *tmp_list, *node;
2656   GdkEventFilter *filter;
2657
2658   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2659
2660   private = (GdkWindowObject*) window;
2661
2662   if (private)
2663     tmp_list = private->filters;
2664   else
2665     tmp_list = _gdk_default_filters;
2666
2667   while (tmp_list)
2668     {
2669       filter = (GdkEventFilter *)tmp_list->data;
2670       node = tmp_list;
2671       tmp_list = tmp_list->next;
2672
2673       if ((filter->function == function) && (filter->data == data))
2674         {
2675           if (private)
2676             private->filters = g_list_remove_link (private->filters, node);
2677           else
2678             _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
2679           g_list_free_1 (node);
2680           g_free (filter);
2681
2682           return;
2683         }
2684     }
2685 }
2686
2687 /**
2688  * gdk_screen_get_toplevel_windows:
2689  * @screen: The #GdkScreen where the toplevels are located.
2690  *
2691  * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2692  * A toplevel window is a child of the root window (see
2693  * gdk_get_default_root_window()).
2694  *
2695  * The returned list should be freed with g_list_free(), but
2696  * its elements need not be freed.
2697  *
2698  * Return value: list of toplevel windows, free with g_list_free()
2699  *
2700  * Since: 2.2
2701  **/
2702 GList *
2703 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2704 {
2705   GdkWindow * root_window;
2706   GList *new_list = NULL;
2707   GList *tmp_list;
2708
2709   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2710
2711   root_window = gdk_screen_get_root_window (screen);
2712
2713   tmp_list = ((GdkWindowObject *)root_window)->children;
2714   while (tmp_list)
2715     {
2716       GdkWindowObject *w = tmp_list->data;
2717
2718       if (w->window_type != GDK_WINDOW_FOREIGN)
2719         new_list = g_list_prepend (new_list, w);
2720       tmp_list = tmp_list->next;
2721     }
2722
2723   return new_list;
2724 }
2725
2726 /**
2727  * gdk_window_is_visible:
2728  * @window: a #GdkWindow
2729  *
2730  * Checks whether the window has been mapped (with gdk_window_show() or
2731  * gdk_window_show_unraised()).
2732  *
2733  * Return value: %TRUE if the window is mapped
2734  **/
2735 gboolean
2736 gdk_window_is_visible (GdkWindow *window)
2737 {
2738   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2739
2740   return GDK_WINDOW_IS_MAPPED (window);
2741 }
2742
2743 /**
2744  * gdk_window_is_viewable:
2745  * @window: a #GdkWindow
2746  *
2747  * Check if the window and all ancestors of the window are
2748  * mapped. (This is not necessarily "viewable" in the X sense, since
2749  * we only check as far as we have GDK window parents, not to the root
2750  * window.)
2751  *
2752  * Return value: %TRUE if the window is viewable
2753  **/
2754 gboolean
2755 gdk_window_is_viewable (GdkWindow *window)
2756 {
2757   GdkWindowObject *private = (GdkWindowObject *)window;
2758
2759   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2760
2761   if (private->destroyed)
2762     return FALSE;
2763
2764   return private->viewable;
2765 }
2766
2767 /**
2768  * gdk_window_get_state:
2769  * @window: a #GdkWindow
2770  *
2771  * Gets the bitwise OR of the currently active window state flags,
2772  * from the #GdkWindowState enumeration.
2773  *
2774  * Return value: window state bitfield
2775  **/
2776 GdkWindowState
2777 gdk_window_get_state (GdkWindow *window)
2778 {
2779   GdkWindowObject *private = (GdkWindowObject *)window;
2780
2781   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2782
2783   return private->state;
2784 }
2785
2786
2787 /* This creates an empty "implicit" paint region for the impl window.
2788  * By itself this does nothing, but real paints to this window
2789  * or children of it can use this pixmap as backing to avoid allocating
2790  * multiple pixmaps for subwindow rendering. When doing so they
2791  * add to the region of the implicit paint region, which will be
2792  * pushed to the window when the implicit paint region is ended.
2793  * Such paints should not copy anything to the window on paint end, but
2794  * should rely on the implicit paint end.
2795  * The implicit paint will be automatically ended if someone draws
2796  * directly to the window or a child window.
2797  */
2798 static gboolean
2799 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2800 {
2801   GdkWindowObject *private = (GdkWindowObject *)window;
2802   GdkWindowPaint *paint;
2803
2804   g_assert (gdk_window_has_impl (private));
2805
2806   if (_gdk_native_windows)
2807     return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2808
2809   if (GDK_IS_PAINTABLE (private->impl))
2810     return FALSE; /* Implementation does double buffering */
2811
2812   if (private->paint_stack != NULL ||
2813       private->implicit_paint != NULL)
2814     return FALSE; /* Don't stack implicit paints */
2815
2816   if (private->outstanding_surfaces != 0)
2817     return FALSE; /* May conflict with direct drawing to cairo surface */
2818
2819   /* Never do implicit paints for foreign windows, they don't need
2820    * double buffer combination since they have no client side children,
2821    * and creating pixmaps for them is risky since they could disappear
2822    * at any time
2823    */
2824   if (private->window_type == GDK_WINDOW_FOREIGN)
2825     return FALSE;
2826
2827   paint = g_new (GdkWindowPaint, 1);
2828   paint->region = gdk_region_new (); /* Empty */
2829   paint->x_offset = rect->x;
2830   paint->y_offset = rect->y;
2831   paint->uses_implicit = FALSE;
2832   paint->flushed = FALSE;
2833   paint->surface = NULL;
2834   paint->pixmap =
2835     gdk_pixmap_new (window,
2836                     MAX (rect->width, 1), MAX (rect->height, 1), -1);
2837
2838   private->implicit_paint = paint;
2839
2840   return TRUE;
2841 }
2842
2843 /* Ensure that all content related to this (sub)window is pushed to the
2844    native region. If there is an active paint then that area is not
2845    pushed, in order to not show partially finished double buffers. */
2846 static void
2847 gdk_window_flush_implicit_paint (GdkWindow *window)
2848 {
2849   GdkWindowObject *private = (GdkWindowObject *)window;
2850   GdkWindowObject *impl_window;
2851   GdkWindowPaint *paint;
2852   GdkRegion *region;
2853   GdkGC *tmp_gc;
2854   GSList *list;
2855
2856   impl_window = gdk_window_get_impl_window (private);
2857   if (impl_window->implicit_paint == NULL)
2858     return;
2859
2860   paint = impl_window->implicit_paint;
2861   paint->flushed = TRUE;
2862   region = gdk_region_copy (private->clip_region_with_children);
2863
2864   /* Don't flush active double buffers, as that may show partially done
2865    * rendering */
2866   for (list = private->paint_stack; list != NULL; list = list->next)
2867     {
2868       GdkWindowPaint *tmp_paint = list->data;
2869
2870       gdk_region_subtract (region, tmp_paint->region);
2871     }
2872
2873   gdk_region_offset (region, private->abs_x, private->abs_y);
2874   gdk_region_intersect (region, paint->region);
2875
2876   if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (region))
2877     {
2878       /* Remove flushed region from the implicit paint */
2879       gdk_region_subtract (paint->region, region);
2880
2881       /* Some regions are valid, push these to window now */
2882       tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE);
2883       _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE);
2884       gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
2885                          0, 0, paint->x_offset, paint->y_offset, -1, -1);
2886       /* Reset clip region of the cached GdkGC */
2887       gdk_gc_set_clip_region (tmp_gc, NULL);
2888     }
2889   else
2890     gdk_region_destroy (region);
2891 }
2892
2893 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2894 static void
2895 gdk_window_end_implicit_paint (GdkWindow *window)
2896 {
2897   GdkWindowObject *private = (GdkWindowObject *)window;
2898   GdkWindowPaint *paint;
2899   GdkGC *tmp_gc;
2900
2901   g_assert (gdk_window_has_impl (private));
2902
2903   g_assert (private->implicit_paint != NULL);
2904
2905   paint = private->implicit_paint;
2906
2907   private->implicit_paint = NULL;
2908
2909   if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (paint->region))
2910     {
2911       /* Some regions are valid, push these to window now */
2912       tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE);
2913       _gdk_gc_set_clip_region_internal (tmp_gc, paint->region, TRUE);
2914       gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
2915                          0, 0, paint->x_offset, paint->y_offset, -1, -1);
2916       /* Reset clip region of the cached GdkGC */
2917       gdk_gc_set_clip_region (tmp_gc, NULL);
2918     }
2919   else
2920     gdk_region_destroy (paint->region);
2921
2922   g_object_unref (paint->pixmap);
2923   g_free (paint);
2924 }
2925
2926 /**
2927  * gdk_window_begin_paint_rect:
2928  * @window: a #GdkWindow
2929  * @rectangle: rectangle you intend to draw to
2930  *
2931  * A convenience wrapper around gdk_window_begin_paint_region() which
2932  * creates a rectangular region for you. See
2933  * gdk_window_begin_paint_region() for details.
2934  *
2935  **/
2936 void
2937 gdk_window_begin_paint_rect (GdkWindow          *window,
2938                              const GdkRectangle *rectangle)
2939 {
2940   GdkRegion *region;
2941
2942   g_return_if_fail (GDK_IS_WINDOW (window));
2943
2944   region = gdk_region_rectangle (rectangle);
2945   gdk_window_begin_paint_region (window, region);
2946   gdk_region_destroy (region);
2947 }
2948
2949 /**
2950  * gdk_window_begin_paint_region:
2951  * @window: a #GdkWindow
2952  * @region: region you intend to draw to
2953  *
2954  * Indicates that you are beginning the process of redrawing @region.
2955  * A backing store (offscreen buffer) large enough to contain @region
2956  * will be created. The backing store will be initialized with the
2957  * background color or background pixmap for @window. Then, all
2958  * drawing operations performed on @window will be diverted to the
2959  * backing store.  When you call gdk_window_end_paint(), the backing
2960  * store will be copied to @window, making it visible onscreen. Only
2961  * the part of @window contained in @region will be modified; that is,
2962  * drawing operations are clipped to @region.
2963  *
2964  * The net result of all this is to remove flicker, because the user
2965  * sees the finished product appear all at once when you call
2966  * gdk_window_end_paint(). If you draw to @window directly without
2967  * calling gdk_window_begin_paint_region(), the user may see flicker
2968  * as individual drawing operations are performed in sequence.  The
2969  * clipping and background-initializing features of
2970  * gdk_window_begin_paint_region() are conveniences for the
2971  * programmer, so you can avoid doing that work yourself.
2972  *
2973  * When using GTK+, the widget system automatically places calls to
2974  * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2975  * emissions of the expose_event signal. That is, if you're writing an
2976  * expose event handler, you can assume that the exposed area in
2977  * #GdkEventExpose has already been cleared to the window background,
2978  * is already set as the clip region, and already has a backing store.
2979  * Therefore in most cases, application code need not call
2980  * gdk_window_begin_paint_region(). (You can disable the automatic
2981  * calls around expose events on a widget-by-widget basis by calling
2982  * gtk_widget_set_double_buffered().)
2983  *
2984  * If you call this function multiple times before calling the
2985  * matching gdk_window_end_paint(), the backing stores are pushed onto
2986  * a stack. gdk_window_end_paint() copies the topmost backing store
2987  * onscreen, subtracts the topmost region from all other regions in
2988  * the stack, and pops the stack. All drawing operations affect only
2989  * the topmost backing store in the stack. One matching call to
2990  * gdk_window_end_paint() is required for each call to
2991  * gdk_window_begin_paint_region().
2992  *
2993  **/
2994 void
2995 gdk_window_begin_paint_region (GdkWindow       *window,
2996                                const GdkRegion *region)
2997 {
2998 #ifdef USE_BACKING_STORE
2999   GdkWindowObject *private = (GdkWindowObject *)window;
3000   GdkRectangle clip_box;
3001   GdkWindowPaint *paint, *implicit_paint;
3002   GdkWindowObject *impl_window;
3003   GSList *list;
3004
3005   g_return_if_fail (GDK_IS_WINDOW (window));
3006
3007   if (GDK_WINDOW_DESTROYED (window))
3008     return;
3009
3010   if (GDK_IS_PAINTABLE (private->impl))
3011     {
3012       GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3013
3014       if (iface->begin_paint_region)
3015         iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
3016
3017       return;
3018     }
3019
3020   impl_window = gdk_window_get_impl_window (private);
3021   implicit_paint = impl_window->implicit_paint;
3022
3023   paint = g_new (GdkWindowPaint, 1);
3024   paint->region = gdk_region_copy (region);
3025   paint->region_tag = new_region_tag ();
3026
3027   gdk_region_intersect (paint->region, private->clip_region_with_children);
3028   gdk_region_get_clipbox (paint->region, &clip_box);
3029
3030   /* Convert to impl coords */
3031   gdk_region_offset (paint->region, private->abs_x, private->abs_y);
3032
3033   /* Mark the region as valid on the implicit paint */
3034
3035   if (implicit_paint)
3036     gdk_region_union (implicit_paint->region, paint->region);
3037
3038   /* Convert back to normal coords */
3039   gdk_region_offset (paint->region, -private->abs_x, -private->abs_y);
3040
3041   if (implicit_paint)
3042     {
3043       int width, height;
3044
3045       paint->uses_implicit = TRUE;
3046       paint->pixmap = g_object_ref (implicit_paint->pixmap);
3047       paint->x_offset = -private->abs_x + implicit_paint->x_offset;
3048       paint->y_offset = -private->abs_y + implicit_paint->y_offset;
3049
3050       gdk_drawable_get_size (paint->pixmap, &width, &height);
3051       paint->surface = _gdk_drawable_create_cairo_surface (paint->pixmap, width, height);
3052     }
3053   else
3054     {
3055       paint->uses_implicit = FALSE;
3056       paint->x_offset = clip_box.x;
3057       paint->y_offset = clip_box.y;
3058       paint->pixmap =
3059         gdk_pixmap_new (window,
3060                         MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1);
3061       paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap);
3062     }
3063
3064   if (paint->surface)
3065     cairo_surface_set_device_offset (paint->surface,
3066                                      -paint->x_offset, -paint->y_offset);
3067
3068   for (list = private->paint_stack; list != NULL; list = list->next)
3069     {
3070       GdkWindowPaint *tmp_paint = list->data;
3071
3072       gdk_region_subtract (tmp_paint->region, paint->region);
3073     }
3074
3075   private->paint_stack = g_slist_prepend (private->paint_stack, paint);
3076
3077   if (!gdk_region_empty (paint->region))
3078     {
3079       gdk_window_clear_backing_region (window,
3080                                        paint->region);
3081     }
3082
3083 #endif /* USE_BACKING_STORE */
3084 }
3085
3086 static void
3087 setup_redirect_clip (GdkWindow      *window,
3088                      GdkGC          *gc,
3089                      int            *x_offset_out,
3090                      int            *y_offset_out)
3091 {
3092   GdkWindowObject *private = (GdkWindowObject *)window;
3093   GdkRegion *visible_region;
3094   GdkRectangle dest_rect;
3095   GdkRegion *tmpreg;
3096   GdkWindow *toplevel;
3097   int x_offset, y_offset;
3098
3099   toplevel = GDK_WINDOW (private->redirect->redirected);
3100
3101   /* Get the clip region for gc clip rect + window hierarchy in
3102      window relative coords */
3103   visible_region =
3104     _gdk_window_calculate_full_clip_region (window, toplevel,
3105                                             TRUE,
3106                                             &x_offset,
3107                                             &y_offset);
3108
3109   /* Compensate for the source pos/size */
3110   x_offset -= private->redirect->src_x;
3111   y_offset -= private->redirect->src_y;
3112   dest_rect.x = -x_offset;
3113   dest_rect.y = -y_offset;
3114   dest_rect.width = private->redirect->width;
3115   dest_rect.height = private->redirect->height;
3116   tmpreg = gdk_region_rectangle (&dest_rect);
3117   gdk_region_intersect (visible_region, tmpreg);
3118   gdk_region_destroy (tmpreg);
3119
3120   /* Compensate for the dest pos */
3121   x_offset += private->redirect->dest_x;
3122   y_offset += private->redirect->dest_y;
3123
3124   gdk_gc_set_clip_region (gc, visible_region); /* This resets clip origin! */
3125
3126   /* offset clip and tiles from window coords to pixmaps coords */
3127   gdk_gc_offset (gc, -x_offset, -y_offset);
3128
3129   gdk_region_destroy (visible_region);
3130
3131   *x_offset_out = x_offset;
3132   *y_offset_out = y_offset;
3133 }
3134
3135 /**
3136  * gdk_window_end_paint:
3137  * @window: a #GdkWindow
3138  *
3139  * Indicates that the backing store created by the most recent call to
3140  * gdk_window_begin_paint_region() should be copied onscreen and
3141  * deleted, leaving the next-most-recent backing store or no backing
3142  * store at all as the active paint region. See
3143  * gdk_window_begin_paint_region() for full details. It is an error to
3144  * call this function without a matching
3145  * gdk_window_begin_paint_region() first.
3146  *
3147  **/
3148 void
3149 gdk_window_end_paint (GdkWindow *window)
3150 {
3151 #ifdef USE_BACKING_STORE
3152   GdkWindowObject *private = (GdkWindowObject *)window;
3153   GdkWindowObject *composited;
3154   GdkWindowPaint *paint;
3155   GdkGC *tmp_gc;
3156   GdkRectangle clip_box;
3157   gint x_offset, y_offset;
3158   GdkRegion *full_clip;
3159
3160   g_return_if_fail (GDK_IS_WINDOW (window));
3161
3162   if (GDK_WINDOW_DESTROYED (window))
3163     return;
3164
3165   if (GDK_IS_PAINTABLE (private->impl))
3166     {
3167       GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3168
3169       if (iface->end_paint)
3170         iface->end_paint ((GdkPaintable*)private->impl);
3171       return;
3172     }
3173
3174   if (private->paint_stack == NULL)
3175     {
3176       g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3177       return;
3178     }
3179
3180   paint = private->paint_stack->data;
3181
3182   private->paint_stack = g_slist_delete_link (private->paint_stack,
3183                                               private->paint_stack);
3184
3185   gdk_region_get_clipbox (paint->region, &clip_box);
3186
3187   tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE);
3188
3189   x_offset = -private->abs_x;
3190   y_offset = -private->abs_y;
3191
3192   if (!paint->uses_implicit)
3193     {
3194       gdk_window_flush_outstanding_moves (window);
3195
3196       full_clip = gdk_region_copy (private->clip_region_with_children);
3197       gdk_region_intersect (full_clip, paint->region);
3198       _gdk_gc_set_clip_region_internal (tmp_gc, full_clip, TRUE); /* Takes ownership of full_clip */
3199       gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset);
3200       gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
3201                          clip_box.x - paint->x_offset,
3202                          clip_box.y - paint->y_offset,
3203                          clip_box.x - x_offset, clip_box.y - y_offset,
3204                          clip_box.width, clip_box.height);
3205     }
3206
3207   if (private->redirect)
3208     {
3209       int x_offset, y_offset;
3210
3211       /* TODO: Should also use paint->region for clipping */
3212       setup_redirect_clip (window, tmp_gc, &x_offset, &y_offset);
3213       gdk_draw_drawable (private->redirect->pixmap, tmp_gc, paint->pixmap,
3214                          clip_box.x - paint->x_offset,
3215                          clip_box.y - paint->y_offset,
3216                          clip_box.x + x_offset,
3217                          clip_box.y + y_offset,
3218                          clip_box.width, clip_box.height);
3219     }
3220
3221   /* Reset clip region of the cached GdkGC */
3222   gdk_gc_set_clip_region (tmp_gc, NULL);
3223
3224   cairo_surface_destroy (paint->surface);
3225   g_object_unref (paint->pixmap);
3226   gdk_region_destroy (paint->region);
3227   g_free (paint);
3228
3229   /* find a composited window in our hierarchy to signal its
3230    * parent to redraw, calculating the clip box as we go...
3231    *
3232    * stop if parent becomes NULL since then we'd have nowhere
3233    * to draw (ie: 'composited' will always be non-NULL here).
3234    */
3235   for (composited = private;
3236        composited->parent;
3237        composited = composited->parent)
3238     {
3239       int width, height;
3240
3241       gdk_drawable_get_size (GDK_DRAWABLE (composited->parent),
3242                              &width, &height);
3243
3244       clip_box.x += composited->x;
3245       clip_box.y += composited->y;
3246       clip_box.width = MIN (clip_box.width, width - clip_box.x);
3247       clip_box.height = MIN (clip_box.height, height - clip_box.y);
3248
3249       if (composited->composited)
3250         {
3251           gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3252                                       &clip_box, FALSE);
3253           break;
3254         }
3255     }
3256 #endif /* USE_BACKING_STORE */
3257 }
3258
3259 static void
3260 gdk_window_free_paint_stack (GdkWindow *window)
3261 {
3262   GdkWindowObject *private = (GdkWindowObject *)window;
3263
3264   if (private->paint_stack)
3265     {
3266       GSList *tmp_list = private->paint_stack;
3267
3268       while (tmp_list)
3269         {
3270           GdkWindowPaint *paint = tmp_list->data;
3271
3272           if (tmp_list == private->paint_stack)
3273             g_object_unref (paint->pixmap);
3274
3275           gdk_region_destroy (paint->region);
3276           g_free (paint);
3277
3278           tmp_list = tmp_list->next;
3279         }
3280
3281       g_slist_free (private->paint_stack);
3282       private->paint_stack = NULL;
3283     }
3284 }
3285
3286 static void
3287 do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3288                              GdkRegion *dest_region, /* In impl window coords */
3289                              int dx, int dy)
3290 {
3291   GdkGC *tmp_gc;
3292   GdkRectangle copy_rect;
3293   GdkWindowObject *private;
3294   GdkWindowImplIface *impl_iface;
3295
3296   /* We need to get data from subwindows here, because we might have
3297    * shaped a native window over the moving region (with bg none,
3298    * so the pixels are still there). In fact we might need to get data
3299    * from overlapping native window that are not children of this window,
3300    * so we copy from the toplevel with INCLUDE_INFERIORS.
3301    */
3302   private = impl_window;
3303   while (!gdk_window_is_toplevel (private))
3304     {
3305       dx -= private->parent->abs_x + private->x;
3306       dy -= private->parent->abs_y + private->y;
3307       private = gdk_window_get_impl_window (private->parent);
3308     }
3309   tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private);
3310
3311   gdk_region_get_clipbox (dest_region, &copy_rect);
3312   gdk_gc_set_clip_region (tmp_gc, dest_region);
3313
3314   /* The region area is moved and we queue translations for all expose events
3315      to the source area that were sent prior to the copy */
3316   gdk_region_offset (dest_region, -dx, -dy); /* Move to source region */
3317   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
3318
3319   impl_iface->queue_translation ((GdkWindow *)impl_window,
3320                                  tmp_gc,
3321                                  dest_region, dx, dy);
3322
3323   gdk_draw_drawable (impl_window->impl,
3324                      tmp_gc,
3325                      private->impl,
3326                      copy_rect.x-dx, copy_rect.y-dy,
3327                      copy_rect.x, copy_rect.y,
3328                      copy_rect.width, copy_rect.height);
3329   gdk_gc_set_clip_region (tmp_gc, NULL);
3330 }
3331
3332 static GdkWindowRegionMove *
3333 gdk_window_region_move_new (GdkRegion *region,
3334                             int dx, int dy)
3335 {
3336   GdkWindowRegionMove *move;
3337
3338   move = g_slice_new (GdkWindowRegionMove);
3339   move->dest_region  = gdk_region_copy (region);
3340   move->dx = dx;
3341   move->dy = dy;
3342
3343   return move;
3344 }
3345
3346 static void
3347 gdk_window_region_move_free (GdkWindowRegionMove *move)
3348 {
3349   gdk_region_destroy (move->dest_region);
3350   g_slice_free (GdkWindowRegionMove, move);
3351 }
3352
3353 static void
3354 append_move_region (GdkWindowObject *impl_window,
3355                     GdkRegion *new_dest_region,
3356                     int dx, int dy)
3357 {
3358   GdkWindowRegionMove *move, *old_move;
3359   GdkRegion *new_total_region, *old_total_region;
3360   GdkRegion *source_overlaps_destination;
3361   GdkRegion *non_overwritten;
3362   gboolean added_move;
3363   GList *l, *prev;
3364
3365   if (gdk_region_empty (new_dest_region))
3366     return;
3367
3368   /* In principle this could just append the move to the list of outstanding
3369      moves that will be replayed before drawing anything when we're handling
3370      exposes. However, we'd like to do a bit better since its commonly the case
3371      that we get multiple copies where A is copied to B and then B is copied
3372      to C, and we'd like to express this as a simple copy A to C operation. */
3373
3374   /* We approach this by taking the new move and pushing it ahead of moves
3375      starting at the end of the list and stopping when its not safe to do so.
3376      It's not safe to push past a move if either the source of the new move
3377      is in the destination of the old move, or if the destination of the new
3378      move is in the source of the new move, or if the destination of the new
3379      move overlaps the destination of the old move. We simplify this by
3380      just comparing the total regions (src + dest) */
3381   new_total_region = gdk_region_copy (new_dest_region);
3382   gdk_region_offset (new_total_region, -dx, -dy);
3383   gdk_region_union (new_total_region, new_dest_region);
3384
3385   added_move = FALSE;
3386   for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3387     {
3388       prev = l->prev;
3389       old_move = l->data;
3390
3391       old_total_region = gdk_region_copy (old_move->dest_region);
3392       gdk_region_offset (old_total_region, -old_move->dx, -old_move->dy);
3393       gdk_region_union (old_total_region, old_move->dest_region);
3394
3395       gdk_region_intersect (old_total_region, new_total_region);
3396       /* If these regions intersect then its not safe to push the
3397          new region before the old one */
3398       if (!gdk_region_empty (old_total_region))
3399         {
3400           /* The area where the new moves source overlaps the old ones
3401              destination */
3402           source_overlaps_destination = gdk_region_copy (new_dest_region);
3403           gdk_region_offset (source_overlaps_destination, -dx, -dy);
3404           gdk_region_intersect (source_overlaps_destination, old_move->dest_region);
3405           gdk_region_offset (source_overlaps_destination, dx, dy);
3406
3407           /* We can do all sort of optimizations here, but to do things safely it becomes
3408              quite complicated. However, a very common case is that you copy something first,
3409              then copy all that or a subset of it to a new location (i.e. if you scroll twice
3410              in the same direction). We'd like to detect this case and optimize it to one
3411              copy. */
3412           if (gdk_region_equal (source_overlaps_destination, new_dest_region))
3413             {
3414               /* This means we might be able to replace the old move and the new one
3415                  with the new one read from the old ones source, and a second copy of
3416                  the non-overwritten parts of the old move. However, such a split
3417                  is only valid if the source in the old move isn't overwritten
3418                  by the destination of the new one */
3419
3420               /* the new destination of old move if split is ok: */
3421               non_overwritten = gdk_region_copy (old_move->dest_region);
3422               gdk_region_subtract (non_overwritten, new_dest_region);
3423               /* move to source region */
3424               gdk_region_offset (non_overwritten, -old_move->dx, -old_move->dy);
3425
3426               gdk_region_intersect (non_overwritten, new_dest_region);
3427               if (gdk_region_empty (non_overwritten))
3428                 {
3429                   added_move = TRUE;
3430                   move = gdk_window_region_move_new (new_dest_region,
3431                                                      dx + old_move->dx,
3432                                                      dy + old_move->dy);
3433
3434                   impl_window->outstanding_moves =
3435                     g_list_insert_before (impl_window->outstanding_moves,
3436                                           l, move);
3437                   gdk_region_subtract (old_move->dest_region, new_dest_region);
3438                 }
3439               gdk_region_destroy (non_overwritten);
3440             }
3441
3442           gdk_region_destroy (source_overlaps_destination);
3443           gdk_region_destroy (old_total_region);
3444           break;
3445         }
3446       gdk_region_destroy (old_total_region);
3447     }
3448
3449   gdk_region_destroy (new_total_region);
3450
3451   if (!added_move)
3452     {
3453       move = gdk_window_region_move_new (new_dest_region, dx, dy);
3454
3455       if (l == NULL)
3456         impl_window->outstanding_moves =
3457           g_list_prepend (impl_window->outstanding_moves,
3458                           move);
3459       else
3460         impl_window->outstanding_moves =
3461           g_list_insert_before (impl_window->outstanding_moves,
3462                                 l->next, move);
3463     }
3464 }
3465
3466 /* Moves bits and update area by dx/dy in impl window.
3467    Takes ownership of region to avoid copy (because we may change it) */
3468 static void
3469 move_region_on_impl (GdkWindowObject *impl_window,
3470                      GdkRegion *region, /* In impl window coords */
3471                      int dx, int dy)
3472 {
3473   if ((dx == 0 && dy == 0) ||
3474       gdk_region_empty (region))
3475     {
3476       gdk_region_destroy (region);
3477       return;
3478     }
3479
3480   g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3481
3482   /* Move any old invalid regions in the copy source area by dx/dy */
3483   if (impl_window->update_area)
3484     {
3485       GdkRegion *update_area;
3486
3487       update_area = gdk_region_copy (region);
3488
3489       /* Convert from target to source */
3490       gdk_region_offset (update_area, -dx, -dy);
3491       gdk_region_intersect (update_area, impl_window->update_area);
3492       /* We only copy the area, so keep the old update area invalid.
3493          It would be safe to remove it too, as code that uses
3494          move_region_on_impl generally also invalidate the source
3495          area. However, it would just use waste cycles. */
3496
3497       /* Convert back */
3498       gdk_region_offset (update_area, dx, dy);
3499       gdk_region_union (impl_window->update_area, update_area);
3500
3501       /* This area of the destination is now invalid,
3502          so no need to copy to it.  */
3503       gdk_region_subtract (region, update_area);
3504
3505       gdk_region_destroy (update_area);
3506     }
3507
3508   /* If we're currently exposing this window, don't copy to this
3509      destination, as it will be overdrawn when the expose is done,
3510      instead invalidate it and repaint later. */
3511   if (impl_window->implicit_paint)
3512     {
3513       GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3514       GdkRegion *exposing;
3515
3516       exposing = gdk_region_copy (implicit_paint->region);
3517       gdk_region_intersect (exposing, region);
3518       gdk_region_subtract (region, exposing);
3519
3520       impl_window_add_update_area (impl_window, exposing);
3521       gdk_region_destroy (exposing);
3522     }
3523
3524   if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3525     append_move_region (impl_window, region, dx, dy);
3526   else
3527     do_move_region_bits_on_impl (impl_window,
3528                                  region, dx, dy);
3529
3530   gdk_region_destroy (region);
3531 }
3532
3533 /* Flushes all outstanding changes to the window, call this
3534  * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3535  */
3536 static void
3537 gdk_window_flush_outstanding_moves (GdkWindow *window)
3538 {
3539   GdkWindowObject *private;
3540   GdkWindowObject *impl_window;
3541   GList *l;
3542   GdkWindowRegionMove *move;
3543
3544   private = (GdkWindowObject *) window;
3545
3546   impl_window = gdk_window_get_impl_window (private);
3547
3548   for (l = impl_window->outstanding_moves; l != NULL; l = l->next)
3549     {
3550       move = l->data;
3551
3552       do_move_region_bits_on_impl (impl_window,
3553                                    move->dest_region, move->dx, move->dy);
3554
3555       gdk_window_region_move_free (move);
3556     }
3557
3558   g_list_free (impl_window->outstanding_moves);
3559   impl_window->outstanding_moves = NULL;
3560 }
3561
3562 /**
3563  * gdk_window_flush:
3564  * @window: a #GdkWindow
3565  *
3566  * Flush all outstanding cached operations on a window, leaving the
3567  * window in a state which reflects all that has been drawn before.
3568  *
3569  * Gdk uses multiple kinds of caching to get better performance and
3570  * nicer drawing. For instance, during exposes all paints to a window
3571  * using double buffered rendering are keep on a pixmap until the last
3572  * window has been exposed. It also delays window moves/scrolls until
3573  * as long as possible until next update to avoid tearing when moving
3574  * windows.
3575  *
3576  * Normally this should be completely invisible to applications, as
3577  * we automatically flush the windows when required, but this might
3578  * be needed if you for instance mix direct native drawing with
3579  * gdk drawing. For Gtk widgets that don't use double buffering this
3580  * will be called automatically before sending the expose event.
3581  *
3582  * Since: 2.18
3583  **/
3584 void
3585 gdk_window_flush (GdkWindow *window)
3586 {
3587   gdk_window_flush_outstanding_moves (window);
3588   gdk_window_flush_implicit_paint (window);
3589 }
3590
3591 /* If we're about to move/resize or otherwise change the
3592  * hierarchy of a client side window in an impl and we're
3593  * called from an expose event handler then we need to
3594  * flush any already painted parts of the implicit paint
3595  * that are not part of the current paint, as these may
3596  * be used when scrolling or may overdraw the changes
3597  * caused by the hierarchy change.
3598  */
3599 static void
3600 gdk_window_flush_if_exposing (GdkWindow *window)
3601 {
3602   GdkWindowObject *private;
3603   GdkWindowObject *impl_window;
3604
3605   private = (GdkWindowObject *) window;
3606   impl_window = gdk_window_get_impl_window (private);
3607
3608   /* If we're in an implicit paint (i.e. in an expose handler, flush
3609      all the already finished exposes to get things to an uptodate state. */
3610   if (impl_window->implicit_paint)
3611     gdk_window_flush (window);
3612 }
3613
3614
3615 static void
3616 gdk_window_flush_recursive_helper (GdkWindowObject *window,
3617                                    GdkWindow *impl)
3618 {
3619   GdkWindowObject *child;
3620   GList *l;
3621
3622   for (l = window->children; l != NULL; l = l->next)
3623     {
3624       child = l->data;
3625
3626       if (child->impl == impl)
3627         /* Same impl, ignore */
3628         gdk_window_flush_recursive_helper (child, impl);
3629       else
3630         gdk_window_flush_recursive (child);
3631     }
3632 }
3633
3634 static void
3635 gdk_window_flush_recursive (GdkWindowObject *window)
3636 {
3637   gdk_window_flush ((GdkWindow *)window);
3638   gdk_window_flush_recursive_helper (window, window->impl);
3639 }
3640
3641 static void
3642 gdk_window_get_offsets (GdkWindow *window,
3643                         gint      *x_offset,
3644                         gint      *y_offset)
3645 {
3646   GdkWindowObject *private = (GdkWindowObject *)window;
3647
3648   if (private->paint_stack)
3649     {
3650       GdkWindowPaint *paint = private->paint_stack->data;
3651       *x_offset = paint->x_offset;
3652       *y_offset = paint->y_offset;
3653     }
3654   else
3655     {
3656       *x_offset = -private->abs_x;
3657       *y_offset = -private->abs_y;
3658     }
3659 }
3660
3661 /**
3662  * gdk_window_get_internal_paint_info:
3663  * @window: a #GdkWindow
3664  * @real_drawable: (out): location to store the drawable to which drawing should be
3665  *            done.
3666  * @x_offset: (out): location to store the X offset between coordinates in @window,
3667  *            and the underlying window system primitive coordinates for
3668  *            *@real_drawable.
3669  * @y_offset: (out): location to store the Y offset between coordinates in @window,
3670  *            and the underlying window system primitive coordinates for
3671  *            *@real_drawable.
3672  *
3673  * If you bypass the GDK layer and use windowing system primitives to
3674  * draw directly onto a #GdkWindow, then you need to deal with two
3675  * details: there may be an offset between GDK coordinates and windowing
3676  * system coordinates, and GDK may have redirected drawing to a offscreen
3677  * pixmap as the result of a gdk_window_begin_paint_region() calls.
3678  * This function allows retrieving the information you need to compensate
3679  * for these effects.
3680  *
3681  * This function exposes details of the GDK implementation, and is thus
3682  * likely to change in future releases of GDK.
3683  **/
3684 void
3685 gdk_window_get_internal_paint_info (GdkWindow    *window,
3686                                     GdkDrawable **real_drawable,
3687                                     gint         *x_offset,
3688                                     gint         *y_offset)
3689 {
3690   gint x_off, y_off;
3691
3692   GdkWindowObject *private;
3693
3694   g_return_if_fail (GDK_IS_WINDOW (window));
3695
3696   private = (GdkWindowObject *)window;
3697
3698   if (real_drawable)
3699     {
3700       if (private->paint_stack)
3701         {
3702           GdkWindowPaint *paint = private->paint_stack->data;
3703           *real_drawable = paint->pixmap;
3704         }
3705       else
3706         {
3707           /* This means you're probably gonna be doing some weird shit
3708              directly to the window, so we flush all outstanding stuff */
3709           gdk_window_flush (window);
3710           *real_drawable = window;
3711         }
3712     }
3713
3714   gdk_window_get_offsets (window, &x_off, &y_off);
3715
3716   if (x_offset)
3717     *x_offset = x_off;
3718   if (y_offset)
3719     *y_offset = y_off;
3720 }
3721
3722 static GdkDrawable *
3723 start_draw_helper (GdkDrawable *drawable,
3724                    GdkGC *gc,
3725                    gint *x_offset_out,
3726                    gint *y_offset_out)
3727 {
3728   GdkWindowObject *private = (GdkWindowObject *)drawable;
3729   gint x_offset, y_offset;
3730   GdkDrawable *impl;
3731   gint old_clip_x = gc->clip_x_origin;
3732   gint old_clip_y = gc->clip_y_origin;
3733   GdkRegion *clip;
3734   guint32 clip_region_tag;
3735   GdkWindowPaint *paint;
3736
3737   paint = NULL;
3738   if (private->paint_stack)
3739     paint = private->paint_stack->data;
3740
3741   if (paint)
3742     {
3743       x_offset = paint->x_offset;
3744       y_offset = paint->y_offset;
3745     }
3746   else
3747     {
3748       x_offset = -private->abs_x;
3749       y_offset = -private->abs_y;
3750     }
3751
3752   if (x_offset != 0 || y_offset != 0)
3753     {
3754       gdk_gc_set_clip_origin (gc,
3755                               old_clip_x - x_offset,
3756                               old_clip_y - y_offset);
3757       gdk_gc_set_ts_origin (gc,
3758                             gc->ts_x_origin - x_offset,
3759                             gc->ts_y_origin - y_offset);
3760     }
3761
3762   *x_offset_out = x_offset;
3763   *y_offset_out = y_offset;
3764
3765   /* Add client side window clip region to gc */
3766   clip = NULL;
3767   if (paint)
3768     {
3769       /* Only need clipping if using implicit paint, otherwise
3770          the pixmap is clipped when copying to the window in end_paint */
3771       if (paint->uses_implicit)
3772         {
3773           /* This includes the window clip */
3774           clip = paint->region;
3775         }
3776       clip_region_tag = paint->region_tag;
3777
3778       /* After having set up the drawable clip rect on a GC we need to make sure
3779        * that we draw to th the impl, otherwise the pixmap code will reset the
3780        * drawable clip. */
3781       impl = ((GdkPixmapObject *)(paint->pixmap))->impl;
3782     }
3783   else
3784     {
3785       /* Drawing directly to the window, flush anything outstanding to
3786          guarantee ordering. */
3787       gdk_window_flush ((GdkWindow *)drawable);
3788
3789       /* Don't clip when drawing to root or all native */
3790       if (!_gdk_native_windows && private->window_type != GDK_WINDOW_ROOT)
3791         {
3792           if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
3793             clip = private->clip_region_with_children;
3794           else
3795             clip = private->clip_region;
3796         }
3797       clip_region_tag = private->clip_tag;
3798       impl = private->impl;
3799     }
3800
3801   if (clip)
3802     _gdk_gc_add_drawable_clip (gc,
3803                                clip_region_tag, clip,
3804                                /* If there was a clip origin set appart from the
3805                                 * window offset, need to take that into
3806                                 * consideration */
3807                                -old_clip_x, -old_clip_y);
3808
3809   return impl;
3810 }
3811
3812 #define BEGIN_DRAW                                      \
3813   {                                                     \
3814     GdkDrawable *impl;                                  \
3815     gint x_offset, y_offset;                            \
3816     gint old_clip_x = gc->clip_x_origin;                \
3817     gint old_clip_y = gc->clip_y_origin;                \
3818     gint old_ts_x = gc->ts_x_origin;                    \
3819     gint old_ts_y = gc->ts_y_origin;                    \
3820     impl = start_draw_helper (drawable, gc,             \
3821                               &x_offset, &y_offset);
3822
3823 #define END_DRAW                                            \
3824     if (x_offset != 0 || y_offset != 0)                     \
3825      {                                                      \
3826        gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \
3827        gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y);       \
3828      }                                                      \
3829   }
3830
3831 #define BEGIN_DRAW_MACRO \
3832   {
3833
3834 #define END_DRAW_MACRO \
3835   }
3836
3837 typedef struct
3838 {
3839   GdkDrawable *drawable;
3840   GdkGC *gc;
3841
3842   gint x_offset;
3843   gint y_offset;
3844
3845   gint clip_x;
3846   gint clip_y;
3847   gint ts_x;
3848   gint ts_y;
3849 } DirectDrawInfo;
3850
3851 GdkDrawable *
3852 _gdk_drawable_begin_direct_draw (GdkDrawable *drawable,
3853                                  GdkGC *gc,
3854                                  gpointer *priv_data,
3855                                  gint *x_offset_out,
3856                                  gint *y_offset_out)
3857 {
3858   g_return_val_if_fail (priv_data != NULL, NULL);
3859
3860   GdkDrawable *out_impl = NULL;
3861
3862   *priv_data = NULL;
3863
3864   if (GDK_IS_PIXMAP (drawable))
3865     {
3866       /* We bypass the GdkPixmap functions, so do this ourself */
3867       _gdk_gc_remove_drawable_clip (gc);
3868
3869       out_impl = drawable;
3870
3871       *x_offset_out = 0;
3872       *y_offset_out = 0;
3873     }
3874   else
3875     {
3876       if (GDK_WINDOW_DESTROYED (drawable))
3877         return NULL;
3878
3879       BEGIN_DRAW;
3880
3881       if (impl == NULL)
3882         return NULL;
3883
3884       out_impl = impl;
3885
3886       *x_offset_out = x_offset;
3887       *y_offset_out = y_offset;
3888
3889       DirectDrawInfo *priv = g_new (DirectDrawInfo, 1);
3890
3891       priv->drawable = impl;
3892       priv->gc = gc;
3893
3894       priv->x_offset = x_offset;
3895       priv->y_offset = y_offset;
3896       priv->clip_x = old_clip_x;
3897       priv->clip_y = old_clip_y;
3898       priv->ts_x = old_ts_x;
3899       priv->ts_y = old_ts_y;
3900
3901       *priv_data = (gpointer) priv;
3902
3903       END_DRAW_MACRO;
3904     }
3905
3906   return out_impl;
3907 }
3908
3909 void
3910 _gdk_drawable_end_direct_draw (gpointer priv_data)
3911 {
3912   /* Its a GdkPixmap or the call to _gdk_drawable_begin_direct_draw failed. */
3913   if (priv_data == NULL)
3914     return;
3915
3916   DirectDrawInfo *priv = priv_data;
3917   GdkGC *gc = priv->gc;
3918
3919   /* This is only for GdkWindows - if GdkPixmaps need any handling here in
3920    * the future, then we should keep track of what type of drawable it is in
3921    * DirectDrawInfo. */
3922   BEGIN_DRAW_MACRO;
3923
3924   gint x_offset = priv->x_offset;
3925   gint y_offset = priv->y_offset;
3926   gint old_clip_x = priv->clip_x;
3927   gint old_clip_y = priv->clip_y;
3928   gint old_ts_x = priv->ts_x;
3929   gint old_ts_y = priv->ts_y;
3930
3931   END_DRAW;
3932
3933   g_free (priv_data);
3934 }
3935
3936 static GdkGC *
3937 gdk_window_create_gc (GdkDrawable     *drawable,
3938                       GdkGCValues     *values,
3939                       GdkGCValuesMask  mask)
3940 {
3941   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
3942
3943   if (GDK_WINDOW_DESTROYED (drawable))
3944     return NULL;
3945
3946   return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl,
3947                                  values, mask);
3948 }
3949
3950 static void
3951 gdk_window_draw_rectangle (GdkDrawable *drawable,
3952                            GdkGC       *gc,
3953                            gboolean     filled,
3954                            gint         x,
3955                            gint         y,
3956                            gint         width,
3957                            gint         height)
3958 {
3959   if (GDK_WINDOW_DESTROYED (drawable))
3960     return;
3961
3962   BEGIN_DRAW;
3963   gdk_draw_rectangle (impl, gc, filled,
3964                       x - x_offset, y - y_offset, width, height);
3965   END_DRAW;
3966 }
3967
3968 static void
3969 gdk_window_draw_arc (GdkDrawable *drawable,
3970                      GdkGC       *gc,
3971                      gboolean     filled,
3972                      gint         x,
3973                      gint         y,
3974                      gint         width,
3975                      gint         height,
3976                      gint         angle1,
3977                      gint         angle2)
3978 {
3979   if (GDK_WINDOW_DESTROYED (drawable))
3980     return;
3981
3982   BEGIN_DRAW;
3983   gdk_draw_arc (impl, gc, filled,
3984                 x - x_offset, y - y_offset,
3985                 width, height, angle1, angle2);
3986   END_DRAW;
3987 }
3988
3989 static void
3990 gdk_window_draw_polygon (GdkDrawable *drawable,
3991                          GdkGC       *gc,
3992                          gboolean     filled,
3993                          GdkPoint    *points,
3994                          gint         npoints)
3995 {
3996   GdkPoint *new_points;
3997
3998   if (GDK_WINDOW_DESTROYED (drawable))
3999     return;
4000
4001   BEGIN_DRAW;
4002
4003   if (x_offset != 0 || y_offset != 0)
4004     {
4005       int i;
4006
4007       new_points = g_new (GdkPoint, npoints);
4008       for (i=0; i<npoints; i++)
4009         {
4010           new_points[i].x = points[i].x - x_offset;
4011           new_points[i].y = points[i].y - y_offset;
4012         }
4013     }
4014   else
4015     new_points = points;
4016
4017   gdk_draw_polygon (impl, gc, filled, new_points, npoints);
4018
4019   if (new_points != points)
4020     g_free (new_points);
4021
4022   END_DRAW;
4023 }
4024
4025 static GdkDrawable *
4026 gdk_window_get_source_drawable (GdkDrawable *drawable)
4027 {
4028   GdkWindow *window = GDK_WINDOW (drawable);
4029   GdkWindowObject *private;
4030
4031   private = (GdkWindowObject *) window;
4032   if (GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable)
4033     return GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable (private->impl);
4034
4035   return drawable;
4036 }
4037
4038 static GdkDrawable *
4039 gdk_window_get_composite_drawable (GdkDrawable *drawable,
4040                                    gint         x,
4041                                    gint         y,
4042                                    gint         width,
4043                                    gint         height,
4044                                    gint        *composite_x_offset,
4045                                    gint        *composite_y_offset)
4046 {
4047   GdkWindowObject *private = (GdkWindowObject *)drawable;
4048   GSList *list;
4049   GdkPixmap *tmp_pixmap;
4050   GdkRectangle rect;
4051   GdkGC *tmp_gc;
4052   gboolean overlap_buffer;
4053   GdkDrawable *source;
4054   GdkWindowObject *impl_window;
4055   GdkWindowPaint *implicit_paint;
4056
4057   *composite_x_offset = -private->abs_x;
4058   *composite_y_offset = -private->abs_y;
4059
4060   if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable)))
4061     return g_object_ref (_gdk_drawable_get_source_drawable (drawable));
4062
4063   /* See if any buffered part is overlapping the part we want
4064    * to get
4065    */
4066   rect.x = x;
4067   rect.y = y;
4068   rect.width = width;
4069   rect.height = height;
4070
4071   overlap_buffer = FALSE;
4072
4073   for (list = private->paint_stack; list != NULL; list = list->next)
4074     {
4075       GdkWindowPaint *paint = list->data;
4076       GdkOverlapType overlap;
4077
4078       overlap = gdk_region_rect_in (paint->region, &rect);
4079
4080       if (overlap == GDK_OVERLAP_RECTANGLE_IN)
4081         {
4082           *composite_x_offset = paint->x_offset;
4083           *composite_y_offset = paint->y_offset;
4084
4085           return g_object_ref (paint->pixmap);
4086         }
4087       else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
4088         {
4089           overlap_buffer = TRUE;
4090           break;
4091         }
4092     }
4093
4094   impl_window = gdk_window_get_impl_window (private);
4095   implicit_paint = impl_window->implicit_paint;
4096   if (implicit_paint)
4097     {
4098       GdkOverlapType overlap;
4099
4100       rect.x += private->abs_x;
4101       rect.y += private->abs_y;
4102
4103       overlap = gdk_region_rect_in (implicit_paint->region, &rect);
4104       if (overlap == GDK_OVERLAP_RECTANGLE_IN)
4105         {
4106           *composite_x_offset = -private->abs_x + implicit_paint->x_offset;
4107           *composite_y_offset = -private->abs_y + implicit_paint->y_offset;
4108
4109           return g_object_ref (implicit_paint->pixmap);
4110         }
4111       else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
4112         overlap_buffer = TRUE;
4113     }
4114
4115   if (!overlap_buffer)
4116     return g_object_ref (_gdk_drawable_get_source_drawable (drawable));
4117
4118   tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1);
4119   tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE);
4120
4121   source = _gdk_drawable_get_source_drawable (drawable);
4122
4123   /* Copy the current window contents */
4124   gdk_draw_drawable (tmp_pixmap,
4125                      tmp_gc,
4126                      GDK_WINDOW_OBJECT (source)->impl,
4127                      x - *composite_x_offset,
4128                      y - *composite_y_offset,
4129                      0, 0,
4130                      width, height);
4131
4132   /* paint the backing stores */
4133   if (implicit_paint)
4134     {
4135       GdkWindowPaint *paint = list->data;
4136
4137       gdk_gc_set_clip_region (tmp_gc, paint->region);
4138       gdk_gc_set_clip_origin (tmp_gc, -x  - paint->x_offset, -y  - paint->y_offset);
4139
4140       gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
4141                          x - paint->x_offset,
4142                          y - paint->y_offset,
4143                          0, 0, width, height);
4144     }
4145
4146   for (list = private->paint_stack; list != NULL; list = list->next)
4147     {
4148       GdkWindowPaint *paint = list->data;
4149
4150       if (paint->uses_implicit)
4151         continue; /* We already copied this above */
4152
4153       gdk_gc_set_clip_region (tmp_gc, paint->region);
4154       gdk_gc_set_clip_origin (tmp_gc, -x, -y);
4155
4156       gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
4157                          x - paint->x_offset,
4158                          y - paint->y_offset,
4159                          0, 0, width, height);
4160     }
4161
4162   /* Reset clip region of the cached GdkGC */
4163   gdk_gc_set_clip_region (tmp_gc, NULL);
4164
4165   /* Set these to location of tmp_pixmap within the window */
4166   *composite_x_offset = x;
4167   *composite_y_offset = y;
4168
4169   return tmp_pixmap;
4170 }
4171
4172 static GdkRegion*
4173 gdk_window_get_clip_region (GdkDrawable *drawable)
4174 {
4175   GdkWindowObject *private = (GdkWindowObject *)drawable;
4176   GdkRegion *result;
4177
4178   result = gdk_region_copy (private->clip_region);
4179
4180   if (private->paint_stack)
4181     {
4182       GdkRegion *paint_region = gdk_region_new ();
4183       GSList *tmp_list = private->paint_stack;
4184
4185       while (tmp_list)
4186         {
4187           GdkWindowPaint *paint = tmp_list->data;
4188
4189           gdk_region_union (paint_region, paint->region);
4190
4191           tmp_list = tmp_list->next;
4192         }
4193
4194       gdk_region_intersect (result, paint_region);
4195       gdk_region_destroy (paint_region);
4196     }
4197
4198   return result;
4199 }
4200
4201 static GdkRegion*
4202 gdk_window_get_visible_region (GdkDrawable *drawable)
4203 {
4204   GdkWindowObject *private = (GdkWindowObject*) drawable;
4205
4206   return gdk_region_copy (private->clip_region);
4207 }
4208
4209 static void
4210 gdk_window_draw_drawable (GdkDrawable *drawable,
4211                           GdkGC       *gc,
4212                           GdkPixmap   *src,
4213                           gint         xsrc,
4214                           gint         ysrc,
4215                           gint         xdest,
4216                           gint         ydest,
4217                           gint         width,
4218                           gint         height,
4219                           GdkDrawable *original_src)
4220 {
4221   GdkWindowObject *private = (GdkWindowObject *)drawable;
4222
4223   if (GDK_WINDOW_DESTROYED (drawable))
4224     return;
4225
4226   BEGIN_DRAW;
4227
4228   /* Call the method directly to avoid getting the composite drawable again */
4229   GDK_DRAWABLE_GET_CLASS (impl)->draw_drawable_with_src (impl, gc,
4230                                                          src,
4231                                                          xsrc, ysrc,
4232                                                          xdest - x_offset,
4233                                                          ydest - y_offset,
4234                                                          width, height,
4235                                                          original_src);
4236
4237   if (!private->paint_stack)
4238     {
4239       /* We might have drawn from an obscured part of a client
4240          side window, if so we need to send graphics exposures */
4241       if (_gdk_gc_get_exposures (gc) &&
4242           GDK_IS_WINDOW (original_src))
4243         {
4244           GdkRegion *exposure_region;
4245           GdkRegion *clip;
4246           GdkRectangle r;
4247
4248           r.x = xdest;
4249           r.y = ydest;
4250           r.width = width;
4251           r.height = height;
4252           exposure_region = gdk_region_rectangle (&r);
4253
4254           if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
4255             clip = private->clip_region_with_children;
4256           else
4257             clip = private->clip_region;
4258           gdk_region_intersect (exposure_region, clip);
4259
4260           _gdk_gc_remove_drawable_clip (gc);
4261           clip = _gdk_gc_get_clip_region (gc);
4262           if (clip)
4263             {
4264               gdk_region_offset (exposure_region,
4265                                  old_clip_x,
4266                                  old_clip_y);
4267               gdk_region_intersect (exposure_region, clip);
4268               gdk_region_offset (exposure_region,
4269                                  -old_clip_x,
4270                                  -old_clip_y);
4271             }
4272
4273           /* Note: We don't clip by the clip mask if set, so this
4274              may invalidate to much */
4275
4276           /* Remove the area that is correctly copied from the src.
4277            * Note that xsrc/ysrc has been corrected for abs_x/y offsets already,
4278            * which need to be undone */
4279           clip = gdk_drawable_get_visible_region (original_src);
4280           gdk_region_offset (clip,
4281                              xdest - (xsrc - GDK_WINDOW_OBJECT (original_src)->abs_x),
4282                              ydest - (ysrc - GDK_WINDOW_OBJECT (original_src)->abs_y));
4283           gdk_region_subtract (exposure_region, clip);
4284           gdk_region_destroy (clip);
4285
4286           gdk_window_invalidate_region_full (GDK_WINDOW (private),
4287                                               exposure_region,
4288                                               _gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS,
4289                                               CLEAR_BG_ALL);
4290
4291           gdk_region_destroy (exposure_region);
4292         }
4293     }
4294
4295   END_DRAW;
4296 }
4297
4298 static void
4299 gdk_window_draw_points (GdkDrawable *drawable,
4300                         GdkGC       *gc,
4301                         GdkPoint    *points,
4302                         gint         npoints)
4303 {
4304   GdkPoint *new_points;
4305
4306   if (GDK_WINDOW_DESTROYED (drawable))
4307     return;
4308
4309   BEGIN_DRAW;
4310
4311   if (x_offset != 0 || y_offset != 0)
4312     {
4313       gint i;
4314
4315       new_points = g_new (GdkPoint, npoints);
4316       for (i=0; i<npoints; i++)
4317         {
4318           new_points[i].x = points[i].x - x_offset;
4319           new_points[i].y = points[i].y - y_offset;
4320         }
4321     }
4322   else
4323     new_points = points;
4324
4325   gdk_draw_points (impl, gc, new_points, npoints);
4326
4327   if (new_points != points)
4328     g_free (new_points);
4329
4330   END_DRAW;
4331 }
4332
4333 static void
4334 gdk_window_draw_segments (GdkDrawable *drawable,
4335                           GdkGC       *gc,
4336                           GdkSegment  *segs,
4337                           gint         nsegs)
4338 {
4339   GdkSegment *new_segs;
4340
4341   if (GDK_WINDOW_DESTROYED (drawable))
4342     return;
4343
4344   BEGIN_DRAW;
4345
4346   if (x_offset != 0 || y_offset != 0)
4347     {
4348       gint i;
4349
4350       new_segs = g_new (GdkSegment, nsegs);
4351       for (i=0; i<nsegs; i++)
4352         {
4353           new_segs[i].x1 = segs[i].x1 - x_offset;
4354           new_segs[i].y1 = segs[i].y1 - y_offset;
4355           new_segs[i].x2 = segs[i].x2 - x_offset;
4356           new_segs[i].y2 = segs[i].y2 - y_offset;
4357         }
4358     }
4359   else
4360     new_segs = segs;
4361
4362   gdk_draw_segments (impl, gc, new_segs, nsegs);
4363
4364   if (new_segs != segs)
4365     g_free (new_segs);
4366
4367   END_DRAW;
4368 }
4369
4370 static void
4371 gdk_window_draw_lines (GdkDrawable *drawable,
4372                        GdkGC       *gc,
4373                        GdkPoint    *points,
4374                        gint         npoints)
4375 {
4376   GdkPoint *new_points;
4377
4378   if (GDK_WINDOW_DESTROYED (drawable))
4379     return;
4380
4381   BEGIN_DRAW;
4382
4383   if (x_offset != 0 || y_offset != 0)
4384     {
4385       gint i;
4386
4387       new_points = g_new (GdkPoint, npoints);
4388       for (i=0; i<npoints; i++)
4389         {
4390           new_points[i].x = points[i].x - x_offset;
4391           new_points[i].y = points[i].y - y_offset;
4392         }
4393     }
4394   else
4395     new_points = points;
4396
4397   gdk_draw_lines (impl, gc, new_points, npoints);
4398
4399   if (new_points != points)
4400     g_free (new_points);
4401
4402   END_DRAW;
4403 }
4404
4405 static void
4406 gdk_window_draw_glyphs (GdkDrawable      *drawable,
4407                         GdkGC            *gc,
4408                         PangoFont        *font,
4409                         gint              x,
4410                         gint              y,
4411                         PangoGlyphString *glyphs)
4412 {
4413   if (GDK_WINDOW_DESTROYED (drawable))
4414     return;
4415
4416   BEGIN_DRAW;
4417   gdk_draw_glyphs (impl, gc, font,
4418                    x - x_offset, y - y_offset, glyphs);
4419   END_DRAW;
4420 }
4421
4422 static void
4423 gdk_window_draw_glyphs_transformed (GdkDrawable      *drawable,
4424                                     GdkGC            *gc,
4425                                     PangoMatrix      *matrix,
4426                                     PangoFont        *font,
4427                                     gint              x,
4428                                     gint              y,
4429                                     PangoGlyphString *glyphs)
4430 {
4431   PangoMatrix tmp_matrix;
4432
4433   if (GDK_WINDOW_DESTROYED (drawable))
4434     return;
4435
4436   BEGIN_DRAW;
4437
4438   if (x_offset != 0 || y_offset != 0)
4439     {
4440       if (matrix)
4441         {
4442           tmp_matrix = *matrix;
4443           tmp_matrix.x0 -= x_offset;
4444           tmp_matrix.y0 -= y_offset;
4445           matrix = &tmp_matrix;
4446         }
4447       else if (GDK_PANGO_UNITS_OVERFLOWS (x_offset, y_offset))
4448         {
4449           PangoMatrix identity = PANGO_MATRIX_INIT;
4450
4451           tmp_matrix = identity;
4452           tmp_matrix.x0 -= x_offset;
4453           tmp_matrix.y0 -= y_offset;
4454           matrix = &tmp_matrix;
4455         }
4456       else
4457         {
4458           x -= x_offset * PANGO_SCALE;
4459           y -= y_offset * PANGO_SCALE;
4460         }
4461     }
4462
4463   gdk_draw_glyphs_transformed (impl, gc, matrix, font, x, y, glyphs);
4464
4465   END_DRAW;
4466 }
4467
4468 typedef struct {
4469   cairo_t *cr; /* if non-null, it means use this cairo context */
4470   GdkGC *gc;   /* if non-null, it means use this GC instead */
4471 } BackingRectMethod;
4472
4473 static void
4474 setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
4475 {
4476   GdkWindowObject *private = (GdkWindowObject *)window;
4477
4478   if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
4479     {
4480       GdkWindowPaint tmp_paint;
4481
4482       tmp_paint = *paint;
4483       tmp_paint.x_offset += private->x;
4484       tmp_paint.y_offset += private->y;
4485
4486       x_offset_cairo += private->x;
4487       y_offset_cairo += private->y;
4488
4489       setup_backing_rect_method (method, GDK_WINDOW (private->parent), &tmp_paint, x_offset_cairo, y_offset_cairo);
4490     }
4491   else if (private->bg_pixmap &&
4492            private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
4493            private->bg_pixmap != GDK_NO_BG)
4494     {
4495 /* This is a workaround for https://bugs.freedesktop.org/show_bug.cgi?id=4320.
4496  * In it, using a pixmap as a repeating pattern in Cairo, and painting it to a
4497  * pixmap destination surface, can be very slow (on the order of seconds for a
4498  * whole-screen copy).  The workaround is to use pretty much the same code that
4499  * we used in GTK+ 2.6 (pre-Cairo), which clears the double-buffer pixmap with
4500  * a tiled GC XFillRectangle().
4501  */
4502
4503 /* Actually computing this flag is left as an exercise for the reader */
4504 #if defined (G_OS_UNIX)
4505 #  define GDK_CAIRO_REPEAT_IS_FAST 0
4506 #else
4507 #  define GDK_CAIRO_REPEAT_IS_FAST 1
4508 #endif
4509
4510 #if GDK_CAIRO_REPEAT_IS_FAST
4511       cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
4512       cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
4513       cairo_surface_destroy (surface);
4514
4515       if (x_offset_cairo != 0 || y_offset_cairo != 0)
4516         {
4517           cairo_matrix_t matrix;
4518           cairo_matrix_init_translate (&matrix, x_offset_cairo, y_offset_cairo);
4519           cairo_pattern_set_matrix (pattern, &matrix);
4520         }
4521
4522       cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
4523
4524       method->cr = cairo_create (paint->surface);
4525       method->gc = NULL;
4526
4527       cairo_set_source (method->cr, pattern);
4528       cairo_pattern_destroy (pattern);
4529 #else
4530       guint gc_mask;
4531       GdkGCValues gc_values;
4532
4533       gc_values.fill = GDK_TILED;
4534       gc_values.tile = private->bg_pixmap;
4535       gc_values.ts_x_origin = -x_offset_cairo;
4536       gc_values.ts_y_origin = -y_offset_cairo;
4537
4538       gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN;
4539
4540       method->gc = gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask);
4541 #endif
4542     }
4543   else
4544     {
4545       method->cr = cairo_create (paint->surface);
4546
4547       gdk_cairo_set_source_color (method->cr, &private->bg_color);
4548     }
4549 }
4550
4551 static void
4552 gdk_window_clear_backing_region (GdkWindow *window,
4553                                  GdkRegion *region)
4554 {
4555   GdkWindowObject *private = (GdkWindowObject *)window;
4556   GdkWindowPaint *paint = private->paint_stack->data;
4557   BackingRectMethod method;
4558   GdkRegion *clip;
4559   GdkRectangle clipbox;
4560 #if 0
4561   GTimer *timer;
4562   double elapsed;
4563 #endif
4564
4565   if (GDK_WINDOW_DESTROYED (window))
4566     return;
4567
4568 #if 0
4569   timer = g_timer_new ();
4570 #endif
4571
4572   method.cr = NULL;
4573   method.gc = NULL;
4574   setup_backing_rect_method (&method, window, paint, 0, 0);
4575
4576   clip = gdk_region_copy (paint->region);
4577   gdk_region_intersect (clip, region);
4578   gdk_region_get_clipbox (clip, &clipbox);
4579
4580
4581   if (method.cr)
4582     {
4583       g_assert (method.gc == NULL);
4584
4585       gdk_cairo_region (method.cr, clip);
4586       cairo_fill (method.cr);
4587
4588       cairo_destroy (method.cr);
4589 #if 0
4590       elapsed = g_timer_elapsed (timer, NULL);
4591       g_print ("Draw the background with Cairo: %fs\n", elapsed);
4592 #endif
4593     }
4594   else
4595     {
4596       g_assert (method.gc != NULL);
4597
4598       gdk_gc_set_clip_region (method.gc, clip);
4599       gdk_draw_rectangle (window, method.gc, TRUE,
4600                           clipbox.x, clipbox.y,
4601                           clipbox.width, clipbox.height);
4602       g_object_unref (method.gc);
4603
4604 #if 0
4605       elapsed = g_timer_elapsed (timer, NULL);
4606       g_print ("Draw the background with GDK: %fs\n", elapsed);
4607 #endif
4608     }
4609
4610   gdk_region_destroy (clip);
4611
4612 #if 0
4613   g_timer_destroy (timer);
4614 #endif
4615 }
4616
4617 static void
4618 gdk_window_clear_backing_region_redirect (GdkWindow *window,
4619                                           GdkRegion *region)
4620 {
4621   GdkWindowObject *private = (GdkWindowObject *)window;
4622   GdkWindowRedirect *redirect = private->redirect;
4623   GdkRegion *clip_region;
4624   GdkRectangle clipbox;
4625   gint x_offset, y_offset;
4626   BackingRectMethod method;
4627   GdkWindowPaint paint;
4628
4629   if (GDK_WINDOW_DESTROYED (window))
4630     return;
4631
4632   clip_region = _gdk_window_calculate_full_clip_region (window,
4633                                                         GDK_WINDOW (redirect->redirected),
4634                                                         TRUE,
4635                                                         &x_offset, &y_offset);
4636   gdk_region_intersect (clip_region, region);
4637
4638   /* offset is from redirected window origin to window origin, convert to
4639      the offset from the redirected pixmap origin to the window origin */
4640   x_offset += redirect->dest_x - redirect->src_x;
4641   y_offset += redirect->dest_y - redirect->src_y;
4642
4643   /* Convert region to pixmap coords */
4644   gdk_region_offset (clip_region, x_offset, y_offset);
4645
4646   paint.x_offset = 0;
4647   paint.y_offset = 0;
4648   paint.pixmap = redirect->pixmap;
4649   paint.surface = _gdk_drawable_ref_cairo_surface (redirect->pixmap);
4650
4651   method.cr = NULL;
4652   method.gc = NULL;
4653   setup_backing_rect_method (&method, window, &paint, -x_offset, -y_offset);
4654
4655   if (method.cr)
4656     {
4657       g_assert (method.gc == NULL);
4658
4659       gdk_cairo_region (method.cr, clip_region);
4660       cairo_fill (method.cr);
4661
4662       cairo_destroy (method.cr);
4663     }
4664   else
4665     {
4666       g_assert (method.gc != NULL);
4667
4668       gdk_region_get_clipbox (clip_region, &clipbox);
4669       gdk_gc_set_clip_region (method.gc, clip_region);
4670       gdk_draw_rectangle (redirect->pixmap, method.gc, TRUE,
4671                           clipbox.x, clipbox.y,
4672                           clipbox.width, clipbox.height);
4673       g_object_unref (method.gc);
4674
4675     }
4676
4677   gdk_region_destroy (clip_region);
4678   cairo_surface_destroy (paint.surface);
4679 }
4680
4681 static void
4682 gdk_window_clear_backing_region_direct (GdkWindow *window,
4683                                         GdkRegion *region)
4684 {
4685   GdkWindowObject *private = (GdkWindowObject *)window;
4686   BackingRectMethod method;
4687   GdkWindowPaint paint;
4688   GdkRegion *clip;
4689   GdkRectangle clipbox;
4690
4691   if (GDK_WINDOW_DESTROYED (window))
4692     return;
4693
4694   paint.x_offset = 0;
4695   paint.y_offset = 0;
4696   paint.pixmap = window;
4697   paint.surface = _gdk_drawable_ref_cairo_surface (window);
4698
4699   method.cr = NULL;
4700   method.gc = NULL;
4701   setup_backing_rect_method (&method, window, &paint, 0, 0);
4702
4703   clip = gdk_region_copy (private->clip_region_with_children);
4704   gdk_region_intersect (clip, region);
4705   gdk_region_get_clipbox (clip, &clipbox);
4706
4707   if (method.cr)
4708     {
4709       g_assert (method.gc == NULL);
4710
4711       gdk_cairo_region (method.cr, clip);
4712       cairo_fill (method.cr);
4713
4714       cairo_destroy (method.cr);
4715     }
4716   else
4717     {
4718       g_assert (method.gc != NULL);
4719
4720       gdk_gc_set_clip_region (method.gc, clip);
4721       gdk_draw_rectangle (window, method.gc, TRUE,
4722                           clipbox.x, clipbox.y,
4723                           clipbox.width, clipbox.height);
4724       g_object_unref (method.gc);
4725
4726     }
4727
4728   gdk_region_destroy (clip);
4729   cairo_surface_destroy (paint.surface);
4730 }
4731
4732
4733 /**
4734  * gdk_window_clear:
4735  * @window: a #GdkWindow
4736  *
4737  * Clears an entire @window to the background color or background pixmap.
4738  **/
4739 void
4740 gdk_window_clear (GdkWindow *window)
4741 {
4742   gint width, height;
4743
4744   g_return_if_fail (GDK_IS_WINDOW (window));
4745
4746   gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
4747
4748   gdk_window_clear_area (window, 0, 0,
4749                          width, height);
4750 }
4751
4752 /* TRUE if the window clears to the same pixels as a native
4753    window clear. This means you can use the native window
4754    clearing operation, and additionally it means any clearing
4755    done by the native window system for you will already be right */
4756 static gboolean
4757 clears_as_native (GdkWindowObject *private)
4758 {
4759   GdkWindowObject *next;
4760
4761   next = private;
4762   do
4763     {
4764       private = next;
4765       if (gdk_window_has_impl (private))
4766         return TRUE;
4767       next = private->parent;
4768     }
4769   while (private->bg_pixmap == GDK_PARENT_RELATIVE_BG &&
4770          next && next->window_type != GDK_WINDOW_ROOT);
4771   return FALSE;
4772 }
4773
4774 static void
4775 gdk_window_clear_region_internal (GdkWindow *window,
4776                                   GdkRegion *region,
4777                                   gboolean   send_expose)
4778 {
4779   GdkWindowObject *private = (GdkWindowObject *)window;
4780   GdkWindowImplIface *impl_iface;
4781
4782   if (private->paint_stack)
4783     gdk_window_clear_backing_region (window, region);
4784   else
4785     {
4786       if (private->redirect)
4787         gdk_window_clear_backing_region_redirect (window, region);
4788
4789       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4790
4791       if (impl_iface->clear_region && clears_as_native (private))
4792         {
4793           GdkRegion *copy;
4794           copy = gdk_region_copy (region);
4795           gdk_region_intersect (copy,
4796                                 private->clip_region_with_children);
4797
4798
4799           /* Drawing directly to the window, flush anything outstanding to
4800              guarantee ordering. */
4801           gdk_window_flush (window);
4802           impl_iface->clear_region (window, copy, send_expose);
4803
4804           gdk_region_destroy (copy);
4805         }
4806       else
4807         {
4808           gdk_window_clear_backing_region_direct (window, region);
4809           if (send_expose)
4810             gdk_window_invalidate_region (window, region, FALSE);
4811         }
4812     }
4813 }
4814
4815 static void
4816 gdk_window_clear_area_internal (GdkWindow *window,
4817                                 gint       x,
4818                                 gint       y,
4819                                 gint       width,
4820                                 gint       height,
4821                                 gboolean   send_expose)
4822 {
4823   GdkRectangle rect;
4824   GdkRegion *region;
4825
4826   g_return_if_fail (GDK_IS_WINDOW (window));
4827
4828   if (GDK_WINDOW_DESTROYED (window))
4829     return;
4830
4831   /* Terminate early to avoid weird interpretation of
4832      zero width/height by XClearArea */
4833   if (width == 0 || height == 0)
4834     return;
4835
4836   rect.x = x;
4837   rect.y = y;
4838   rect.width = width;
4839   rect.height = height;
4840
4841   region = gdk_region_rectangle (&rect);
4842   gdk_window_clear_region_internal (window,
4843                                     region,
4844                                     send_expose);
4845   gdk_region_destroy (region);
4846
4847 }
4848
4849 /**
4850  * gdk_window_clear_area:
4851  * @window: a #GdkWindow
4852  * @x: x coordinate of rectangle to clear
4853  * @y: y coordinate of rectangle to clear
4854  * @width: width of rectangle to clear
4855  * @height: height of rectangle to clear
4856  *
4857  * Clears an area of @window to the background color or background pixmap.
4858  *
4859  **/
4860 void
4861 gdk_window_clear_area (GdkWindow *window,
4862                        gint       x,
4863                        gint       y,
4864                        gint       width,
4865                        gint       height)
4866 {
4867   gdk_window_clear_area_internal (window,
4868                                   x, y,
4869                                   width, height,
4870                                   FALSE);
4871 }
4872
4873 /**
4874  * gdk_window_clear_area_e:
4875  * @window: a #GdkWindow
4876  * @x: x coordinate of rectangle to clear
4877  * @y: y coordinate of rectangle to clear
4878  * @width: width of rectangle to clear
4879  * @height: height of rectangle to clear
4880  *
4881  * Like gdk_window_clear_area(), but also generates an expose event for
4882  * the cleared area.
4883  *
4884  * This function has a stupid name because it dates back to the mists
4885  * time, pre-GDK-1.0.
4886  *
4887  **/
4888 void
4889 gdk_window_clear_area_e (GdkWindow *window,
4890                          gint       x,
4891                          gint       y,
4892                          gint       width,
4893                          gint       height)
4894 {
4895   gdk_window_clear_area_internal (window,
4896                                   x, y,
4897                                   width, height,
4898                                   TRUE);
4899 }
4900
4901 static void
4902 gdk_window_draw_image (GdkDrawable *drawable,
4903                        GdkGC       *gc,
4904                        GdkImage    *image,
4905                        gint         xsrc,
4906                        gint         ysrc,
4907                        gint         xdest,
4908                        gint         ydest,
4909                        gint         width,
4910                        gint         height)
4911 {
4912   if (GDK_WINDOW_DESTROYED (drawable))
4913     return;
4914
4915   BEGIN_DRAW;
4916   gdk_draw_image (impl, gc, image, xsrc, ysrc,
4917                   xdest - x_offset, ydest - y_offset,
4918                   width, height);
4919   END_DRAW;
4920 }
4921
4922 static void
4923 gdk_window_draw_pixbuf (GdkDrawable     *drawable,
4924                         GdkGC           *gc,
4925                         GdkPixbuf       *pixbuf,
4926                         gint             src_x,
4927                         gint             src_y,
4928                         gint             dest_x,
4929                         gint             dest_y,
4930                         gint             width,
4931                         gint             height,
4932                         GdkRgbDither     dither,
4933                         gint             x_dither,
4934                         gint             y_dither)
4935 {
4936   GdkWindowObject *private = (GdkWindowObject *)drawable;
4937   GdkDrawableClass *klass;
4938
4939   if (GDK_WINDOW_DESTROYED (drawable))
4940     return;
4941
4942   /* If no gc => no user clipping, but we need clipping
4943      for window emulation, so use a scratch gc */
4944   if (!gc)
4945     gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
4946
4947   BEGIN_DRAW;
4948
4949   klass = GDK_DRAWABLE_GET_CLASS (impl);
4950
4951   if (private->paint_stack)
4952     klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
4953                         dest_x - x_offset, dest_y - y_offset,
4954                         width, height,
4955                         dither, x_dither - x_offset, y_dither - y_offset);
4956   else
4957     klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
4958                         dest_x - x_offset, dest_y - y_offset,
4959                         width, height,
4960                         dither, x_dither, y_dither);
4961   END_DRAW;
4962 }
4963
4964 static void
4965 gdk_window_draw_trapezoids (GdkDrawable   *drawable,
4966                             GdkGC         *gc,
4967                             GdkTrapezoid  *trapezoids,
4968                             gint           n_trapezoids)
4969 {
4970   GdkTrapezoid *new_trapezoids = NULL;
4971
4972   if (GDK_WINDOW_DESTROYED (drawable))
4973     return;
4974
4975   BEGIN_DRAW;
4976
4977   if (x_offset != 0 || y_offset != 0)
4978     {
4979       gint i;
4980
4981       new_trapezoids = g_new (GdkTrapezoid, n_trapezoids);
4982       for (i=0; i < n_trapezoids; i++)
4983         {
4984           new_trapezoids[i].y1 = trapezoids[i].y1 - y_offset;
4985           new_trapezoids[i].x11 = trapezoids[i].x11 - x_offset;
4986           new_trapezoids[i].x21 = trapezoids[i].x21 - x_offset;
4987           new_trapezoids[i].y2 = trapezoids[i].y2 - y_offset;
4988           new_trapezoids[i].x12 = trapezoids[i].x12 - x_offset;
4989           new_trapezoids[i].x22 = trapezoids[i].x22 - x_offset;
4990         }
4991
4992       trapezoids = new_trapezoids;
4993     }
4994
4995   gdk_draw_trapezoids (impl, gc, trapezoids, n_trapezoids);
4996
4997   g_free (new_trapezoids);
4998
4999   END_DRAW;
5000 }
5001
5002 static void
5003 gdk_window_real_get_size (GdkDrawable *drawable,
5004                           gint *width,
5005                           gint *height)
5006 {
5007   GdkWindowObject *private = (GdkWindowObject *)drawable;
5008
5009   if (width)
5010     *width = private->width;
5011   if (height)
5012     *height = private->height;
5013 }
5014
5015 static GdkVisual*
5016 gdk_window_real_get_visual (GdkDrawable *drawable)
5017 {
5018   GdkColormap *colormap;
5019
5020   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5021
5022   colormap = gdk_drawable_get_colormap (drawable);
5023   return colormap ? gdk_colormap_get_visual (colormap) : NULL;
5024 }
5025
5026 static gint
5027 gdk_window_real_get_depth (GdkDrawable *drawable)
5028 {
5029   g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
5030
5031   return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
5032 }
5033
5034 static GdkScreen*
5035 gdk_window_real_get_screen (GdkDrawable *drawable)
5036 {
5037   return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
5038 }
5039
5040 static void
5041 gdk_window_real_set_colormap (GdkDrawable *drawable,
5042                               GdkColormap *cmap)
5043 {
5044   GdkWindowObject *private;
5045
5046   g_return_if_fail (GDK_IS_WINDOW (drawable));
5047
5048   if (GDK_WINDOW_DESTROYED (drawable))
5049     return;
5050
5051   private = (GdkWindowObject *)drawable;
5052
5053   /* different colormap than parent, requires native window */
5054   if (!private->input_only &&
5055       cmap != gdk_drawable_get_colormap ((GdkDrawable *)(private->parent)))
5056     gdk_window_ensure_native ((GdkWindow *)drawable);
5057
5058   gdk_drawable_set_colormap (private->impl, cmap);
5059 }
5060
5061 static GdkColormap*
5062 gdk_window_real_get_colormap (GdkDrawable *drawable)
5063 {
5064   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5065
5066   if (GDK_WINDOW_DESTROYED (drawable))
5067     return NULL;
5068
5069   return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
5070 }
5071
5072 static GdkImage*
5073 gdk_window_copy_to_image (GdkDrawable     *drawable,
5074                           GdkImage        *image,
5075                           gint             src_x,
5076                           gint             src_y,
5077                           gint             dest_x,
5078                           gint             dest_y,
5079                           gint             width,
5080                           gint             height)
5081 {
5082   GdkWindowObject *private = (GdkWindowObject *) drawable;
5083   gint x_offset, y_offset;
5084
5085   g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5086
5087   if (GDK_WINDOW_DESTROYED (drawable))
5088     return NULL;
5089
5090   /* If we're here, a composite image was not necessary, so
5091    * we can ignore the paint stack.
5092    */
5093
5094   /* TODO: Is this right? */
5095   x_offset = 0;
5096   y_offset = 0;
5097
5098   return gdk_drawable_copy_to_image (private->impl,
5099                                      image,
5100                                      src_x - x_offset,
5101                                      src_y - y_offset,
5102                                      dest_x, dest_y,
5103                                      width, height);
5104 }
5105
5106 static void
5107 gdk_window_drop_cairo_surface (GdkWindowObject *private)
5108 {
5109   if (private->cairo_surface)
5110     {
5111       cairo_surface_finish (private->cairo_surface);
5112       cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
5113                                    NULL, NULL);
5114     }
5115 }
5116
5117 static void
5118 gdk_window_cairo_surface_destroy (void *data)
5119 {
5120   GdkWindowObject *private = (GdkWindowObject*) data;
5121
5122   private->cairo_surface = NULL;
5123   private->impl_window->outstanding_surfaces--;
5124 }
5125
5126 static cairo_surface_t *
5127 gdk_window_create_cairo_surface (GdkDrawable *drawable,
5128                                  int width,
5129                                  int height)
5130 {
5131   return _gdk_windowing_create_cairo_surface (GDK_WINDOW_OBJECT(drawable)->impl,
5132                                               width, height);
5133 }
5134
5135
5136 static cairo_surface_t *
5137 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
5138 {
5139   GdkWindowObject *private = (GdkWindowObject*) drawable;
5140   cairo_surface_t *surface;
5141
5142   if (private->paint_stack)
5143     {
5144       GdkWindowPaint *paint = private->paint_stack->data;
5145
5146       surface = paint->surface;
5147       cairo_surface_reference (surface);
5148     }
5149   else
5150     {
5151
5152       /* This will be drawing directly to the window, so flush implicit paint */
5153       gdk_window_flush ((GdkWindow *)drawable);
5154
5155       if (!private->cairo_surface)
5156         {
5157           int width, height;
5158           GdkDrawable *source;
5159
5160           /* It would be nice if we had some cairo support here so we
5161              could set the clip rect on the cairo surface */
5162           width = private->abs_x + private->width;
5163           height = private->abs_y + private->height;
5164
5165           source = _gdk_drawable_get_source_drawable (drawable);
5166
5167           private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height);
5168
5169           if (private->cairo_surface)
5170             {
5171               private->impl_window->outstanding_surfaces++;
5172
5173               cairo_surface_set_device_offset (private->cairo_surface,
5174                                                private->abs_x,
5175                                                private->abs_y);
5176
5177               cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
5178                                            drawable, gdk_window_cairo_surface_destroy);
5179             }
5180         }
5181       else
5182         cairo_surface_reference (private->cairo_surface);
5183
5184       surface = private->cairo_surface;
5185     }
5186
5187   return surface;
5188 }
5189
5190 static void
5191 gdk_window_set_cairo_clip (GdkDrawable *drawable,
5192                            cairo_t *cr)
5193 {
5194   GdkWindowObject *private = (GdkWindowObject*) drawable;
5195
5196   if (!private->paint_stack)
5197     {
5198       cairo_reset_clip (cr);
5199
5200       cairo_save (cr);
5201       cairo_identity_matrix (cr);
5202
5203       cairo_new_path (cr);
5204       gdk_cairo_region (cr, private->clip_region_with_children);
5205
5206       cairo_restore (cr);
5207       cairo_clip (cr);
5208     }
5209   else
5210     {
5211       GdkWindowPaint *paint = private->paint_stack->data;
5212
5213       /* Only needs to clip to region if piggybacking
5214          on an implicit paint pixmap */
5215       cairo_reset_clip (cr);
5216       if (paint->uses_implicit)
5217         {
5218           cairo_save (cr);
5219           cairo_identity_matrix (cr);
5220
5221           cairo_new_path (cr);
5222           gdk_cairo_region (cr, paint->region);
5223           cairo_restore (cr);
5224
5225           cairo_clip (cr);
5226         }
5227     }
5228 }
5229
5230 /* Code for dirty-region queueing
5231  */
5232 static GSList *update_windows = NULL;
5233 static guint update_idle = 0;
5234 static gboolean debug_updates = FALSE;
5235
5236 static inline gboolean
5237 gdk_window_is_ancestor (GdkWindow *window,
5238                         GdkWindow *ancestor)
5239 {
5240   while (window)
5241     {
5242       GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
5243
5244       if (parent == ancestor)
5245         return TRUE;
5246
5247       window = parent;
5248     }
5249
5250   return FALSE;
5251 }
5252
5253 static void
5254 gdk_window_add_update_window (GdkWindow *window)
5255 {
5256   GSList *tmp;
5257   GSList *prev = NULL;
5258   gboolean has_ancestor_in_list = FALSE;
5259
5260   for (tmp = update_windows; tmp; tmp = tmp->next)
5261     {
5262       GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
5263
5264       /*  check if tmp is an ancestor of "window"; if it is, set a
5265        *  flag indicating that all following windows are either
5266        *  children of "window" or from a differen hierarchy
5267        */
5268       if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
5269         has_ancestor_in_list = TRUE;
5270
5271       /* insert in reverse stacking order when adding around siblings,
5272        * so processing updates properly paints over lower stacked windows
5273        */
5274       if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
5275         {
5276           gint index = g_list_index (parent->children, window);
5277           for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
5278             {
5279               gint sibling_index = g_list_index (parent->children, tmp->data);
5280               if (index > sibling_index)
5281                 break;
5282               prev = tmp;
5283             }
5284           /* here, tmp got advanced past all lower stacked siblings */
5285           tmp = g_slist_prepend (tmp, window);
5286           if (prev)
5287             prev->next = tmp;
5288           else
5289             update_windows = tmp;
5290           return;
5291         }
5292
5293       /*  if "window" has an ancestor in the list and tmp is one of
5294        *  "window's" children, insert "window" before tmp
5295        */
5296       if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
5297         {
5298           tmp = g_slist_prepend (tmp, window);
5299
5300           if (prev)
5301             prev->next = tmp;
5302           else
5303             update_windows = tmp;
5304           return;
5305         }
5306
5307       /*  if we're at the end of the list and had an ancestor it it,
5308        *  append to the list
5309        */
5310       if (! tmp->next && has_ancestor_in_list)
5311         {
5312           tmp = g_slist_append (tmp, window);
5313           return;
5314         }
5315
5316       prev = tmp;
5317     }
5318
5319   /*  if all above checks failed ("window" is from a different
5320    *  hierarchy than what is already in the list) or the list is
5321    *  empty, prepend
5322    */
5323   update_windows = g_slist_prepend (update_windows, window);
5324 }
5325
5326 static void
5327 gdk_window_remove_update_window (GdkWindow *window)
5328 {
5329   update_windows = g_slist_remove (update_windows, window);
5330 }
5331
5332 static gboolean
5333 gdk_window_update_idle (gpointer data)
5334 {
5335   gdk_window_process_all_updates ();
5336
5337   return FALSE;
5338 }
5339
5340 static gboolean
5341 gdk_window_is_toplevel_frozen (GdkWindow *window)
5342 {
5343   GdkWindowObject *toplevel;
5344
5345   toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
5346
5347   return toplevel->update_and_descendants_freeze_count > 0;
5348 }
5349
5350 static void
5351 gdk_window_schedule_update (GdkWindow *window)
5352 {
5353   if (window &&
5354       (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
5355        gdk_window_is_toplevel_frozen (window)))
5356     return;
5357
5358   if (!update_idle)
5359     update_idle =
5360       gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
5361                                  gdk_window_update_idle,
5362                                  NULL, NULL);
5363 }
5364
5365 void
5366 _gdk_window_process_updates_recurse (GdkWindow *window,
5367                                      GdkRegion *expose_region)
5368 {
5369   GdkWindowObject *private = (GdkWindowObject *)window;
5370   GdkWindowObject *child;
5371   GdkRegion *child_region;
5372   GdkRectangle r;
5373   GList *l, *children;
5374
5375   if (gdk_region_empty (expose_region))
5376     return;
5377
5378   /* Make this reentrancy safe for expose handlers freeing windows */
5379   children = g_list_copy (private->children);
5380   g_list_foreach (children, (GFunc)g_object_ref, NULL);
5381
5382   /* Iterate over children, starting at topmost */
5383   for (l = children; l != NULL; l = l->next)
5384     {
5385       child = l->data;
5386
5387       if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
5388         continue;
5389
5390       /* Ignore offscreen children, as they don't draw in their parent and
5391        * don't take part in the clipping */
5392       if (gdk_window_is_offscreen (child))
5393         continue;
5394
5395       r.x = child->x;
5396       r.y = child->y;
5397       r.width = child->width;
5398       r.height = child->height;
5399
5400       child_region = gdk_region_rectangle (&r);
5401       if (child->shape)
5402         {
5403           /* Adjust shape region to parent window coords */
5404           gdk_region_offset (child->shape, child->x, child->y);
5405           gdk_region_intersect (child_region, child->shape);
5406           gdk_region_offset (child->shape, -child->x, -child->y);
5407         }
5408
5409       if (child->impl == private->impl)
5410         {
5411           /* Client side child, expose */
5412           gdk_region_intersect (child_region, expose_region);
5413           gdk_region_subtract (expose_region, child_region);
5414           gdk_region_offset (child_region, -child->x, -child->y);
5415           _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
5416         }
5417       else
5418         {
5419           /* Native child, just remove area from expose region */
5420           gdk_region_subtract (expose_region, child_region);
5421         }
5422       gdk_region_destroy (child_region);
5423     }
5424
5425   g_list_foreach (children, (GFunc)g_object_unref, NULL);
5426   g_list_free (children);
5427
5428   if (!gdk_region_empty (expose_region) &&
5429       !private->destroyed)
5430     {
5431       if (private->event_mask & GDK_EXPOSURE_MASK)
5432         {
5433           GdkEvent event;
5434
5435           event.expose.type = GDK_EXPOSE;
5436           event.expose.window = g_object_ref (window);
5437           event.expose.send_event = FALSE;
5438           event.expose.count = 0;
5439           event.expose.region = expose_region;
5440           gdk_region_get_clipbox (expose_region, &event.expose.area);
5441
5442           (*_gdk_event_func) (&event, _gdk_event_data);
5443
5444           g_object_unref (window);
5445         }
5446       else if (private->bg_pixmap != GDK_NO_BG &&
5447                private->window_type != GDK_WINDOW_FOREIGN)
5448         {
5449           /* No exposure mask set, so nothing will be drawn, the
5450            * app relies on the background being what it specified
5451            * for the window. So, we need to clear this manually.
5452            *
5453            * For foreign windows if expose is not set that generally
5454            * means some other client paints them, so don't clear
5455            * there.
5456            *
5457            * We use begin/end_paint around the clear so that we can
5458            * piggyback on the implicit paint */
5459
5460           gdk_window_begin_paint_region (window, expose_region);
5461           gdk_window_clear_region_internal (window, expose_region, FALSE);
5462           gdk_window_end_paint (window);
5463         }
5464     }
5465 }
5466
5467 /* Process and remove any invalid area on the native window by creating
5468  * expose events for the window and all non-native descendants.
5469  * Also processes any outstanding moves on the window before doing
5470  * any drawing. Note that its possible to have outstanding moves without
5471  * any invalid area as we use the update idle mechanism to coalesce
5472  * multiple moves as well as multiple invalidations.
5473  */
5474 static void
5475 gdk_window_process_updates_internal (GdkWindow *window)
5476 {
5477   GdkWindowObject *private = (GdkWindowObject *)window;
5478   GdkWindowImplIface *impl_iface;
5479   gboolean save_region = FALSE;
5480   GdkRectangle clip_box;
5481
5482   /* Ensure the window lives while updating it */
5483   g_object_ref (window);
5484
5485   /* If an update got queued during update processing, we can get a
5486    * window in the update queue that has an empty update_area.
5487    * just ignore it.
5488    */
5489   if (private->update_area)
5490     {
5491       GdkRegion *update_area = private->update_area;
5492       private->update_area = NULL;
5493
5494       if (_gdk_event_func && gdk_window_is_viewable (window))
5495         {
5496           GdkRegion *expose_region;
5497           gboolean end_implicit;
5498
5499           /* Clip to part visible in toplevel */
5500           gdk_region_intersect (update_area, private->clip_region);
5501
5502           if (debug_updates)
5503             {
5504               /* Make sure we see the red invalid area before redrawing. */
5505               gdk_display_sync (gdk_drawable_get_display (window));
5506               g_usleep (70000);
5507             }
5508
5509           /* At this point we will be completely redrawing all of update_area.
5510            * If we have any outstanding moves that end up moving stuff inside
5511            * this area we don't actually need to move that as that part would
5512            * be overdrawn by the expose anyway. So, in order to copy less data
5513            * we remove these areas from the outstanding moves.
5514            */
5515           if (private->outstanding_moves)
5516             {
5517               GdkWindowRegionMove *move;
5518               GdkRegion *remove;
5519               GList *l, *prev;
5520
5521               remove = gdk_region_copy (update_area);
5522               /* We iterate backwards, starting from the state that would be
5523                  if we had applied all the moves. */
5524               for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
5525                 {
5526                   prev = l->prev;
5527                   move = l->data;
5528
5529                   /* Don't need this area */
5530                   gdk_region_subtract (move->dest_region, remove);
5531
5532                   /* However if any of the destination we do need has a source
5533                      in the updated region we do need that as a destination for
5534                      the earlier moves */
5535                   gdk_region_offset (move->dest_region, -move->dx, -move->dy);
5536                   gdk_region_subtract (remove, move->dest_region);
5537
5538                   if (gdk_region_empty (move->dest_region))
5539                     {
5540                       gdk_window_region_move_free (move);
5541                       private->outstanding_moves =
5542                         g_list_delete_link (private->outstanding_moves, l);
5543                     }
5544                   else /* move back */
5545                     gdk_region_offset (move->dest_region, move->dx, move->dy);
5546                 }
5547               gdk_region_destroy (remove);
5548             }
5549
5550           /* By now we a set of window moves that should be applied, and then
5551            * an update region that should be repainted. A trivial implementation
5552            * would just do that in order, however in order to get nicer drawing
5553            * we do some tricks:
5554            *
5555            * First of all, each subwindow expose may be double buffered by
5556            * itself (depending on widget setting) via
5557            * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
5558            * creating a single pixmap the size of the invalid area on the
5559            * native window which all the individual normal paints will draw
5560            * into. This way in the normal case there will be only one pixmap
5561            * allocated and only once pixmap draw done for all the windows
5562            * in this native window.
5563            * There are a couple of reasons this may fail, for instance, some
5564            * backends (like quartz) do its own double buffering, so we disable
5565            * gdk double buffering there. Secondly, some subwindow could be
5566            * non-double buffered and draw directly to the window outside a
5567            * begin/end_paint pair. That will be lead to a gdk_window_flush
5568            * which immediately executes all outstanding moves and paints+removes
5569            * the implicit paint (further paints will allocate their own pixmap).
5570            *
5571            * Secondly, in the case of implicit double buffering we expose all
5572            * the child windows into the implicit pixmap before we execute
5573            * the outstanding moves. This way we minimize the time between
5574            * doing the moves and rendering the new update area, thus minimizing
5575            * flashing. Of course, if any subwindow is non-double buffered we
5576            * well flush earlier than that.
5577            *
5578            * Thirdly, after having done the outstanding moves we queue an
5579            * "antiexpose" on the area that will be drawn by the expose, which
5580            * means that any invalid region on the native window side before
5581            * the first expose drawing operation will be discarded, as it
5582            * has by then been overdrawn with valid data. This means we can
5583            * avoid doing the unnecessary repaint any outstanding expose events.
5584            */
5585
5586           gdk_region_get_clipbox (update_area, &clip_box);
5587           end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
5588           expose_region = gdk_region_copy (update_area);
5589           if (!end_implicit)
5590             {
5591               /* Rendering is not double buffered by gdk, do outstanding
5592                * moves and queue antiexposure immediately. No need to do
5593                * any tricks */
5594               gdk_window_flush_outstanding_moves (window);
5595               impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5596               save_region = impl_iface->queue_antiexpose (window, update_area);
5597             }
5598
5599           /* Render the invalid areas to the implicit paint, by sending exposes.
5600            * May flush if non-double buffered widget draw. */
5601           _gdk_windowing_window_process_updates_recurse (window, expose_region);
5602
5603           if (end_implicit)
5604             {
5605               /* Do moves right before exposes are rendered to the window */
5606               gdk_window_flush_outstanding_moves (window);
5607
5608               /* By this time we know that any outstanding expose for this
5609                * area is invalid and we can avoid it, so queue an antiexpose.
5610                * However, it may be that due to an non-double buffered expose
5611                * we have already started drawing to the window, so it would
5612                * be to late to anti-expose now. Since this is merely an
5613                * optimization we just avoid doing it at all in that case.
5614                */
5615               if (private->implicit_paint != NULL &&
5616                   !private->implicit_paint->flushed)
5617                 {
5618                   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5619                   save_region = impl_iface->queue_antiexpose (window, update_area);
5620                 }
5621
5622               gdk_window_end_implicit_paint (window);
5623             }
5624           gdk_region_destroy (expose_region);
5625         }
5626       if (!save_region)
5627         gdk_region_destroy (update_area);
5628     }
5629
5630   if (private->outstanding_moves)
5631     {
5632       /* Flush any outstanding moves, may happen if we moved a window but got
5633          no actual invalid area */
5634       gdk_window_flush_outstanding_moves (window);
5635     }
5636
5637   g_object_unref (window);
5638 }
5639
5640 static void
5641 flush_all_displays (void)
5642 {
5643   GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
5644   GSList *tmp_list;
5645
5646   for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
5647     gdk_display_flush (tmp_list->data);
5648
5649   g_slist_free (displays);
5650 }
5651
5652 /* Currently it is not possible to override
5653  * gdk_window_process_all_updates in the same manner as
5654  * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
5655  * by implementing the GdkPaintable interface.  If in the future a
5656  * backend would need this, the right solution would be to add a
5657  * method to GdkDisplay that can be optionally
5658  * NULL. gdk_window_process_all_updates can then walk the list of open
5659  * displays and call the mehod.
5660  */
5661
5662 /**
5663  * gdk_window_process_all_updates:
5664  *
5665  * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
5666  * in the application.
5667  *
5668  **/
5669 void
5670 gdk_window_process_all_updates (void)
5671 {
5672   GSList *old_update_windows = update_windows;
5673   GSList *tmp_list = update_windows;
5674   static gboolean in_process_all_updates = FALSE;
5675   static gboolean got_recursive_update = FALSE;
5676
5677   if (in_process_all_updates)
5678     {
5679       /* We can't do this now since that would recurse, so
5680          delay it until after the recursion is done. */
5681       got_recursive_update = TRUE;
5682       update_idle = 0;
5683       return;
5684     }
5685
5686   in_process_all_updates = TRUE;
5687   got_recursive_update = FALSE;
5688
5689   if (update_idle)
5690     g_source_remove (update_idle);
5691
5692   update_windows = NULL;
5693   update_idle = 0;
5694
5695   _gdk_windowing_before_process_all_updates ();
5696
5697   g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
5698
5699   while (tmp_list)
5700     {
5701       GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
5702
5703       if (!GDK_WINDOW_DESTROYED (tmp_list->data))
5704         {
5705           if (private->update_freeze_count ||
5706               gdk_window_is_toplevel_frozen (tmp_list->data))
5707             gdk_window_add_update_window ((GdkWindow *) private);
5708           else
5709             gdk_window_process_updates_internal (tmp_list->data);
5710         }
5711
5712       g_object_unref (tmp_list->data);
5713       tmp_list = tmp_list->next;
5714     }
5715
5716   g_slist_free (old_update_windows);
5717
5718   flush_all_displays ();
5719
5720   _gdk_windowing_after_process_all_updates ();
5721
5722   in_process_all_updates = FALSE;
5723
5724   /* If we ignored a recursive call, schedule a
5725      redraw now so that it eventually happens,
5726      otherwise we could miss an update if nothing
5727      else schedules an update. */
5728   if (got_recursive_update && !update_idle)
5729     update_idle =
5730       gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
5731                                  gdk_window_update_idle,
5732                                  NULL, NULL);
5733 }
5734
5735 /**
5736  * gdk_window_process_updates:
5737  * @window: a #GdkWindow
5738  * @update_children: whether to also process updates for child windows
5739  *
5740  * Sends one or more expose events to @window. The areas in each
5741  * expose event will cover the entire update area for the window (see
5742  * gdk_window_invalidate_region() for details). Normally GDK calls
5743  * gdk_window_process_all_updates() on your behalf, so there's no
5744  * need to call this function unless you want to force expose events
5745  * to be delivered immediately and synchronously (vs. the usual
5746  * case, where GDK delivers them in an idle handler). Occasionally
5747  * this is useful to produce nicer scrolling behavior, for example.
5748  *
5749  **/
5750 void
5751 gdk_window_process_updates (GdkWindow *window,
5752                             gboolean   update_children)
5753 {
5754   GdkWindowObject *private = (GdkWindowObject *)window;
5755   GdkWindowObject *impl_window;
5756
5757   g_return_if_fail (GDK_IS_WINDOW (window));
5758
5759   if (GDK_WINDOW_DESTROYED (window))
5760     return;
5761
5762   /* Make sure the window lives during the expose callouts */
5763   g_object_ref (window);
5764
5765   impl_window = gdk_window_get_impl_window (private);
5766   if ((impl_window->update_area ||
5767        impl_window->outstanding_moves) &&
5768       !impl_window->update_freeze_count &&
5769       !gdk_window_is_toplevel_frozen (window) &&
5770
5771       /* Don't recurse into process_updates_internal, we'll
5772        * do the update later when idle instead. */
5773       impl_window->implicit_paint == NULL)
5774     {
5775       gdk_window_process_updates_internal ((GdkWindow *)impl_window);
5776       gdk_window_remove_update_window ((GdkWindow *)impl_window);
5777     }
5778
5779   if (update_children)
5780     {
5781       /* process updates in reverse stacking order so composition or
5782        * painting over achieves the desired effect for offscreen windows
5783        */
5784       GList *node, *children;
5785
5786       children = g_list_copy (private->children);
5787       g_list_foreach (children, (GFunc)g_object_ref, NULL);
5788
5789       for (node = g_list_last (children); node; node = node->prev)
5790         {
5791           gdk_window_process_updates (node->data, TRUE);
5792           g_object_unref (node->data);
5793         }
5794
5795       g_list_free (children);
5796     }
5797
5798   g_object_unref (window);
5799 }
5800
5801 static void
5802 gdk_window_invalidate_rect_full (GdkWindow          *window,
5803                                   const GdkRectangle *rect,
5804                                   gboolean            invalidate_children,
5805                                   ClearBg             clear_bg)
5806 {
5807   GdkRectangle window_rect;
5808   GdkRegion *region;
5809   GdkWindowObject *private = (GdkWindowObject *)window;
5810
5811   g_return_if_fail (GDK_IS_WINDOW (window));
5812
5813   if (GDK_WINDOW_DESTROYED (window))
5814     return;
5815
5816   if (private->input_only || !private->viewable)
5817     return;
5818
5819   if (!rect)
5820     {
5821       window_rect.x = 0;
5822       window_rect.y = 0;
5823       gdk_drawable_get_size (GDK_DRAWABLE (window),
5824                              &window_rect.width,
5825                              &window_rect.height);
5826       rect = &window_rect;
5827     }
5828
5829   region = gdk_region_rectangle (rect);
5830   gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
5831   gdk_region_destroy (region);
5832 }
5833
5834 /**
5835  * gdk_window_invalidate_rect:
5836  * @window: a #GdkWindow
5837  * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
5838  *      window
5839  * @invalidate_children: whether to also invalidate child windows
5840  *
5841  * A convenience wrapper around gdk_window_invalidate_region() which
5842  * invalidates a rectangular region. See
5843  * gdk_window_invalidate_region() for details.
5844  **/
5845 void
5846 gdk_window_invalidate_rect (GdkWindow          *window,
5847                             const GdkRectangle *rect,
5848                             gboolean            invalidate_children)
5849 {
5850   gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
5851 }
5852
5853 static void
5854 draw_ugly_color (GdkWindow       *window,
5855                  const GdkRegion *region)
5856 {
5857   /* Draw ugly color all over the newly-invalid region */
5858   GdkColor ugly_color = { 0, 50000, 10000, 10000 };
5859   GdkGC *ugly_gc;
5860   GdkRectangle clipbox;
5861
5862   ugly_gc = gdk_gc_new (window);
5863   gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
5864   gdk_gc_set_clip_region (ugly_gc, region);
5865
5866   gdk_region_get_clipbox (region, &clipbox);
5867
5868   gdk_draw_rectangle (window,
5869                       ugly_gc,
5870                       TRUE,
5871                       clipbox.x, clipbox.y,
5872                       clipbox.width, clipbox.height);
5873
5874   g_object_unref (ugly_gc);
5875 }
5876
5877 static void
5878 impl_window_add_update_area (GdkWindowObject *impl_window,
5879                              GdkRegion *region)
5880 {
5881   if (impl_window->update_area)
5882     gdk_region_union (impl_window->update_area, region);
5883   else
5884     {
5885       gdk_window_add_update_window ((GdkWindow *)impl_window);
5886       impl_window->update_area = gdk_region_copy (region);
5887       gdk_window_schedule_update ((GdkWindow *)impl_window);
5888     }
5889 }
5890
5891 /* clear_bg controls if the region will be cleared to
5892  * the background color/pixmap if the exposure mask is not
5893  * set for the window, whereas this might not otherwise be
5894  * done (unless necessary to emulate background settings).
5895  * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
5896  * need to clear the background, such as when exposing the area beneath a
5897  * hidden or moved window, but not when an app requests repaint or when the
5898  * windowing system exposes a newly visible area (because then the windowing
5899  * system has already cleared the area).
5900  */
5901 static void
5902 gdk_window_invalidate_maybe_recurse_full (GdkWindow       *window,
5903                                           const GdkRegion *region,
5904                                           ClearBg          clear_bg,
5905                                           gboolean       (*child_func) (GdkWindow *,
5906                                                                         gpointer),
5907                                           gpointer   user_data)
5908 {
5909   GdkWindowObject *private = (GdkWindowObject *)window;
5910   GdkWindowObject *impl_window;
5911   GdkRegion *visible_region;
5912   GList *tmp_list;
5913
5914   g_return_if_fail (GDK_IS_WINDOW (window));
5915
5916   if (GDK_WINDOW_DESTROYED (window))
5917     return;
5918
5919   if (private->input_only ||
5920       !private->viewable ||
5921       gdk_region_empty (region) ||
5922       private->window_type == GDK_WINDOW_ROOT)
5923     return;
5924
5925   visible_region = gdk_drawable_get_visible_region (window);
5926   gdk_region_intersect (visible_region, region);
5927
5928   tmp_list = private->children;
5929   while (tmp_list)
5930     {
5931       GdkWindowObject *child = tmp_list->data;
5932
5933       if (!child->input_only)
5934         {
5935           GdkRegion *child_region;
5936           GdkRectangle child_rect;
5937
5938           child_rect.x = child->x;
5939           child_rect.y = child->y;
5940           child_rect.width = child->width;
5941           child_rect.height = child->height;
5942           child_region = gdk_region_rectangle (&child_rect);
5943
5944           /* remove child area from the invalid area of the parent */
5945           if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
5946               !child->composited &&
5947               !gdk_window_is_offscreen (child))
5948             gdk_region_subtract (visible_region, child_region);
5949
5950           if (child_func && (*child_func) ((GdkWindow *)child, user_data))
5951             {
5952               GdkRegion *tmp = gdk_region_copy (region);
5953
5954               gdk_region_offset (tmp, - child_rect.x, - child_rect.y);
5955               gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
5956               gdk_region_intersect (child_region, tmp);
5957
5958               gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
5959                                                         child_region, clear_bg, child_func, user_data);
5960
5961               gdk_region_destroy (tmp);
5962             }
5963
5964           gdk_region_destroy (child_region);
5965         }
5966
5967       tmp_list = tmp_list->next;
5968     }
5969
5970   impl_window = gdk_window_get_impl_window (private);
5971
5972   if (!gdk_region_empty (visible_region)  ||
5973       /* Even if we're not exposing anything, make sure we process
5974          idles for windows with outstanding moves */
5975       (impl_window->outstanding_moves != NULL &&
5976        impl_window->update_area == NULL))
5977     {
5978       if (debug_updates)
5979         draw_ugly_color (window, region);
5980
5981       /* Convert to impl coords */
5982       gdk_region_offset (visible_region, private->abs_x, private->abs_y);
5983
5984       /* Only invalidate area if app requested expose events or if
5985          we need to clear the area (by request or to emulate background
5986          clearing for non-native windows or native windows with no support
5987          for window backgrounds */
5988       if (private->event_mask & GDK_EXPOSURE_MASK ||
5989           clear_bg == CLEAR_BG_ALL ||
5990           (clear_bg == CLEAR_BG_WINCLEARED &&
5991            (!clears_as_native (private) ||
5992             !GDK_WINDOW_IMPL_GET_IFACE (private->impl)->supports_native_bg)))
5993         impl_window_add_update_area (impl_window, visible_region);
5994     }
5995
5996   gdk_region_destroy (visible_region);
5997 }
5998
5999 /**
6000  * gdk_window_invalidate_maybe_recurse:
6001  * @window: a #GdkWindow
6002  * @region: a #GdkRegion
6003  * @child_func: function to use to decide if to recurse to a child,
6004  *              %NULL means never recurse.
6005  * @user_data: data passed to @child_func
6006  *
6007  * Adds @region to the update area for @window. The update area is the
6008  * region that needs to be redrawn, or "dirty region." The call
6009  * gdk_window_process_updates() sends one or more expose events to the
6010  * window, which together cover the entire update area. An
6011  * application would normally redraw the contents of @window in
6012  * response to those expose events.
6013  *
6014  * GDK will call gdk_window_process_all_updates() on your behalf
6015  * whenever your program returns to the main loop and becomes idle, so
6016  * normally there's no need to do that manually, you just need to
6017  * invalidate regions that you know should be redrawn.
6018  *
6019  * The @child_func parameter controls whether the region of
6020  * each child window that intersects @region will also be invalidated.
6021  * Only children for which @child_func returns TRUE will have the area
6022  * invalidated.
6023  **/
6024 void
6025 gdk_window_invalidate_maybe_recurse (GdkWindow       *window,
6026                                      const GdkRegion *region,
6027                                      gboolean       (*child_func) (GdkWindow *,
6028                                                                    gpointer),
6029                                      gpointer   user_data)
6030 {
6031   gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
6032                                             child_func, user_data);
6033 }
6034
6035 static gboolean
6036 true_predicate (GdkWindow *window,
6037                 gpointer   user_data)
6038 {
6039   return TRUE;
6040 }
6041
6042 static void
6043 gdk_window_invalidate_region_full (GdkWindow       *window,
6044                                     const GdkRegion *region,
6045                                     gboolean         invalidate_children,
6046                                     ClearBg          clear_bg)
6047 {
6048   gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
6049                                             invalidate_children ?
6050                                             true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
6051                                        NULL);
6052 }
6053
6054 /**
6055  * gdk_window_invalidate_region:
6056  * @window: a #GdkWindow
6057  * @region: a #GdkRegion
6058  * @invalidate_children: %TRUE to also invalidate child windows
6059  *
6060  * Adds @region to the update area for @window. The update area is the
6061  * region that needs to be redrawn, or "dirty region." The call
6062  * gdk_window_process_updates() sends one or more expose events to the
6063  * window, which together cover the entire update area. An
6064  * application would normally redraw the contents of @window in
6065  * response to those expose events.
6066  *
6067  * GDK will call gdk_window_process_all_updates() on your behalf
6068  * whenever your program returns to the main loop and becomes idle, so
6069  * normally there's no need to do that manually, you just need to
6070  * invalidate regions that you know should be redrawn.
6071  *
6072  * The @invalidate_children parameter controls whether the region of
6073  * each child window that intersects @region will also be invalidated.
6074  * If %FALSE, then the update area for child windows will remain
6075  * unaffected. See gdk_window_invalidate_maybe_recurse if you need
6076  * fine grained control over which children are invalidated.
6077  **/
6078 void
6079 gdk_window_invalidate_region (GdkWindow       *window,
6080                               const GdkRegion *region,
6081                               gboolean         invalidate_children)
6082 {
6083   gdk_window_invalidate_maybe_recurse (window, region,
6084                                        invalidate_children ?
6085                                          true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
6086                                        NULL);
6087 }
6088
6089 /**
6090  * _gdk_window_invalidate_for_expose:
6091  * @window: a #GdkWindow
6092  * @region: a #GdkRegion
6093  *
6094  * Adds @region to the update area for @window. The update area is the
6095  * region that needs to be redrawn, or "dirty region." The call
6096  * gdk_window_process_updates() sends one or more expose events to the
6097  * window, which together cover the entire update area. An
6098  * application would normally redraw the contents of @window in
6099  * response to those expose events.
6100  *
6101  * GDK will call gdk_window_process_all_updates() on your behalf
6102  * whenever your program returns to the main loop and becomes idle, so
6103  * normally there's no need to do that manually, you just need to
6104  * invalidate regions that you know should be redrawn.
6105  *
6106  * This version of invalidation is used when you recieve expose events
6107  * from the native window system. It exposes the native window, plus
6108  * any non-native child windows (but not native child windows, as those would
6109  * have gotten their own expose events).
6110  **/
6111 void
6112 _gdk_window_invalidate_for_expose (GdkWindow       *window,
6113                                    GdkRegion       *region)
6114 {
6115   GdkWindowObject *private = (GdkWindowObject *) window;
6116   GdkWindowRegionMove *move;
6117   GdkRegion *move_region;
6118   GList *l;
6119
6120   /* Any invalidations comming from the windowing system will
6121      be in areas that may be moved by outstanding moves,
6122      so we need to modify the expose region correspondingly,
6123      otherwise we would expose in the wrong place, as the
6124      outstanding moves will be copied before we draw the
6125      exposes. */
6126   for (l = private->outstanding_moves; l != NULL; l = l->next)
6127     {
6128       move = l->data;
6129
6130       /* covert to move source region */
6131       move_region = gdk_region_copy (move->dest_region);
6132       gdk_region_offset (move_region, -move->dx, -move->dy);
6133
6134       /* Move area of region that intersects with move source
6135          by dx, dy of the move*/
6136       gdk_region_intersect (move_region, region);
6137       gdk_region_subtract (region, move_region);
6138       gdk_region_offset (move_region, move->dx, move->dy);
6139       gdk_region_union (region, move_region);
6140
6141       gdk_region_destroy (move_region);
6142     }
6143
6144   gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
6145                                             (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
6146                                             NULL);
6147 }
6148
6149
6150 /**
6151  * gdk_window_get_update_area:
6152  * @window: a #GdkWindow
6153  *
6154  * Transfers ownership of the update area from @window to the caller
6155  * of the function. That is, after calling this function, @window will
6156  * no longer have an invalid/dirty region; the update area is removed
6157  * from @window and handed to you. If a window has no update area,
6158  * gdk_window_get_update_area() returns %NULL. You are responsible for
6159  * calling gdk_region_destroy() on the returned region if it's non-%NULL.
6160  *
6161  * Return value: the update area for @window
6162  **/
6163 GdkRegion *
6164 gdk_window_get_update_area (GdkWindow *window)
6165 {
6166   GdkWindowObject *private = (GdkWindowObject *)window;
6167   GdkWindowObject *impl_window;
6168   GdkRegion *tmp_region;
6169
6170   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6171
6172   impl_window = gdk_window_get_impl_window (private);
6173
6174   if (impl_window->update_area)
6175     {
6176       tmp_region = gdk_region_copy (private->clip_region_with_children);
6177       /* Convert to impl coords */
6178       gdk_region_offset (tmp_region, private->abs_x, private->abs_y);
6179       gdk_region_intersect (tmp_region, impl_window->update_area);
6180
6181       if (gdk_region_empty (tmp_region))
6182         {
6183           gdk_region_destroy (tmp_region);
6184           return NULL;
6185         }
6186       else
6187         {
6188           gdk_region_subtract (impl_window->update_area, tmp_region);
6189
6190           if (gdk_region_empty (impl_window->update_area) &&
6191               impl_window->outstanding_moves == NULL)
6192             {
6193               gdk_region_destroy (impl_window->update_area);
6194               impl_window->update_area = NULL;
6195
6196               gdk_window_remove_update_window ((GdkWindow *)impl_window);
6197             }
6198
6199           /* Convert from impl coords */
6200           gdk_region_offset (tmp_region, -private->abs_x, -private->abs_y);
6201           return tmp_region;
6202
6203         }
6204     }
6205   else
6206     return NULL;
6207 }
6208
6209 /**
6210  * _gdk_window_clear_update_area:
6211  * @window: a #GdkWindow.
6212  *
6213  * Internal function to clear the update area for a window. This
6214  * is called when the window is hidden or destroyed.
6215  **/
6216 void
6217 _gdk_window_clear_update_area (GdkWindow *window)
6218 {
6219   GdkWindowObject *private = (GdkWindowObject *)window;
6220
6221   g_return_if_fail (GDK_IS_WINDOW (window));
6222
6223   if (private->update_area)
6224     {
6225       gdk_window_remove_update_window (window);
6226
6227       gdk_region_destroy (private->update_area);
6228       private->update_area = NULL;
6229     }
6230 }
6231
6232 /**
6233  * gdk_window_freeze_updates:
6234  * @window: a #GdkWindow
6235  *
6236  * Temporarily freezes a window such that it won't receive expose
6237  * events.  The window will begin receiving expose events again when
6238  * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
6239  * has been called more than once, gdk_window_thaw_updates() must be called
6240  * an equal number of times to begin processing exposes.
6241  **/
6242 void
6243 gdk_window_freeze_updates (GdkWindow *window)
6244 {
6245   GdkWindowObject *private = (GdkWindowObject *)window;
6246   GdkWindowObject *impl_window;
6247
6248   g_return_if_fail (GDK_IS_WINDOW (window));
6249
6250   impl_window = gdk_window_get_impl_window (private);
6251   impl_window->update_freeze_count++;
6252 }
6253
6254 /**
6255  * gdk_window_thaw_updates:
6256  * @window: a #GdkWindow
6257  *
6258  * Thaws a window frozen with gdk_window_freeze_updates().
6259  **/
6260 void
6261 gdk_window_thaw_updates (GdkWindow *window)
6262 {
6263   GdkWindowObject *private = (GdkWindowObject *)window;
6264   GdkWindowObject *impl_window;
6265
6266   g_return_if_fail (GDK_IS_WINDOW (window));
6267
6268   impl_window = gdk_window_get_impl_window (private);
6269
6270   g_return_if_fail (impl_window->update_freeze_count > 0);
6271
6272   if (--impl_window->update_freeze_count == 0)
6273     gdk_window_schedule_update (GDK_WINDOW (impl_window));
6274 }
6275
6276 /**
6277  * gdk_window_freeze_toplevel_updates_libgtk_only:
6278  * @window: a #GdkWindow
6279  *
6280  * Temporarily freezes a window and all its descendants such that it won't
6281  * receive expose events.  The window will begin receiving expose events
6282  * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
6283  * gdk_window_freeze_toplevel_updates_libgtk_only()
6284  * has been called more than once,
6285  * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
6286  * an equal number of times to begin processing exposes.
6287  *
6288  * This function is not part of the GDK public API and is only
6289  * for use by GTK+.
6290  **/
6291 void
6292 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
6293 {
6294   GdkWindowObject *private = (GdkWindowObject *)window;
6295
6296   g_return_if_fail (GDK_IS_WINDOW (window));
6297   g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
6298
6299   private->update_and_descendants_freeze_count++;
6300 }
6301
6302 /**
6303  * gdk_window_thaw_toplevel_updates_libgtk_only:
6304  * @window: a #GdkWindow
6305  *
6306  * Thaws a window frozen with
6307  * gdk_window_freeze_toplevel_updates_libgtk_only().
6308  *
6309  * This function is not part of the GDK public API and is only
6310  * for use by GTK+.
6311  **/
6312 void
6313 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
6314 {
6315   GdkWindowObject *private = (GdkWindowObject *)window;
6316
6317   g_return_if_fail (GDK_IS_WINDOW (window));
6318   g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
6319   g_return_if_fail (private->update_and_descendants_freeze_count > 0);
6320
6321   private->update_and_descendants_freeze_count--;
6322
6323   gdk_window_schedule_update (window);
6324 }
6325
6326 /**
6327  * gdk_window_set_debug_updates:
6328  * @setting: %TRUE to turn on update debugging
6329  *
6330  * With update debugging enabled, calls to
6331  * gdk_window_invalidate_region() clear the invalidated region of the
6332  * screen to a noticeable color, and GDK pauses for a short time
6333  * before sending exposes to windows during
6334  * gdk_window_process_updates().  The net effect is that you can see
6335  * the invalid region for each window and watch redraws as they
6336  * occur. This allows you to diagnose inefficiencies in your application.
6337  *
6338  * In essence, because the GDK rendering model prevents all flicker,
6339  * if you are redrawing the same region 400 times you may never
6340  * notice, aside from noticing a speed problem. Enabling update
6341  * debugging causes GTK to flicker slowly and noticeably, so you can
6342  * see exactly what's being redrawn when, in what order.
6343  *
6344  * The --gtk-debug=updates command line option passed to GTK+ programs
6345  * enables this debug option at application startup time. That's
6346  * usually more useful than calling gdk_window_set_debug_updates()
6347  * yourself, though you might want to use this function to enable
6348  * updates sometime after application startup time.
6349  *
6350  **/
6351 void
6352 gdk_window_set_debug_updates (gboolean setting)
6353 {
6354   debug_updates = setting;
6355 }
6356
6357 /**
6358  * gdk_window_constrain_size:
6359  * @geometry: a #GdkGeometry structure
6360  * @flags: a mask indicating what portions of @geometry are set
6361  * @width: desired width of window
6362  * @height: desired height of the window
6363  * @new_width: location to store resulting width
6364  * @new_height: location to store resulting height
6365  *
6366  * Constrains a desired width and height according to a
6367  * set of geometry hints (such as minimum and maximum size).
6368  */
6369 void
6370 gdk_window_constrain_size (GdkGeometry *geometry,
6371                            guint        flags,
6372                            gint         width,
6373                            gint         height,
6374                            gint        *new_width,
6375                            gint        *new_height)
6376 {
6377   /* This routine is partially borrowed from fvwm.
6378    *
6379    * Copyright 1993, Robert Nation
6380    *     You may use this code for any purpose, as long as the original
6381    *     copyright remains in the source code and all documentation
6382    *
6383    * which in turn borrows parts of the algorithm from uwm
6384    */
6385   gint min_width = 0;
6386   gint min_height = 0;
6387   gint base_width = 0;
6388   gint base_height = 0;
6389   gint xinc = 1;
6390   gint yinc = 1;
6391   gint max_width = G_MAXINT;
6392   gint max_height = G_MAXINT;
6393
6394 #define FLOOR(value, base)      ( ((gint) ((value) / (base))) * (base) )
6395
6396   if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
6397     {
6398       base_width = geometry->base_width;
6399       base_height = geometry->base_height;
6400       min_width = geometry->min_width;
6401       min_height = geometry->min_height;
6402     }
6403   else if (flags & GDK_HINT_BASE_SIZE)
6404     {
6405       base_width = geometry->base_width;
6406       base_height = geometry->base_height;
6407       min_width = geometry->base_width;
6408       min_height = geometry->base_height;
6409     }
6410   else if (flags & GDK_HINT_MIN_SIZE)
6411     {
6412       base_width = geometry->min_width;
6413       base_height = geometry->min_height;
6414       min_width = geometry->min_width;
6415       min_height = geometry->min_height;
6416     }
6417
6418   if (flags & GDK_HINT_MAX_SIZE)
6419     {
6420       max_width = geometry->max_width ;
6421       max_height = geometry->max_height;
6422     }
6423
6424   if (flags & GDK_HINT_RESIZE_INC)
6425     {
6426       xinc = MAX (xinc, geometry->width_inc);
6427       yinc = MAX (yinc, geometry->height_inc);
6428     }
6429
6430   /* clamp width and height to min and max values
6431    */
6432   width = CLAMP (width, min_width, max_width);
6433   height = CLAMP (height, min_height, max_height);
6434
6435   /* shrink to base + N * inc
6436    */
6437   width = base_width + FLOOR (width - base_width, xinc);
6438   height = base_height + FLOOR (height - base_height, yinc);
6439
6440   /* constrain aspect ratio, according to:
6441    *
6442    *                width
6443    * min_aspect <= -------- <= max_aspect
6444    *                height
6445    */
6446
6447   if (flags & GDK_HINT_ASPECT &&
6448       geometry->min_aspect > 0 &&
6449       geometry->max_aspect > 0)
6450     {
6451       gint delta;
6452
6453       if (geometry->min_aspect * height > width)
6454         {
6455           delta = FLOOR (height - width / geometry->min_aspect, yinc);
6456           if (height - delta >= min_height)
6457             height -= delta;
6458           else
6459             {
6460               delta = FLOOR (height * geometry->min_aspect - width, xinc);
6461               if (width + delta <= max_width)
6462                 width += delta;
6463             }
6464         }
6465
6466       if (geometry->max_aspect * height < width)
6467         {
6468           delta = FLOOR (width - height * geometry->max_aspect, xinc);
6469           if (width - delta >= min_width)
6470             width -= delta;
6471           else
6472             {
6473               delta = FLOOR (width / geometry->max_aspect - height, yinc);
6474               if (height + delta <= max_height)
6475                 height += delta;
6476             }
6477         }
6478     }
6479
6480 #undef FLOOR
6481
6482   *new_width = width;
6483   *new_height = height;
6484 }
6485
6486 /**
6487  * gdk_window_get_pointer:
6488  * @window: a #GdkWindow
6489  * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
6490  *      return the X coordinate
6491  * @y: (out) (allow-none):  return location for Y coordinate of pointer or %NULL to not
6492  *      return the Y coordinate
6493  * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
6494  *      modifier mask
6495  *
6496  * Obtains the current pointer position and modifier state.
6497  * The position is given in coordinates relative to the upper left
6498  * corner of @window.
6499  *
6500  * Return value: (transfer none): the window containing the pointer (as with
6501  * gdk_window_at_pointer()), or %NULL if the window containing the
6502  * pointer isn't known to GDK
6503  *
6504  * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
6505  **/
6506 GdkWindow*
6507 gdk_window_get_pointer (GdkWindow         *window,
6508                         gint              *x,
6509                         gint              *y,
6510                         GdkModifierType   *mask)
6511 {
6512   GdkDisplay *display;
6513
6514   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6515
6516   display = gdk_drawable_get_display (window);
6517
6518   return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
6519 }
6520
6521 /**
6522  * gdk_window_get_device_position:
6523  * @window: a #GdkWindow.
6524  * @device: #GdkDevice to query to.
6525  * @x: return location for the X coordinate of @device, or %NULL.
6526  * @y: return location for the Y coordinate of @device, or %NULL.
6527  * @mask: return location for the modifier mask, or %NULL.
6528  *
6529  * Obtains the current device position and modifier state.
6530  * The position is given in coordinates relative to the upper left
6531  * corner of @window.
6532  *
6533  * Returns: The window underneath @device (as with
6534  * gdk_display_get_window_at_device_position()), or %NULL if the
6535  * window is not known to GDK.
6536  *
6537  * Since: 3.0
6538  **/
6539 GdkWindow *
6540 gdk_window_get_device_position (GdkWindow       *window,
6541                                 GdkDevice       *device,
6542                                 gint            *x,
6543                                 gint            *y,
6544                                 GdkModifierType *mask)
6545 {
6546   GdkDisplay *display;
6547   gint tmp_x, tmp_y;
6548   GdkModifierType tmp_mask;
6549   GdkWindow *child;
6550
6551   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6552   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6553
6554   display = gdk_drawable_get_display (window);
6555   child = display->device_hooks->window_get_device_position (display, device, window,
6556                                                              &tmp_x, &tmp_y, &tmp_mask);
6557
6558   if (x)
6559     *x = tmp_x;
6560   if (y)
6561     *y = tmp_y;
6562   if (mask)
6563     *mask = tmp_mask;
6564
6565   _gdk_display_enable_motion_hints (display, device);
6566
6567   return child;
6568 }
6569
6570 /**
6571  * gdk_window_at_pointer:
6572  * @win_x: (out) (allow-none): return location for origin of the window under the pointer
6573  * @win_y: (out) (allow-none): return location for origin of the window under the pointer
6574  *
6575  * Obtains the window underneath the mouse pointer, returning the
6576  * location of that window in @win_x, @win_y. Returns %NULL if the
6577  * window under the mouse pointer is not known to GDK (if the window
6578  * belongs to another application and a #GdkWindow hasn't been created
6579  * for it with gdk_window_foreign_new())
6580  *
6581  * NOTE: For multihead-aware widgets or applications use
6582  * gdk_display_get_window_at_pointer() instead.
6583  *
6584  * Return value: (transfer none): window under the mouse pointer
6585  *
6586  * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
6587  **/
6588 GdkWindow*
6589 gdk_window_at_pointer (gint *win_x,
6590                        gint *win_y)
6591 {
6592   return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
6593 }
6594
6595 /**
6596  * gdk_get_default_root_window:
6597  *
6598  * Obtains the root window (parent all other windows are inside)
6599  * for the default display and screen.
6600  *
6601  * Return value: the default root window
6602  **/
6603 GdkWindow *
6604 gdk_get_default_root_window (void)
6605 {
6606   return gdk_screen_get_root_window (gdk_screen_get_default ());
6607 }
6608
6609 /**
6610  * gdk_window_foreign_new:
6611  * @anid: a native window handle.
6612  *
6613  * Wraps a native window for the default display in a #GdkWindow.
6614  * This may fail if the window has been destroyed.
6615  *
6616  * For example in the X backend, a native window handle is an Xlib
6617  * <type>XID</type>.
6618  *
6619  * Return value: the newly-created #GdkWindow wrapper for the
6620  *    native window or %NULL if the window has been destroyed.
6621  **/
6622 GdkWindow *
6623 gdk_window_foreign_new (GdkNativeWindow anid)
6624 {
6625   return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
6626 }
6627
6628 static void
6629 get_all_native_children (GdkWindowObject *private,
6630                          GList **native)
6631 {
6632   GdkWindowObject *child;
6633   GList *l;
6634
6635   for (l = private->children; l != NULL; l = l->next)
6636     {
6637       child = l->data;
6638
6639       if (gdk_window_has_impl (child))
6640         *native = g_list_prepend (*native, child);
6641       else
6642         get_all_native_children (child, native);
6643     }
6644 }
6645
6646
6647 static inline void
6648 gdk_window_raise_internal (GdkWindow *window)
6649 {
6650   GdkWindowObject *private = (GdkWindowObject *)window;
6651   GdkWindowObject *parent = private->parent;
6652   GdkWindowObject *above;
6653   GList *native_children;
6654   GList *l, listhead;
6655   GdkWindowImplIface *impl_iface;
6656
6657   if (parent)
6658     {
6659       parent->children = g_list_remove (parent->children, window);
6660       parent->children = g_list_prepend (parent->children, window);
6661     }
6662
6663   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6664   /* Just do native raise for toplevels */
6665   if (gdk_window_is_toplevel (private) ||
6666       /* The restack_under codepath should work correctly even if the parent
6667          is native, but it relies on the order of ->children to be correct,
6668          and some apps like SWT reorder the x windows without gdks knowledge,
6669          so we use raise directly in order to make these behave as before
6670          when using native windows */
6671       (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
6672     {
6673       impl_iface->raise (window);
6674     }
6675   else if (gdk_window_has_impl (private))
6676     {
6677       above = find_native_sibling_above (parent, private);
6678       if (above)
6679         {
6680           listhead.data = window;
6681           listhead.next = NULL;
6682           listhead.prev = NULL;
6683           impl_iface->restack_under ((GdkWindow *)above,
6684                                      &listhead);
6685         }
6686       else
6687         impl_iface->raise (window);
6688     }
6689   else
6690     {
6691       native_children = NULL;
6692       get_all_native_children (private, &native_children);
6693       if (native_children != NULL)
6694         {
6695           above = find_native_sibling_above (parent, private);
6696
6697           if (above)
6698             impl_iface->restack_under ((GdkWindow *)above,
6699                                        native_children);
6700           else
6701             {
6702               /* Right order, since native_children is bottom-topmost first */
6703               for (l = native_children; l != NULL; l = l->next)
6704                 impl_iface->raise (l->data);
6705             }
6706
6707           g_list_free (native_children);
6708         }
6709
6710     }
6711 }
6712
6713 /* Returns TRUE If the native window was mapped or unmapped */
6714 static gboolean
6715 set_viewable (GdkWindowObject *w,
6716               gboolean val)
6717 {
6718   GdkWindowObject *child;
6719   GdkWindowImplIface *impl_iface;
6720   GList *l;
6721
6722   if (w->viewable == val)
6723     return FALSE;
6724
6725   w->viewable = val;
6726
6727   if (val)
6728     recompute_visible_regions (w, FALSE, FALSE);
6729
6730   for (l = w->children; l != NULL; l = l->next)
6731     {
6732       child = l->data;
6733
6734       if (GDK_WINDOW_IS_MAPPED (child) &&
6735           child->window_type != GDK_WINDOW_FOREIGN)
6736         set_viewable (child, val);
6737     }
6738
6739   if (!_gdk_native_windows &&
6740       gdk_window_has_impl (w)  &&
6741       w->window_type != GDK_WINDOW_FOREIGN &&
6742       !gdk_window_is_toplevel (w))
6743     {
6744       /* For most native windows we show/hide them not when they are
6745        * mapped/unmapped, because that may not produce the correct results.
6746        * For instance, if a native window have a non-native parent which is
6747        * hidden, but its native parent is viewable then showing the window
6748        * would make it viewable to X but its not viewable wrt the non-native
6749        * hierarchy. In order to handle this we track the gdk side viewability
6750        * and only map really viewable windows.
6751        *
6752        * There are two exceptions though:
6753        *
6754        * For foreign windows we don't want ever change the mapped state
6755        * except when explicitly done via gdk_window_show/hide, as this may
6756        * cause problems for client owning the foreign window when its window
6757        * is suddenly mapped or unmapped.
6758        *
6759        * For toplevel windows embedded in a foreign window (e.g. a plug)
6760        * we sometimes synthesize a map of a window, but the native
6761        * window is really shown by the embedder, so we don't want to
6762        * do the show ourselves. We can't really tell this case from the normal
6763        * toplevel show as such toplevels are seen by gdk as parents of the
6764        * root window, so we make an exception for all toplevels.
6765        *
6766        * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
6767        * like this, so we just always show/hide directly.
6768        */
6769
6770       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
6771       if (val)
6772         impl_iface->show ((GdkWindow *)w, FALSE);
6773       else
6774         impl_iface->hide ((GdkWindow *)w);
6775
6776       return TRUE;
6777     }
6778
6779   return FALSE;
6780 }
6781
6782 /* Returns TRUE If the native window was mapped or unmapped */
6783 gboolean
6784 _gdk_window_update_viewable (GdkWindow *window)
6785 {
6786   GdkWindowObject *priv = (GdkWindowObject *)window;
6787   gboolean viewable;
6788
6789   if (priv->window_type == GDK_WINDOW_FOREIGN ||
6790       priv->window_type == GDK_WINDOW_ROOT)
6791     viewable = TRUE;
6792   else if (gdk_window_is_toplevel (priv) ||
6793            priv->parent->viewable)
6794     viewable = GDK_WINDOW_IS_MAPPED (priv);
6795   else
6796     viewable = FALSE;
6797
6798   return set_viewable (priv, viewable);
6799 }
6800
6801 static void
6802 gdk_window_show_internal (GdkWindow *window, gboolean raise)
6803 {
6804   GdkWindowObject *private;
6805   GdkWindowImplIface *impl_iface;
6806   gboolean was_mapped, was_viewable;
6807   gboolean did_show;
6808
6809   g_return_if_fail (GDK_IS_WINDOW (window));
6810
6811   private = (GdkWindowObject *) window;
6812   if (private->destroyed)
6813     return;
6814
6815   was_mapped = GDK_WINDOW_IS_MAPPED (window);
6816   was_viewable = private->viewable;
6817
6818   if (raise)
6819     /* Keep children in (reverse) stacking order */
6820     gdk_window_raise_internal (window);
6821
6822   if (gdk_window_has_impl (private))
6823     {
6824       if (!was_mapped)
6825         gdk_synthesize_window_state (window,
6826                                      GDK_WINDOW_STATE_WITHDRAWN,
6827                                      0);
6828     }
6829   else
6830     {
6831       private->state = 0;
6832     }
6833
6834   did_show = _gdk_window_update_viewable (window);
6835
6836   /* If it was already viewable the backend show op won't be called, call it
6837      again to ensure things happen right if the mapped tracking was not right
6838      for e.g. a foreign window.
6839      Dunno if this is strictly needed but its what happened pre-csw.
6840      Also show if not done by gdk_window_update_viewable. */
6841   if (gdk_window_has_impl (private) && (was_viewable || !did_show))
6842     {
6843       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6844       impl_iface->show ((GdkWindow *)private,
6845                         !did_show ? was_mapped : TRUE);
6846     }
6847
6848   if (!was_mapped && !gdk_window_has_impl (private))
6849     {
6850       if (private->event_mask & GDK_STRUCTURE_MASK)
6851         _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
6852
6853       if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
6854         _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
6855     }
6856
6857   if (!was_mapped || raise)
6858     {
6859       recompute_visible_regions (private, TRUE, FALSE);
6860
6861       /* If any decendants became visible we need to send visibility notify */
6862       gdk_window_update_visibility_recursively (private, NULL);
6863
6864       if (gdk_window_is_viewable (window))
6865         {
6866           _gdk_synthesize_crossing_events_for_geometry_change (window);
6867           gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
6868         }
6869     }
6870 }
6871
6872 /**
6873  * gdk_window_show_unraised:
6874  * @window: a #GdkWindow
6875  *
6876  * Shows a #GdkWindow onscreen, but does not modify its stacking
6877  * order. In contrast, gdk_window_show() will raise the window
6878  * to the top of the window stack.
6879  *
6880  * On the X11 platform, in Xlib terms, this function calls
6881  * XMapWindow() (it also updates some internal GDK state, which means
6882  * that you can't really use XMapWindow() directly on a GDK window).
6883  */
6884 void
6885 gdk_window_show_unraised (GdkWindow *window)
6886 {
6887   gdk_window_show_internal (window, FALSE);
6888 }
6889
6890 /**
6891  * gdk_window_raise:
6892  * @window: a #GdkWindow
6893  *
6894  * Raises @window to the top of the Z-order (stacking order), so that
6895  * other windows with the same parent window appear below @window.
6896  * This is true whether or not the windows are visible.
6897  *
6898  * If @window is a toplevel, the window manager may choose to deny the
6899  * request to move the window in the Z-order, gdk_window_raise() only
6900  * requests the restack, does not guarantee it.
6901  */
6902 void
6903 gdk_window_raise (GdkWindow *window)
6904 {
6905   GdkWindowObject *private;
6906   GdkRegion *old_region, *new_region;
6907
6908   g_return_if_fail (GDK_IS_WINDOW (window));
6909
6910   private = (GdkWindowObject *) window;
6911   if (private->destroyed)
6912     return;
6913
6914   gdk_window_flush_if_exposing (window);
6915
6916   old_region = NULL;
6917   if (gdk_window_is_viewable (window) &&
6918       !private->input_only)
6919     old_region = gdk_region_copy (private->clip_region);
6920
6921   /* Keep children in (reverse) stacking order */
6922   gdk_window_raise_internal (window);
6923
6924   recompute_visible_regions (private, TRUE, FALSE);
6925
6926   if (old_region)
6927     {
6928       new_region = gdk_region_copy (private->clip_region);
6929
6930       gdk_region_subtract (new_region, old_region);
6931       gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
6932
6933       gdk_region_destroy (old_region);
6934       gdk_region_destroy (new_region);
6935     }
6936 }
6937
6938 static void
6939 gdk_window_lower_internal (GdkWindow *window)
6940 {
6941   GdkWindowObject *private = (GdkWindowObject *)window;
6942   GdkWindowObject *parent = private->parent;
6943   GdkWindowImplIface *impl_iface;
6944   GdkWindowObject *above;
6945   GList *native_children;
6946   GList *l, listhead;
6947
6948   if (parent)
6949     {
6950       parent->children = g_list_remove (parent->children, window);
6951       parent->children = g_list_append (parent->children, window);
6952     }
6953
6954   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6955   /* Just do native lower for toplevels */
6956   if (gdk_window_is_toplevel (private) ||
6957       /* The restack_under codepath should work correctly even if the parent
6958          is native, but it relies on the order of ->children to be correct,
6959          and some apps like SWT reorder the x windows without gdks knowledge,
6960          so we use lower directly in order to make these behave as before
6961          when using native windows */
6962       (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
6963     {
6964       impl_iface->lower (window);
6965     }
6966   else if (gdk_window_has_impl (private))
6967     {
6968       above = find_native_sibling_above (parent, private);
6969       if (above)
6970         {
6971           listhead.data = window;
6972           listhead.next = NULL;
6973           listhead.prev = NULL;
6974           impl_iface->restack_under ((GdkWindow *)above, &listhead);
6975         }
6976       else
6977         impl_iface->raise (window);
6978     }
6979   else
6980     {
6981       native_children = NULL;
6982       get_all_native_children (private, &native_children);
6983       if (native_children != NULL)
6984         {
6985           above = find_native_sibling_above (parent, private);
6986
6987           if (above)
6988             impl_iface->restack_under ((GdkWindow *)above,
6989                                        native_children);
6990           else
6991             {
6992               /* Right order, since native_children is bottom-topmost first */
6993               for (l = native_children; l != NULL; l = l->next)
6994                 impl_iface->raise (l->data);
6995             }
6996
6997           g_list_free (native_children);
6998         }
6999
7000     }
7001 }
7002
7003 static void
7004 gdk_window_invalidate_in_parent (GdkWindowObject *private)
7005 {
7006   GdkRectangle r, child;
7007
7008   if (gdk_window_is_toplevel (private))
7009     return;
7010
7011   /* get the visible rectangle of the parent */
7012   r.x = r.y = 0;
7013   r.width = private->parent->width;
7014   r.height = private->parent->height;
7015
7016   child.x = private->x;
7017   child.y = private->y;
7018   child.width = private->width;
7019   child.height = private->height;
7020   gdk_rectangle_intersect (&r, &child, &r);
7021
7022   gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
7023 }
7024
7025
7026 /**
7027  * gdk_window_lower:
7028  * @window: a #GdkWindow
7029  *
7030  * Lowers @window to the bottom of the Z-order (stacking order), so that
7031  * other windows with the same parent window appear above @window.
7032  * This is true whether or not the other windows are visible.
7033  *
7034  * If @window is a toplevel, the window manager may choose to deny the
7035  * request to move the window in the Z-order, gdk_window_lower() only
7036  * requests the restack, does not guarantee it.
7037  *
7038  * Note that gdk_window_show() raises the window again, so don't call this
7039  * function before gdk_window_show(). (Try gdk_window_show_unraised().)
7040  */
7041 void
7042 gdk_window_lower (GdkWindow *window)
7043 {
7044   GdkWindowObject *private;
7045
7046   g_return_if_fail (GDK_IS_WINDOW (window));
7047
7048   private = (GdkWindowObject *) window;
7049   if (private->destroyed)
7050     return;
7051
7052   gdk_window_flush_if_exposing (window);
7053
7054   /* Keep children in (reverse) stacking order */
7055   gdk_window_lower_internal (window);
7056
7057   recompute_visible_regions (private, TRUE, FALSE);
7058
7059   _gdk_synthesize_crossing_events_for_geometry_change (window);
7060   gdk_window_invalidate_in_parent (private);
7061 }
7062
7063 /**
7064  * gdk_window_restack:
7065  * @window: a #GdkWindow
7066  * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
7067  * @above: a boolean
7068  *
7069  * Changes the position of  @window in the Z-order (stacking order), so that
7070  * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
7071  * %FALSE).
7072  *
7073  * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
7074  * lowers the window.
7075  *
7076  * If @window is a toplevel, the window manager may choose to deny the
7077  * request to move the window in the Z-order, gdk_window_restack() only
7078  * requests the restack, does not guarantee it.
7079  *
7080  * Since: 2.18
7081  */
7082 void
7083 gdk_window_restack (GdkWindow     *window,
7084                     GdkWindow     *sibling,
7085                     gboolean       above)
7086 {
7087   GdkWindowObject *private;
7088   GdkWindowImplIface *impl_iface;
7089   GdkWindowObject *parent;
7090   GdkWindowObject *above_native;
7091   GList *sibling_link;
7092   GList *native_children;
7093   GList *l, listhead;
7094
7095   g_return_if_fail (GDK_IS_WINDOW (window));
7096   g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
7097
7098   private = (GdkWindowObject *) window;
7099   if (private->destroyed)
7100     return;
7101
7102   if (sibling == NULL)
7103     {
7104       if (above)
7105         gdk_window_raise (window);
7106       else
7107         gdk_window_lower (window);
7108       return;
7109     }
7110
7111   gdk_window_flush_if_exposing (window);
7112
7113   if (gdk_window_is_toplevel (private))
7114     {
7115       g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
7116       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7117       impl_iface->restack_toplevel (window, sibling, above);
7118       return;
7119     }
7120
7121   parent = private->parent;
7122   if (parent)
7123     {
7124       sibling_link = g_list_find (parent->children, sibling);
7125       g_return_if_fail (sibling_link != NULL);
7126       if (sibling_link == NULL)
7127         return;
7128
7129       parent->children = g_list_remove (parent->children, window);
7130       if (above)
7131         parent->children = g_list_insert_before (parent->children,
7132                                                  sibling_link,
7133                                                  window);
7134       else
7135         parent->children = g_list_insert_before (parent->children,
7136                                                  sibling_link->next,
7137                                                  window);
7138
7139       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7140       if (gdk_window_has_impl (private))
7141         {
7142           above_native = find_native_sibling_above (parent, private);
7143           if (above_native)
7144             {
7145               listhead.data = window;
7146               listhead.next = NULL;
7147               listhead.prev = NULL;
7148               impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
7149             }
7150           else
7151             impl_iface->raise (window);
7152         }
7153       else
7154         {
7155           native_children = NULL;
7156           get_all_native_children (private, &native_children);
7157           if (native_children != NULL)
7158             {
7159               above_native = find_native_sibling_above (parent, private);
7160               if (above_native)
7161                 impl_iface->restack_under ((GdkWindow *)above_native,
7162                                            native_children);
7163               else
7164                 {
7165                   /* Right order, since native_children is bottom-topmost first */
7166                   for (l = native_children; l != NULL; l = l->next)
7167                     impl_iface->raise (l->data);
7168                 }
7169
7170               g_list_free (native_children);
7171             }
7172         }
7173     }
7174
7175   recompute_visible_regions (private, TRUE, FALSE);
7176
7177   _gdk_synthesize_crossing_events_for_geometry_change (window);
7178   gdk_window_invalidate_in_parent (private);
7179 }
7180
7181
7182 /**
7183  * gdk_window_show:
7184  * @window: a #GdkWindow
7185  *
7186  * Like gdk_window_show_unraised(), but also raises the window to the
7187  * top of the window stack (moves the window to the front of the
7188  * Z-order).
7189  *
7190  * This function maps a window so it's visible onscreen. Its opposite
7191  * is gdk_window_hide().
7192  *
7193  * When implementing a #GtkWidget, you should call this function on the widget's
7194  * #GdkWindow as part of the "map" method.
7195  */
7196 void
7197 gdk_window_show (GdkWindow *window)
7198 {
7199   gdk_window_show_internal (window, TRUE);
7200 }
7201
7202 /**
7203  * gdk_window_hide:
7204  * @window: a #GdkWindow
7205  *
7206  * For toplevel windows, withdraws them, so they will no longer be
7207  * known to the window manager; for all windows, unmaps them, so
7208  * they won't be displayed. Normally done automatically as
7209  * part of gtk_widget_hide().
7210  */
7211 void
7212 gdk_window_hide (GdkWindow *window)
7213 {
7214   GdkWindowObject *private;
7215   GdkWindowImplIface *impl_iface;
7216   gboolean was_mapped, did_hide;
7217
7218   g_return_if_fail (GDK_IS_WINDOW (window));
7219
7220   private = (GdkWindowObject *) window;
7221   if (private->destroyed)
7222     return;
7223
7224   was_mapped = GDK_WINDOW_IS_MAPPED (private);
7225
7226   if (gdk_window_has_impl (private))
7227     {
7228
7229       if (GDK_WINDOW_IS_MAPPED (window))
7230         gdk_synthesize_window_state (window,
7231                                      0,
7232                                      GDK_WINDOW_STATE_WITHDRAWN);
7233     }
7234   else if (was_mapped)
7235     {
7236       GdkDisplay *display;
7237       GdkDeviceManager *device_manager;
7238       GList *devices, *d;
7239
7240       /* May need to break grabs on children */
7241       display = gdk_drawable_get_display (window);
7242       device_manager = gdk_display_get_device_manager (display);
7243
7244       /* Get all devices */
7245       devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
7246       devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
7247       devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
7248
7249       for (d = devices; d; d = d->next)
7250         {
7251           GdkDevice *device = d->data;
7252
7253           if (_gdk_display_end_device_grab (display, device,
7254                                             _gdk_windowing_window_get_next_serial (display),
7255                                             window,
7256                                             TRUE))
7257             gdk_device_ungrab (device, GDK_CURRENT_TIME);
7258         }
7259
7260       private->state = GDK_WINDOW_STATE_WITHDRAWN;
7261       g_list_free (devices);
7262     }
7263
7264   did_hide = _gdk_window_update_viewable (window);
7265
7266   /* Hide foreign window as those are not handled by update_viewable. */
7267   if (gdk_window_has_impl (private) && (!did_hide))
7268     {
7269       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7270       impl_iface->hide (window);
7271     }
7272
7273   recompute_visible_regions (private, TRUE, FALSE);
7274
7275   /* all decendants became non-visible, we need to send visibility notify */
7276   gdk_window_update_visibility_recursively (private, NULL);
7277
7278   if (was_mapped && !gdk_window_has_impl (private))
7279     {
7280       if (private->event_mask & GDK_STRUCTURE_MASK)
7281         _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7282
7283       if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
7284         _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7285
7286       _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
7287     }
7288
7289   /* Invalidate the rect */
7290   if (was_mapped)
7291     gdk_window_invalidate_in_parent (private);
7292 }
7293
7294 /**
7295  * gdk_window_withdraw:
7296  * @window: a toplevel #GdkWindow
7297  *
7298  * Withdraws a window (unmaps it and asks the window manager to forget about it).
7299  * This function is not really useful as gdk_window_hide() automatically
7300  * withdraws toplevel windows before hiding them.
7301  **/
7302 void
7303 gdk_window_withdraw (GdkWindow *window)
7304 {
7305   GdkWindowObject *private;
7306   GdkWindowImplIface *impl_iface;
7307   gboolean was_mapped;
7308
7309   g_return_if_fail (GDK_IS_WINDOW (window));
7310
7311   private = (GdkWindowObject *) window;
7312   if (private->destroyed)
7313     return;
7314
7315   was_mapped = GDK_WINDOW_IS_MAPPED (private);
7316
7317   if (gdk_window_has_impl (private))
7318     {
7319       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7320       impl_iface->withdraw (window);
7321
7322       if (was_mapped)
7323         {
7324           if (private->event_mask & GDK_STRUCTURE_MASK)
7325             _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7326
7327           if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
7328             _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7329
7330           _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
7331         }
7332
7333       recompute_visible_regions (private, TRUE, FALSE);
7334     }
7335 }
7336
7337 /**
7338  * gdk_window_set_events:
7339  * @window: a #GdkWindow
7340  * @event_mask: event mask for @window
7341  *
7342  * The event mask for a window determines which events will be reported
7343  * for that window from all master input devices. For example, an event mask
7344  * including #GDK_BUTTON_PRESS_MASK means the window should report button
7345  * press events. The event mask is the bitwise OR of values from the
7346  * #GdkEventMask enumeration.
7347  **/
7348 void
7349 gdk_window_set_events (GdkWindow       *window,
7350                        GdkEventMask     event_mask)
7351 {
7352   GdkWindowObject *private;
7353   GdkWindowImplIface *impl_iface;
7354   GdkDisplay *display;
7355
7356   g_return_if_fail (GDK_IS_WINDOW (window));
7357
7358   private = (GdkWindowObject *) window;
7359   if (private->destroyed)
7360     return;
7361
7362   /* If motion hint is disabled, enable motion events again */
7363   display = gdk_drawable_get_display (window);
7364   if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
7365       !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
7366     {
7367       GList *devices = private->devices_inside;
7368
7369       while (devices)
7370         {
7371           _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
7372           devices = devices->next;
7373         }
7374     }
7375
7376   private->event_mask = event_mask;
7377
7378   if (gdk_window_has_impl (private))
7379     {
7380       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7381       impl_iface->set_events (window,
7382                               get_native_event_mask (private));
7383     }
7384
7385 }
7386
7387 /**
7388  * gdk_window_get_events:
7389  * @window: a #GdkWindow
7390  *
7391  * Gets the event mask for @window for all master input devices. See
7392  * gdk_window_set_events().
7393  *
7394  * Return value: event mask for @window
7395  **/
7396 GdkEventMask
7397 gdk_window_get_events (GdkWindow *window)
7398 {
7399   GdkWindowObject *private;
7400
7401   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7402
7403   private = (GdkWindowObject *) window;
7404   if (private->destroyed)
7405     return 0;
7406
7407   return private->event_mask;
7408 }
7409
7410 /**
7411  * gdk_window_set_device_events:
7412  * @window: a #GdkWindow
7413  * @device: #GdkDevice to enable events for.
7414  * @event_mask: event mask for @window
7415  *
7416  * Sets the event mask for a given device (Normally a floating device, not
7417  * attached to any visible pointer) to @window. For example, an event mask
7418  * including #GDK_BUTTON_PRESS_MASK means the window should report button
7419  * press events. The event mask is the bitwise OR of values from the
7420  * #GdkEventMask enumeration.
7421  *
7422  * Since: 3.0
7423  **/
7424 void
7425 gdk_window_set_device_events (GdkWindow    *window,
7426                               GdkDevice    *device,
7427                               GdkEventMask  event_mask)
7428 {
7429   GdkEventMask device_mask;
7430   GdkWindowObject *private;
7431   GdkDisplay *display;
7432   GdkWindow *native;
7433
7434   g_return_if_fail (GDK_IS_WINDOW (window));
7435   g_return_if_fail (GDK_IS_DEVICE (device));
7436
7437   if (GDK_WINDOW_DESTROYED (window))
7438     return;
7439
7440   private = (GdkWindowObject *) window;
7441
7442   /* If motion hint is disabled, enable motion events again */
7443   display = gdk_drawable_get_display (window);
7444   if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
7445       !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
7446     _gdk_display_enable_motion_hints (display, device);
7447
7448   if (G_UNLIKELY (!private->device_events))
7449     private->device_events = g_hash_table_new (NULL, NULL);
7450
7451   if (event_mask == 0)
7452     {
7453       /* FIXME: unsetting events on a master device
7454        * would restore private->event_mask
7455        */
7456       g_hash_table_remove (private->device_events, device);
7457     }
7458   else
7459     g_hash_table_insert (private->device_events, device,
7460                          GINT_TO_POINTER (event_mask));
7461
7462   if (_gdk_native_windows)
7463     native = window;
7464   else
7465     native = gdk_window_get_toplevel (window);
7466
7467   while (gdk_window_is_offscreen ((GdkWindowObject *)native))
7468     {
7469       native = gdk_offscreen_window_get_embedder (native);
7470
7471       if (native == NULL ||
7472           (!_gdk_window_has_impl (native) &&
7473            !gdk_window_is_viewable (native)))
7474         return;
7475
7476       native = gdk_window_get_toplevel (native);
7477     }
7478
7479   device_mask = get_native_device_event_mask (private, device);
7480   GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
7481 }
7482
7483 /**
7484  * gdk_window_get_device_events:
7485  * @window: a #GdkWindow.
7486  * @device: a #GdkDevice.
7487  *
7488  * Returns the event mask for @window corresponding to an specific device.
7489  *
7490  * Returns: device event mask for @window
7491  *
7492  * Since: 3.0
7493  **/
7494 GdkEventMask
7495 gdk_window_get_device_events (GdkWindow *window,
7496                               GdkDevice *device)
7497 {
7498   GdkWindowObject *private;
7499   GdkEventMask mask;
7500
7501   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7502   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
7503
7504   if (GDK_WINDOW_DESTROYED (window))
7505     return 0;
7506
7507   private = (GdkWindowObject *) window;
7508
7509   if (!private->device_events)
7510     return 0;
7511
7512   mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
7513
7514   /* FIXME: device could be controlled by private->event_mask */
7515
7516   return mask;
7517 }
7518
7519 static void
7520 gdk_window_move_resize_toplevel (GdkWindow *window,
7521                                  gboolean   with_move,
7522                                  gint       x,
7523                                  gint       y,
7524                                  gint       width,
7525                                  gint       height)
7526 {
7527   GdkWindowObject *private;
7528   GdkRegion *old_region, *new_region;
7529   GdkWindowImplIface *impl_iface;
7530   gboolean expose;
7531   int old_x, old_y, old_abs_x, old_abs_y;
7532   int dx, dy;
7533   gboolean is_resize;
7534
7535   private = (GdkWindowObject *) window;
7536
7537   expose = FALSE;
7538   old_region = NULL;
7539
7540   old_x = private->x;
7541   old_y = private->y;
7542
7543   is_resize = (width != -1) || (height != -1);
7544
7545   if (gdk_window_is_viewable (window) &&
7546       !private->input_only)
7547     {
7548       expose = TRUE;
7549       old_region = gdk_region_copy (private->clip_region);
7550     }
7551
7552   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7553   impl_iface->move_resize (window, with_move, x, y, width, height);
7554
7555   dx = private->x - old_x;
7556   dy = private->y - old_y;
7557
7558   old_abs_x = private->abs_x;
7559   old_abs_y = private->abs_y;
7560
7561   /* Avoid recomputing for pure toplevel moves, for performance reasons */
7562   if (is_resize)
7563     recompute_visible_regions (private, TRUE, FALSE);
7564
7565   if (expose)
7566     {
7567       new_region = gdk_region_copy (private->clip_region);
7568
7569       /* This is the newly exposed area (due to any resize),
7570        * X will expose it, but lets do that without the
7571        * roundtrip
7572        */
7573       gdk_region_subtract (new_region, old_region);
7574       gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
7575
7576       gdk_region_destroy (old_region);
7577       gdk_region_destroy (new_region);
7578     }
7579
7580   _gdk_synthesize_crossing_events_for_geometry_change (window);
7581 }
7582
7583
7584 static void
7585 move_native_children (GdkWindowObject *private)
7586 {
7587   GList *l;
7588   GdkWindowObject *child;
7589   GdkWindowImplIface *impl_iface;
7590
7591   for (l = private->children; l; l = l->next)
7592     {
7593       child = l->data;
7594
7595       if (child->impl != private->impl)
7596         {
7597           impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
7598           impl_iface->move_resize ((GdkWindow *)child, TRUE,
7599                                    child->x, child->y,
7600                                    child->width, child->height);
7601         }
7602       else
7603         move_native_children  (child);
7604     }
7605 }
7606
7607 static gboolean
7608 collect_native_child_region_helper (GdkWindowObject *window,
7609                                     GdkWindow *impl,
7610                                     GdkRegion **region,
7611                                     int x_offset,
7612                                     int y_offset)
7613 {
7614   GdkWindowObject *child;
7615   GdkRegion *tmp;
7616   GList *l;
7617
7618   for (l = window->children; l != NULL; l = l->next)
7619     {
7620       child = l->data;
7621
7622       if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
7623         continue;
7624
7625       if (child->impl != impl)
7626         {
7627           tmp = gdk_region_copy (child->clip_region);
7628           gdk_region_offset (tmp,
7629                              x_offset + child->x,
7630                              y_offset + child->y);
7631           if (*region == NULL)
7632             *region = tmp;
7633           else
7634             {
7635               gdk_region_union (*region, tmp);
7636               gdk_region_destroy (tmp);
7637             }
7638         }
7639       else
7640         collect_native_child_region_helper (child, impl, region,
7641                                             x_offset + child->x,
7642                                             y_offset + child->y);
7643     }
7644
7645   return FALSE;
7646 }
7647
7648 static GdkRegion *
7649 collect_native_child_region (GdkWindowObject *window,
7650                              gboolean include_this)
7651 {
7652   GdkRegion *region;
7653
7654   if (include_this && gdk_window_has_impl (window) && window->viewable)
7655     return gdk_region_copy (window->clip_region);
7656
7657   region = NULL;
7658
7659   collect_native_child_region_helper (window, window->impl, &region, 0, 0);
7660
7661   return region;
7662 }
7663
7664
7665 static void
7666 gdk_window_move_resize_internal (GdkWindow *window,
7667                                  gboolean   with_move,
7668                                  gint       x,
7669                                  gint       y,
7670                                  gint       width,
7671                                  gint       height)
7672 {
7673   GdkWindowObject *private;
7674   GdkRegion *old_region, *new_region, *copy_area;
7675   GdkRegion *old_native_child_region, *new_native_child_region;
7676   GdkWindowObject *impl_window;
7677   GdkWindowImplIface *impl_iface;
7678   gboolean expose;
7679   int old_x, old_y, old_abs_x, old_abs_y;
7680   int dx, dy;
7681
7682   g_return_if_fail (GDK_IS_WINDOW (window));
7683
7684   private = (GdkWindowObject *) window;
7685   if (private->destroyed)
7686     return;
7687
7688   if (gdk_window_is_toplevel (private))
7689     {
7690       gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
7691       return;
7692     }
7693
7694   /* Bail early if no change */
7695   if (private->width == width &&
7696       private->height == height &&
7697       (!with_move ||
7698        (private->x == x &&
7699         private->y == y)))
7700     return;
7701
7702   gdk_window_flush_if_exposing (window);
7703
7704   /* Handle child windows */
7705
7706   expose = FALSE;
7707   old_region = NULL;
7708
7709   impl_window = gdk_window_get_impl_window (private);
7710
7711   old_x = private->x;
7712   old_y = private->y;
7713
7714   old_native_child_region = NULL;
7715   if (gdk_window_is_viewable (window) &&
7716       !private->input_only)
7717     {
7718       expose = TRUE;
7719
7720       old_region = gdk_region_copy (private->clip_region);
7721       /* Adjust region to parent window coords */
7722       gdk_region_offset (old_region, private->x, private->y);
7723
7724       old_native_child_region = collect_native_child_region (private, TRUE);
7725       if (old_native_child_region)
7726         {
7727           /* Adjust region to parent window coords */
7728           gdk_region_offset (old_native_child_region, private->x, private->y);
7729
7730           /* Any native window move will immediately copy stuff to the destination, which may overwrite a
7731            * source or destination for a delayed GdkWindowRegionMove. So, we need
7732            * to flush those here for the parent window and all overlapped subwindows
7733            * of it. And we need to do this before setting the new clips as those will be
7734            * affecting this.
7735            */
7736           gdk_window_flush_recursive (private->parent);
7737         }
7738     }
7739
7740   /* Set the new position and size */
7741   if (with_move)
7742     {
7743       private->x = x;
7744       private->y = y;
7745     }
7746   if (!(width < 0 && height < 0))
7747     {
7748       if (width < 1)
7749         width = 1;
7750       private->width = width;
7751       if (height < 1)
7752         height = 1;
7753       private->height = height;
7754     }
7755
7756   dx = private->x - old_x;
7757   dy = private->y - old_y;
7758
7759   old_abs_x = private->abs_x;
7760   old_abs_y = private->abs_y;
7761
7762   recompute_visible_regions (private, TRUE, FALSE);
7763
7764   new_native_child_region = NULL;
7765   if (old_native_child_region)
7766     {
7767       new_native_child_region = collect_native_child_region (private, TRUE);
7768       /* Adjust region to parent window coords */
7769       gdk_region_offset (new_native_child_region, private->x, private->y);
7770     }
7771
7772   if (gdk_window_has_impl (private))
7773     {
7774       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7775
7776       /* Do the actual move after recomputing things, as this will have set the shape to
7777          the now correct one, thus avoiding copying regions that should not be copied. */
7778       impl_iface->move_resize (window, TRUE,
7779                                private->x, private->y,
7780                                private->width, private->height);
7781     }
7782   else if (old_abs_x != private->abs_x ||
7783            old_abs_y != private->abs_y)
7784     move_native_children (private);
7785
7786   if (expose)
7787     {
7788       new_region = gdk_region_copy (private->clip_region);
7789       /* Adjust region to parent window coords */
7790       gdk_region_offset (new_region, private->x, private->y);
7791
7792       /* copy_area:
7793        * Part of the data at the new location can be copied from the
7794        * old location, this area is the intersection of the old region
7795        * moved as the copy will move it and then intersected with
7796        * the new region.
7797        *
7798        * new_region:
7799        * Everything in the old and new regions that is not copied must be
7800        * invalidated (including children) as this is newly exposed
7801        */
7802       copy_area = gdk_region_copy (new_region);
7803
7804       gdk_region_union (new_region, old_region);
7805
7806       if (old_native_child_region)
7807         {
7808           /* Don't copy from inside native children, as this is copied by
7809            * the native window move.
7810            */
7811           gdk_region_subtract (old_region, old_native_child_region);
7812         }
7813       gdk_region_offset (old_region, dx, dy);
7814
7815       gdk_region_intersect (copy_area, old_region);
7816
7817       if (new_native_child_region)
7818         {
7819           /* Don't copy any bits that would cause a read from the moved
7820              native windows, as we can't read that data */
7821           gdk_region_offset (new_native_child_region, dx, dy);
7822           gdk_region_subtract (copy_area, new_native_child_region);
7823           gdk_region_offset (new_native_child_region, -dx, -dy);
7824         }
7825
7826       gdk_region_subtract (new_region, copy_area);
7827
7828       /* Convert old region to impl coords */
7829       gdk_region_offset (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
7830
7831       /* convert from parent coords to impl */
7832       gdk_region_offset (copy_area, private->abs_x - private->x, private->abs_y - private->y);
7833
7834       move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
7835
7836       /* Invalidate affected part in the parent window
7837        *  (no higher window should be affected)
7838        * We also invalidate any children in that area, which could include
7839        * this window if it still overlaps that area.
7840        */
7841       if (old_native_child_region)
7842         {
7843           /* No need to expose the region that the native window move copies */
7844           gdk_region_offset (old_native_child_region, dx, dy);
7845           gdk_region_intersect (old_native_child_region, new_native_child_region);
7846           gdk_region_subtract (new_region, old_native_child_region);
7847         }
7848       gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
7849
7850       gdk_region_destroy (old_region);
7851       gdk_region_destroy (new_region);
7852     }
7853
7854   if (old_native_child_region)
7855     {
7856       gdk_region_destroy (old_native_child_region);
7857       gdk_region_destroy (new_native_child_region);
7858     }
7859
7860   _gdk_synthesize_crossing_events_for_geometry_change (window);
7861 }
7862
7863
7864
7865 /**
7866  * gdk_window_move:
7867  * @window: a #GdkWindow
7868  * @x: X coordinate relative to window's parent
7869  * @y: Y coordinate relative to window's parent
7870  *
7871  * Repositions a window relative to its parent window.
7872  * For toplevel windows, window managers may ignore or modify the move;
7873  * you should probably use gtk_window_move() on a #GtkWindow widget
7874  * anyway, instead of using GDK functions. For child windows,
7875  * the move will reliably succeed.
7876  *
7877  * If you're also planning to resize the window, use gdk_window_move_resize()
7878  * to both move and resize simultaneously, for a nicer visual effect.
7879  **/
7880 void
7881 gdk_window_move (GdkWindow *window,
7882                  gint       x,
7883                  gint       y)
7884 {
7885   gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
7886 }
7887
7888 /**
7889  * gdk_window_resize:
7890  * @window: a #GdkWindow
7891  * @width: new width of the window
7892  * @height: new height of the window
7893  *
7894  * Resizes @window; for toplevel windows, asks the window manager to resize
7895  * the window. The window manager may not allow the resize. When using GTK+,
7896  * use gtk_window_resize() instead of this low-level GDK function.
7897  *
7898  * Windows may not be resized below 1x1.
7899  *
7900  * If you're also planning to move the window, use gdk_window_move_resize()
7901  * to both move and resize simultaneously, for a nicer visual effect.
7902  **/
7903 void
7904 gdk_window_resize (GdkWindow *window,
7905                    gint       width,
7906                    gint       height)
7907 {
7908   gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
7909 }
7910
7911
7912 /**
7913  * gdk_window_move_resize:
7914  * @window: a #GdkWindow
7915  * @x: new X position relative to window's parent
7916  * @y: new Y position relative to window's parent
7917  * @width: new width
7918  * @height: new height
7919  *
7920  * Equivalent to calling gdk_window_move() and gdk_window_resize(),
7921  * except that both operations are performed at once, avoiding strange
7922  * visual effects. (i.e. the user may be able to see the window first
7923  * move, then resize, if you don't use gdk_window_move_resize().)
7924  **/
7925 void
7926 gdk_window_move_resize (GdkWindow *window,
7927                         gint       x,
7928                         gint       y,
7929                         gint       width,
7930                         gint       height)
7931 {
7932   gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
7933 }
7934
7935
7936 /**
7937  * gdk_window_scroll:
7938  * @window: a #GdkWindow
7939  * @dx: Amount to scroll in the X direction
7940  * @dy: Amount to scroll in the Y direction
7941  *
7942  * Scroll the contents of @window, both pixels and children, by the
7943  * given amount. @window itself does not move. Portions of the window
7944  * that the scroll operation brings in from offscreen areas are
7945  * invalidated. The invalidated region may be bigger than what would
7946  * strictly be necessary.
7947  *
7948  * For X11, a minimum area will be invalidated if the window has no
7949  * subwindows, or if the edges of the window's parent do not extend
7950  * beyond the edges of the window. In other cases, a multi-step process
7951  * is used to scroll the window which may produce temporary visual
7952  * artifacts and unnecessary invalidations.
7953  **/
7954 void
7955 gdk_window_scroll (GdkWindow *window,
7956                    gint       dx,
7957                    gint       dy)
7958 {
7959   GdkWindowObject *private = (GdkWindowObject *) window;
7960   GdkWindowObject *impl_window;
7961   GdkRegion *copy_area, *noncopy_area;
7962   GdkRegion *old_native_child_region, *new_native_child_region;
7963   GList *tmp_list;
7964
7965   g_return_if_fail (GDK_IS_WINDOW (window));
7966
7967   if (dx == 0 && dy == 0)
7968     return;
7969
7970   if (private->destroyed)
7971     return;
7972
7973   gdk_window_flush_if_exposing (window);
7974
7975   old_native_child_region = collect_native_child_region (private, FALSE);
7976   if (old_native_child_region)
7977     {
7978       /* Any native window move will immediately copy stuff to the destination, which may overwrite a
7979        * source or destination for a delayed GdkWindowRegionMove. So, we need
7980        * to flush those here for the window and all overlapped subwindows
7981        * of it. And we need to do this before setting the new clips as those will be
7982        * affecting this.
7983        */
7984       gdk_window_flush_recursive (private);
7985     }
7986
7987
7988   /* First move all child windows, without causing invalidation */
7989
7990   tmp_list = private->children;
7991   while (tmp_list)
7992     {
7993       GdkWindow *child = GDK_WINDOW (tmp_list->data);
7994       GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
7995
7996       /* Just update the positions, the bits will move with the copy */
7997       child_obj->x += dx;
7998       child_obj->y += dy;
7999
8000       tmp_list = tmp_list->next;
8001     }
8002
8003   recompute_visible_regions (private, FALSE, TRUE);
8004
8005   new_native_child_region = NULL;
8006   if (old_native_child_region)
8007     new_native_child_region = collect_native_child_region (private, FALSE);
8008
8009   move_native_children (private);
8010
8011   /* Then copy the actual bits of the window w/ child windows */
8012
8013   impl_window = gdk_window_get_impl_window (private);
8014
8015   /* Calculate the area that can be gotten by copying the old area */
8016   copy_area = gdk_region_copy (private->clip_region);
8017   if (old_native_child_region)
8018     {
8019       /* Don't copy from inside native children, as this is copied by
8020        * the native window move.
8021        */
8022       gdk_region_subtract (copy_area, old_native_child_region);
8023
8024       /* Don't copy any bits that would cause a read from the moved
8025          native windows, as we can't read that data */
8026       gdk_region_subtract (copy_area, new_native_child_region);
8027     }
8028   gdk_region_offset (copy_area, dx, dy);
8029   gdk_region_intersect (copy_area, private->clip_region);
8030
8031   /* And the rest need to be invalidated */
8032   noncopy_area = gdk_region_copy (private->clip_region);
8033   gdk_region_subtract (noncopy_area, copy_area);
8034
8035   /* convert from window coords to impl */
8036   gdk_region_offset (copy_area, private->abs_x, private->abs_y);
8037
8038   move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
8039
8040   /* Invalidate not copied regions */
8041   if (old_native_child_region)
8042     {
8043       /* No need to expose the region that the native window move copies */
8044       gdk_region_offset (old_native_child_region, dx, dy);
8045       gdk_region_intersect (old_native_child_region, new_native_child_region);
8046       gdk_region_subtract (noncopy_area, old_native_child_region);
8047     }
8048   gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
8049
8050   gdk_region_destroy (noncopy_area);
8051
8052   if (old_native_child_region)
8053     {
8054       gdk_region_destroy (old_native_child_region);
8055       gdk_region_destroy (new_native_child_region);
8056     }
8057
8058   _gdk_synthesize_crossing_events_for_geometry_change (window);
8059 }
8060
8061 /**
8062  * gdk_window_move_region:
8063  * @window: a #GdkWindow
8064  * @region: The #GdkRegion to move
8065  * @dx: Amount to move in the X direction
8066  * @dy: Amount to move in the Y direction
8067  *
8068  * Move the part of @window indicated by @region by @dy pixels in the Y
8069  * direction and @dx pixels in the X direction. The portions of @region
8070  * that not covered by the new position of @region are invalidated.
8071  *
8072  * Child windows are not moved.
8073  *
8074  * Since: 2.8
8075  */
8076 void
8077 gdk_window_move_region (GdkWindow       *window,
8078                         const GdkRegion *region,
8079                         gint             dx,
8080                         gint             dy)
8081 {
8082   GdkWindowObject *private = (GdkWindowObject *) window;
8083   GdkWindowObject *impl_window;
8084   GdkRegion *nocopy_area;
8085   GdkRegion *copy_area;
8086
8087   g_return_if_fail (GDK_IS_WINDOW (window));
8088   g_return_if_fail (region != NULL);
8089
8090   if (dx == 0 && dy == 0)
8091     return;
8092
8093   if (private->destroyed)
8094     return;
8095
8096   impl_window = gdk_window_get_impl_window (private);
8097
8098   /* compute source regions */
8099   copy_area = gdk_region_copy (region);
8100   gdk_region_intersect (copy_area, private->clip_region_with_children);
8101
8102   /* compute destination regions */
8103   gdk_region_offset (copy_area, dx, dy);
8104   gdk_region_intersect (copy_area, private->clip_region_with_children);
8105
8106   /* Invalidate parts of the region (source and dest) not covered
8107      by the copy */
8108   nocopy_area = gdk_region_copy (region);
8109   gdk_region_offset (nocopy_area, dx, dy);
8110   gdk_region_union (nocopy_area, region);
8111   gdk_region_subtract (nocopy_area, copy_area);
8112
8113   /* convert from window coords to impl */
8114   gdk_region_offset (copy_area, private->abs_x, private->abs_y);
8115   move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
8116
8117   gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
8118   gdk_region_destroy (nocopy_area);
8119 }
8120
8121 /**
8122  * gdk_window_get_background:
8123  * @window: a #GdkWindow.
8124  * @color: (out): a #GdkColor to be filled in
8125  *
8126  * Sets @color to equal the current background color of @window.
8127  *
8128  * Since: 2.22
8129  */
8130 void
8131 gdk_window_get_background (GdkWindow *window,
8132                            GdkColor  *color)
8133 {
8134   GdkWindowObject *private;
8135
8136   g_return_if_fail (GDK_IS_WINDOW (window));
8137   g_return_if_fail (color != NULL);
8138
8139   private = (GdkWindowObject *) window;
8140
8141   *color = private->bg_color;
8142 }
8143
8144 /**
8145  * gdk_window_set_background:
8146  * @window: a #GdkWindow
8147  * @color: an allocated #GdkColor
8148  *
8149  * Sets the background color of @window. (However, when using GTK+,
8150  * set the background of a widget with gtk_widget_modify_bg() - if
8151  * you're an application - or gtk_style_set_background() - if you're
8152  * implementing a custom widget.)
8153  *
8154  * The @color must be allocated; gdk_rgb_find_color() is the best way
8155  * to allocate a color.
8156  *
8157  * See also gdk_window_set_background_pixmap().
8158  */
8159 void
8160 gdk_window_set_background (GdkWindow      *window,
8161                            const GdkColor *color)
8162 {
8163   GdkWindowObject *private;
8164   GdkColormap *colormap = gdk_drawable_get_colormap (window);
8165   GdkWindowImplIface *impl_iface;
8166
8167   g_return_if_fail (GDK_IS_WINDOW (window));
8168
8169   private = (GdkWindowObject *) window;
8170
8171   private->bg_color = *color;
8172   gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
8173
8174   if (private->bg_pixmap &&
8175       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
8176       private->bg_pixmap != GDK_NO_BG)
8177     g_object_unref (private->bg_pixmap);
8178
8179   private->bg_pixmap = NULL;
8180
8181   if (!GDK_WINDOW_DESTROYED (window) &&
8182       gdk_window_has_impl (private) &&
8183       !private->input_only)
8184     {
8185       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8186       impl_iface->set_background (window, &private->bg_color);
8187     }
8188 }
8189
8190 /**
8191  * gdk_window_get_back_pixmap:
8192  * @window: a #GdkWindow.
8193  * @pixmap: (out) (allow-none): a #GdkPixmap to be filled in, or %NULL.
8194  * @parent_relative: (out) (allow-none): a pointer to a #gboolean to be filled in, or %NULL.
8195  *
8196  * Sets @pixmap to the current background pixmap of @window.  You do not
8197  * own the pointer that is returned and this pointer should not be freeed
8198  * or unreferenced.  Sets @parent_relative to %TRUE if the tiling is done
8199  * based on the origin of the parent window.
8200  *
8201  * Since: 2.22
8202  */
8203 void
8204 gdk_window_get_back_pixmap (GdkWindow  *window,
8205                             GdkPixmap **pixmap,
8206                             gboolean   *parent_relative)
8207 {
8208   GdkWindowObject *private;
8209
8210   g_return_if_fail (GDK_IS_WINDOW (window));
8211
8212   private = (GdkWindowObject *) window;
8213
8214   if (pixmap)
8215     {
8216       if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG ||
8217           private->bg_pixmap == GDK_NO_BG)
8218         *pixmap = NULL;
8219       else
8220         *pixmap = private->bg_pixmap;
8221     }
8222
8223   if (parent_relative)
8224     *parent_relative = (private->bg_pixmap == GDK_PARENT_RELATIVE_BG);
8225 }
8226
8227 /**
8228  * gdk_window_set_back_pixmap:
8229  * @window: a #GdkWindow
8230  * @pixmap: (allow-none): a #GdkPixmap, or %NULL
8231  * @parent_relative: whether the tiling origin is at the origin of
8232  *   @window's parent
8233  *
8234  * Sets the background pixmap of @window. May also be used to set a
8235  * background of "None" on @window, by setting a background pixmap
8236  * of %NULL.
8237  *
8238  * A background pixmap will be tiled, positioning the first tile at
8239  * the origin of @window, or if @parent_relative is %TRUE, the tiling
8240  * will be done based on the origin of the parent window (useful to
8241  * align tiles in a parent with tiles in a child).
8242  *
8243  * A background pixmap of %NULL means that the window will have no
8244  * background.  A window with no background will never have its
8245  * background filled by the windowing system, instead the window will
8246  * contain whatever pixels were already in the corresponding area of
8247  * the display.
8248  *
8249  * The windowing system will normally fill a window with its background
8250  * when the window is obscured then exposed, and when you call
8251  * gdk_window_clear().
8252  */
8253 void
8254 gdk_window_set_back_pixmap (GdkWindow *window,
8255                             GdkPixmap *pixmap,
8256                             gboolean   parent_relative)
8257 {
8258   GdkWindowObject *private;
8259   GdkWindowImplIface *impl_iface;
8260
8261   g_return_if_fail (GDK_IS_WINDOW (window));
8262   g_return_if_fail (pixmap == NULL || !parent_relative);
8263   g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
8264
8265   private = (GdkWindowObject *) window;
8266
8267   if (pixmap && !gdk_drawable_get_colormap (pixmap))
8268     {
8269       g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
8270       return;
8271     }
8272
8273   if (private->bg_pixmap &&
8274       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
8275       private->bg_pixmap != GDK_NO_BG)
8276     g_object_unref (private->bg_pixmap);
8277
8278   if (parent_relative)
8279     private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
8280   else if (pixmap)
8281     private->bg_pixmap = g_object_ref (pixmap);
8282   else
8283     private->bg_pixmap = GDK_NO_BG;
8284
8285   if (!GDK_WINDOW_DESTROYED (window) &&
8286       gdk_window_has_impl (private) &&
8287       !private->input_only)
8288     {
8289       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8290       impl_iface->set_back_pixmap (window, private->bg_pixmap);
8291     }
8292 }
8293
8294 static void
8295 update_cursor_foreach (GdkDisplay           *display,
8296                        GdkDevice            *device,
8297                        GdkPointerWindowInfo *pointer_info,
8298                        gpointer              user_data)
8299 {
8300   GdkWindow *window = user_data;
8301   GdkWindowObject *private = (GdkWindowObject *) window;
8302
8303   if (_gdk_native_windows ||
8304       private->window_type == GDK_WINDOW_ROOT ||
8305       private->window_type == GDK_WINDOW_FOREIGN)
8306     GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_device_cursor (window, device, private->cursor);
8307   else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
8308     update_cursor (display, device);
8309 }
8310
8311 /**
8312  * gdk_window_get_cursor:
8313  * @window: a #GdkWindow
8314  *
8315  * Retrieves a #GdkCursor pointer for the cursor currently set on the
8316  * specified #GdkWindow, or %NULL.  If the return value is %NULL then
8317  * there is no custom cursor set on the specified window, and it is
8318  * using the cursor for its parent window.
8319  *
8320  * Return value: a #GdkCursor, or %NULL. The returned object is owned
8321  *   by the #GdkWindow and should not be unreferenced directly. Use
8322  *   gdk_window_set_cursor() to unset the cursor of the window
8323  *
8324  * Since: 2.18
8325  */
8326 GdkCursor *
8327 gdk_window_get_cursor (GdkWindow *window)
8328 {
8329   GdkWindowObject *private;
8330
8331   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
8332
8333   private = (GdkWindowObject *) window;
8334
8335   return private->cursor;
8336 }
8337
8338 /**
8339  * gdk_window_set_cursor:
8340  * @window: a #GdkWindow
8341  * @cursor: (allow-none): a cursor
8342  *
8343  * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
8344  * or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor
8345  * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
8346  * to gdk_window_set_cursor() means that @window will use the cursor of its
8347  * parent window. Most windows should use this default.
8348  */
8349 void
8350 gdk_window_set_cursor (GdkWindow *window,
8351                        GdkCursor *cursor)
8352 {
8353   GdkWindowObject *private;
8354   GdkDisplay *display;
8355
8356   g_return_if_fail (GDK_IS_WINDOW (window));
8357
8358   private = (GdkWindowObject *) window;
8359   display = gdk_drawable_get_display (window);
8360
8361   if (private->cursor)
8362     {
8363       gdk_cursor_unref (private->cursor);
8364       private->cursor = NULL;
8365     }
8366
8367   if (!GDK_WINDOW_DESTROYED (window))
8368     {
8369       if (cursor)
8370         private->cursor = gdk_cursor_ref (cursor);
8371
8372       _gdk_display_pointer_info_foreach (display,
8373                                          update_cursor_foreach,
8374                                          window);
8375
8376       g_object_notify (G_OBJECT (window), "cursor");
8377     }
8378 }
8379
8380 /**
8381  * gdk_window_get_device_cursor:
8382  * @window: a #GdkWindow.
8383  * @device: a #GdkDevice.
8384  *
8385  * Retrieves a #GdkCursor pointer for the @device currently set on the
8386  * specified #GdkWindow, or %NULL.  If the return value is %NULL then
8387  * there is no custom cursor set on the specified window, and it is
8388  * using the cursor for its parent window.
8389  *
8390  * Returns: a #GdkCursor, or %NULL. The returned object is owned
8391  *   by the #GdkWindow and should not be unreferenced directly. Use
8392  *   gdk_window_set_cursor() to unset the cursor of the window
8393  *
8394  * Since: 3.0
8395  **/
8396 GdkCursor *
8397 gdk_window_get_device_cursor (GdkWindow *window,
8398                               GdkDevice *device)
8399 {
8400   GdkWindowObject *private;
8401
8402   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
8403   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
8404
8405   private = (GdkWindowObject *) window;
8406
8407   return g_hash_table_lookup (private->device_cursor, device);
8408 }
8409
8410 /**
8411  * gdk_window_set_device_cursor:
8412  * @window: a #Gdkwindow
8413  * @device: a #GdkDevice
8414  * @cursor: a #GdkCursor
8415  *
8416  * Sets a specific #GdkCursor for a given device when it gets inside @window.
8417  * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixmap() to create
8418  * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
8419  * %NULL for the @cursor argument to gdk_window_set_cursor() means that
8420  * @window will use the cursor of its parent window. Most windows should
8421  * use this default.
8422  *
8423  * Since: 3.0
8424  **/
8425 void
8426 gdk_window_set_device_cursor (GdkWindow *window,
8427                               GdkDevice *device,
8428                               GdkCursor *cursor)
8429 {
8430   GdkWindowObject *private;
8431   GdkDisplay *display;
8432
8433   g_return_if_fail (GDK_IS_WINDOW (window));
8434   g_return_if_fail (GDK_IS_DEVICE (device));
8435
8436   private = (GdkWindowObject *) window;
8437   display = gdk_drawable_get_display (window);
8438
8439   if (!cursor)
8440     g_hash_table_remove (private->device_cursor, device);
8441   else
8442     g_hash_table_replace (private->device_cursor, device, cursor);
8443
8444   if (!GDK_WINDOW_DESTROYED (window))
8445     {
8446       GdkPointerWindowInfo *pointer_info;
8447
8448       pointer_info = _gdk_display_get_pointer_info (display, device);
8449
8450       if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
8451         update_cursor (display, device);
8452     }
8453 }
8454
8455 /**
8456  * gdk_window_get_geometry:
8457  * @window: a #GdkWindow
8458  * @x: return location for X coordinate of window (relative to its parent)
8459  * @y: return location for Y coordinate of window (relative to its parent)
8460  * @width: return location for width of window
8461  * @height: return location for height of window
8462  * @depth: return location for bit depth of window
8463  *
8464  * Any of the return location arguments to this function may be %NULL,
8465  * if you aren't interested in getting the value of that field.
8466  *
8467  * The X and Y coordinates returned are relative to the parent window
8468  * of @window, which for toplevels usually means relative to the
8469  * window decorations (titlebar, etc.) rather than relative to the
8470  * root window (screen-size background window).
8471  *
8472  * On the X11 platform, the geometry is obtained from the X server,
8473  * so reflects the latest position of @window; this may be out-of-sync
8474  * with the position of @window delivered in the most-recently-processed
8475  * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
8476  * position from the most recent configure event.
8477  *
8478  * <note>
8479  * If @window is not a toplevel, it is <emphasis>much</emphasis> better
8480  * to call gdk_window_get_position() and gdk_drawable_get_size() instead,
8481  * because it avoids the roundtrip to the X server and because
8482  * gdk_drawable_get_size() supports the full 32-bit coordinate space,
8483  * whereas gdk_window_get_geometry() is restricted to the 16-bit
8484  * coordinates of X11.
8485  *</note>
8486  **/
8487 void
8488 gdk_window_get_geometry (GdkWindow *window,
8489                          gint      *x,
8490                          gint      *y,
8491                          gint      *width,
8492                          gint      *height,
8493                          gint      *depth)
8494 {
8495   GdkWindowObject *private, *parent;
8496   GdkWindowImplIface *impl_iface;
8497
8498   if (!window)
8499     {
8500       GDK_NOTE (MULTIHEAD,
8501                 g_message ("gdk_window_get_geometry(): Window needs "
8502                            "to be non-NULL to be multi head safe"));
8503       window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
8504     }
8505
8506   g_return_if_fail (GDK_IS_WINDOW (window));
8507
8508   private = (GdkWindowObject *) window;
8509
8510   if (!GDK_WINDOW_DESTROYED (window))
8511     {
8512       if (gdk_window_has_impl (private))
8513         {
8514           impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8515           impl_iface->get_geometry (window, x, y,
8516                                     width, height,
8517                                     depth);
8518           /* This reports the position wrt to the native parent, we need to convert
8519              it to be relative to the client side parent */
8520           parent = private->parent;
8521           if (parent && !gdk_window_has_impl (parent))
8522             {
8523               if (x)
8524                 *x -= parent->abs_x;
8525               if (y)
8526                 *y -= parent->abs_y;
8527             }
8528         }
8529       else
8530         {
8531           if (x)
8532             *x = private->x;
8533           if (y)
8534             *y = private->y;
8535           if (width)
8536             *width = private->width;
8537           if (height)
8538             *height = private->height;
8539           if (depth)
8540             *depth = private->depth;
8541         }
8542     }
8543 }
8544
8545 /**
8546  * gdk_window_get_origin:
8547  * @window: a #GdkWindow
8548  * @x: return location for X coordinate
8549  * @y: return location for Y coordinate
8550  *
8551  * Obtains the position of a window in root window coordinates.
8552  * (Compare with gdk_window_get_position() and
8553  * gdk_window_get_geometry() which return the position of a window
8554  * relative to its parent window.)
8555  *
8556  * Return value: not meaningful, ignore
8557  */
8558 gint
8559 gdk_window_get_origin (GdkWindow *window,
8560                        gint      *x,
8561                        gint      *y)
8562 {
8563   GdkWindowObject *private;
8564   GdkWindowImplIface *impl_iface;
8565
8566   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8567
8568   if (GDK_WINDOW_DESTROYED (window))
8569     {
8570       if (x)
8571         *x = 0;
8572       if (y)
8573         *y = 0;
8574       return 0;
8575     }
8576   
8577   private = (GdkWindowObject *) window;
8578
8579   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8580   impl_iface->get_root_coords (window,
8581                                private->abs_x,
8582                                private->abs_y,
8583                                x, y);
8584
8585   return TRUE;
8586 }
8587
8588 /**
8589  * gdk_window_get_root_coords:
8590  * @window: a #GdkWindow
8591  * @x: X coordinate in window
8592  * @y: Y coordinate in window
8593  * @root_x: return location for X coordinate
8594  * @root_y: return location for Y coordinate
8595  *
8596  * Obtains the position of a window position in root
8597  * window coordinates. This is similar to
8598  * gdk_window_get_origin() but allows you go pass
8599  * in any position in the window, not just the origin.
8600  *
8601  * Since: 2.18
8602  */
8603 void
8604 gdk_window_get_root_coords (GdkWindow *window,
8605                             gint       x,
8606                             gint       y,
8607                             gint      *root_x,
8608                             gint      *root_y)
8609 {
8610   GdkWindowObject *private;
8611   GdkWindowImplIface *impl_iface;
8612
8613   g_return_if_fail (GDK_IS_WINDOW (window));
8614
8615   private = (GdkWindowObject *) window;
8616
8617   if (GDK_WINDOW_DESTROYED (window))
8618     {
8619       if (x)
8620         *root_x = x;
8621       if (y)
8622         *root_y = y;
8623       return;
8624     }
8625   
8626   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8627   impl_iface->get_root_coords (window,
8628                                x + private->abs_x,
8629                                y + private->abs_y,
8630                                root_x, root_y);
8631 }
8632
8633 /**
8634  * gdk_window_coords_to_parent:
8635  * @window: a child window
8636  * @x: X coordinate in child's coordinate system
8637  * @y: Y coordinate in child's coordinate system
8638  * @parent_x: (out) (allow-none): return location for X coordinate
8639  * in parent's coordinate system, or %NULL
8640  * @parent_y: (out) (allow-none): return location for Y coordinate
8641  * in parent's coordinate system, or %NULL
8642  *
8643  * Transforms window coordinates from a child window to its parent
8644  * window, where the parent window is the normal parent as returned by
8645  * gdk_window_get_parent() for normal windows, and the window's
8646  * embedder as returned by gdk_offscreen_window_get_embedder() for
8647  * offscreen windows.
8648  *
8649  * For normal windows, calling this function is equivalent to adding
8650  * the return values of gdk_window_get_position() to the child coordinates.
8651  * For offscreen windows however (which can be arbitrarily transformed),
8652  * this function calls the GdkWindow::to-embedder: signal to translate
8653  * the coordinates.
8654  *
8655  * You should always use this function when writing generic code that
8656  * walks up a window hierarchy.
8657  *
8658  * See also: gdk_window_coords_from_parent()
8659  *
8660  * Since: 2.22
8661  **/
8662 void
8663 gdk_window_coords_to_parent (GdkWindow *window,
8664                              gdouble    x,
8665                              gdouble    y,
8666                              gdouble   *parent_x,
8667                              gdouble   *parent_y)
8668 {
8669   GdkWindowObject *obj;
8670
8671   g_return_if_fail (GDK_IS_WINDOW (window));
8672
8673   obj = (GdkWindowObject *) window;
8674
8675   if (gdk_window_is_offscreen (obj))
8676     {
8677       gdouble px, py;
8678
8679       to_embedder (obj, x, y, &px, &py);
8680
8681       if (parent_x)
8682         *parent_x = px;
8683
8684       if (parent_y)
8685         *parent_y = py;
8686     }
8687   else
8688     {
8689       if (parent_x)
8690         *parent_x = x + obj->x;
8691
8692       if (parent_y)
8693         *parent_y = y + obj->y;
8694     }
8695 }
8696
8697 /**
8698  * gdk_window_coords_from_parent:
8699  * @window: a child window
8700  * @parent_x: X coordinate in parent's coordinate system
8701  * @parent_y: Y coordinate in parent's coordinate system
8702  * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
8703  * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
8704  *
8705  * Transforms window coordinates from a parent window to a child
8706  * window, where the parent window is the normal parent as returned by
8707  * gdk_window_get_parent() for normal windows, and the window's
8708  * embedder as returned by gdk_offscreen_window_get_embedder() for
8709  * offscreen windows.
8710  *
8711  * For normal windows, calling this function is equivalent to subtracting
8712  * the return values of gdk_window_get_position() from the parent coordinates.
8713  * For offscreen windows however (which can be arbitrarily transformed),
8714  * this function calls the GdkWindow::from-embedder: signal to translate
8715  * the coordinates.
8716  *
8717  * You should always use this function when writing generic code that
8718  * walks down a window hierarchy.
8719  *
8720  * See also: gdk_window_coords_to_parent()
8721  *
8722  * Since: 2.22
8723  **/
8724 void
8725 gdk_window_coords_from_parent (GdkWindow *window,
8726                                gdouble    parent_x,
8727                                gdouble    parent_y,
8728                                gdouble   *x,
8729                                gdouble   *y)
8730 {
8731   GdkWindowObject *obj;
8732
8733   g_return_if_fail (GDK_IS_WINDOW (window));
8734
8735   obj = (GdkWindowObject *) window;
8736
8737   if (gdk_window_is_offscreen (obj))
8738     {
8739       gdouble cx, cy;
8740
8741       from_embedder (obj, parent_x, parent_y, &cx, &cy);
8742
8743       if (x)
8744         *x = cx;
8745
8746       if (y)
8747         *y = cy;
8748     }
8749   else
8750     {
8751       if (x)
8752         *x = parent_x - obj->x;
8753
8754       if (y)
8755         *y = parent_y - obj->y;
8756     }
8757 }
8758
8759 /**
8760  * gdk_window_get_deskrelative_origin:
8761  * @window: a toplevel #GdkWindow
8762  * @x: return location for X coordinate
8763  * @y: return location for Y coordinate
8764  *
8765  * This gets the origin of a #GdkWindow relative to
8766  * an Enlightenment-window-manager desktop. As long as you don't
8767  * assume that the user's desktop/workspace covers the entire
8768  * root window (i.e. you don't assume that the desktop begins
8769  * at root window coordinate 0,0) this function is not necessary.
8770  * It's deprecated for that reason.
8771  *
8772  * Return value: not meaningful
8773  **/
8774 gboolean
8775 gdk_window_get_deskrelative_origin (GdkWindow *window,
8776                                     gint      *x,
8777                                     gint      *y)
8778 {
8779   GdkWindowObject *private;
8780   GdkWindowImplIface *impl_iface;
8781   gboolean return_val = FALSE;
8782   gint tx = 0;
8783   gint ty = 0;
8784
8785   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8786
8787   private = (GdkWindowObject *) window;
8788
8789   if (!GDK_WINDOW_DESTROYED (window))
8790     {
8791       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8792       return_val = impl_iface->get_deskrelative_origin (window, &tx, &ty);
8793
8794       if (x)
8795         *x = tx + private->abs_x;
8796       if (y)
8797         *y = ty + private->abs_y;
8798     }
8799
8800   return return_val;
8801 }
8802
8803 /**
8804  * gdk_window_shape_combine_mask:
8805  * @window: a #GdkWindow
8806  * @mask: shape mask
8807  * @x: X position of shape mask with respect to @window
8808  * @y: Y position of shape mask with respect to @window
8809  *
8810  * Applies a shape mask to @window. Pixels in @window corresponding to
8811  * set bits in the @mask will be visible; pixels in @window
8812  * corresponding to unset bits in the @mask will be transparent. This
8813  * gives a non-rectangular window.
8814  *
8815  * If @mask is %NULL, the shape mask will be unset, and the @x/@y
8816  * parameters are not used.
8817  *
8818  * On the X11 platform, this uses an X server extension which is
8819  * widely available on most common platforms, but not available on
8820  * very old X servers, and occasionally the implementation will be
8821  * buggy. On servers without the shape extension, this function
8822  * will do nothing.
8823  *
8824  * This function works on both toplevel and child windows.
8825  */
8826 void
8827 gdk_window_shape_combine_mask (GdkWindow *window,
8828                                GdkBitmap *mask,
8829                                gint       x,
8830                                gint       y)
8831 {
8832   GdkWindowObject *private;
8833   GdkRegion *region;
8834
8835   g_return_if_fail (GDK_IS_WINDOW (window));
8836
8837   private = (GdkWindowObject *) window;
8838
8839   if (mask)
8840     region = _gdk_windowing_get_shape_for_mask (mask);
8841   else
8842     region = NULL;
8843
8844   gdk_window_shape_combine_region (window,
8845                                    region,
8846                                    x, y);
8847
8848   if (region)
8849     gdk_region_destroy (region);
8850 }
8851
8852 /**
8853  * gdk_window_shape_combine_region:
8854  * @window: a #GdkWindow
8855  * @shape_region: region of window to be non-transparent
8856  * @offset_x: X position of @shape_region in @window coordinates
8857  * @offset_y: Y position of @shape_region in @window coordinates
8858  *
8859  * Makes pixels in @window outside @shape_region be transparent,
8860  * so that the window may be nonrectangular. See also
8861  * gdk_window_shape_combine_mask() to use a bitmap as the mask.
8862  *
8863  * If @shape_region is %NULL, the shape will be unset, so the whole
8864  * window will be opaque again. @offset_x and @offset_y are ignored
8865  * if @shape_region is %NULL.
8866  *
8867  * On the X11 platform, this uses an X server extension which is
8868  * widely available on most common platforms, but not available on
8869  * very old X servers, and occasionally the implementation will be
8870  * buggy. On servers without the shape extension, this function
8871  * will do nothing.
8872  *
8873  * This function works on both toplevel and child windows.
8874  */
8875 void
8876 gdk_window_shape_combine_region (GdkWindow       *window,
8877                                  const GdkRegion *shape_region,
8878                                  gint             offset_x,
8879                                  gint             offset_y)
8880 {
8881   GdkWindowObject *private;
8882   GdkRegion *old_region, *new_region, *diff;
8883
8884   g_return_if_fail (GDK_IS_WINDOW (window));
8885
8886   private = (GdkWindowObject *) window;
8887
8888   if (GDK_WINDOW_DESTROYED (window))
8889     return;
8890
8891   private->shaped = (shape_region != NULL);
8892
8893   if (private->shape)
8894     gdk_region_destroy (private->shape);
8895
8896   old_region = NULL;
8897   if (GDK_WINDOW_IS_MAPPED (window))
8898     old_region = gdk_region_copy (private->clip_region);
8899
8900   if (shape_region)
8901     {
8902       private->shape = gdk_region_copy (shape_region);
8903       gdk_region_offset (private->shape, offset_x, offset_y);
8904     }
8905   else
8906     private->shape = NULL;
8907
8908   recompute_visible_regions (private, TRUE, FALSE);
8909
8910   if (gdk_window_has_impl (private) &&
8911       !should_apply_clip_as_shape (private))
8912     apply_shape (private, private->shape);
8913
8914   if (old_region)
8915     {
8916       new_region = gdk_region_copy (private->clip_region);
8917
8918       /* New area in the window, needs invalidation */
8919       diff = gdk_region_copy (new_region);
8920       gdk_region_subtract (diff, old_region);
8921
8922       gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
8923
8924       gdk_region_destroy (diff);
8925
8926       if (!gdk_window_is_toplevel (private))
8927         {
8928           /* New area in the non-root parent window, needs invalidation */
8929           diff = gdk_region_copy (old_region);
8930           gdk_region_subtract (diff, new_region);
8931
8932           /* Adjust region to parent window coords */
8933           gdk_region_offset (diff, private->x, private->y);
8934
8935           gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
8936
8937           gdk_region_destroy (diff);
8938         }
8939
8940       gdk_region_destroy (new_region);
8941       gdk_region_destroy (old_region);
8942     }
8943 }
8944
8945 static void
8946 do_child_shapes (GdkWindow *window,
8947                  gboolean merge)
8948 {
8949   GdkWindowObject *private;
8950   GdkRectangle r;
8951   GdkRegion *region;
8952
8953   private = (GdkWindowObject *) window;
8954
8955   r.x = 0;
8956   r.y = 0;
8957   r.width = private->width;
8958   r.height = private->height;
8959
8960   region = gdk_region_rectangle (&r);
8961   remove_child_area (private, NULL, FALSE, region);
8962
8963   if (merge && private->shape)
8964     gdk_region_subtract (region, private->shape);
8965
8966   gdk_window_shape_combine_region (window, region, 0, 0);
8967 }
8968
8969 /**
8970  * gdk_window_set_child_shapes:
8971  * @window: a #GdkWindow
8972  *
8973  * Sets the shape mask of @window to the union of shape masks
8974  * for all children of @window, ignoring the shape mask of @window
8975  * itself. Contrast with gdk_window_merge_child_shapes() which includes
8976  * the shape mask of @window in the masks to be merged.
8977  **/
8978 void
8979 gdk_window_set_child_shapes (GdkWindow *window)
8980 {
8981   g_return_if_fail (GDK_IS_WINDOW (window));
8982
8983   do_child_shapes (window, FALSE);
8984 }
8985
8986 /**
8987  * gdk_window_merge_child_shapes:
8988  * @window: a #GdkWindow
8989  *
8990  * Merges the shape masks for any child windows into the
8991  * shape mask for @window. i.e. the union of all masks
8992  * for @window and its children will become the new mask
8993  * for @window. See gdk_window_shape_combine_mask().
8994  *
8995  * This function is distinct from gdk_window_set_child_shapes()
8996  * because it includes @window's shape mask in the set of shapes to
8997  * be merged.
8998  */
8999 void
9000 gdk_window_merge_child_shapes (GdkWindow *window)
9001 {
9002   g_return_if_fail (GDK_IS_WINDOW (window));
9003
9004   do_child_shapes (window, TRUE);
9005 }
9006
9007 /**
9008  * gdk_window_input_shape_combine_mask:
9009  * @window: a #GdkWindow
9010  * @mask: (allow-none): shape mask, or %NULL
9011  * @x: X position of shape mask with respect to @window
9012  * @y: Y position of shape mask with respect to @window
9013  *
9014  * Like gdk_window_shape_combine_mask(), but the shape applies
9015  * only to event handling. Mouse events which happen while
9016  * the pointer position corresponds to an unset bit in the
9017  * mask will be passed on the window below @window.
9018  *
9019  * An input shape is typically used with RGBA windows.
9020  * The alpha channel of the window defines which pixels are
9021  * invisible and allows for nicely antialiased borders,
9022  * and the input shape controls where the window is
9023  * "clickable".
9024  *
9025  * On the X11 platform, this requires version 1.1 of the
9026  * shape extension.
9027  *
9028  * On the Win32 platform, this functionality is not present and the
9029  * function does nothing.
9030  *
9031  * Since: 2.10
9032  */
9033 void
9034 gdk_window_input_shape_combine_mask (GdkWindow *window,
9035                                      GdkBitmap *mask,
9036                                      gint       x,
9037                                      gint       y)
9038 {
9039   GdkWindowObject *private;
9040   GdkRegion *region;
9041
9042   g_return_if_fail (GDK_IS_WINDOW (window));
9043
9044   private = (GdkWindowObject *) window;
9045
9046   if (mask)
9047     region = _gdk_windowing_get_shape_for_mask (mask);
9048   else
9049     region = NULL;
9050
9051   gdk_window_input_shape_combine_region (window,
9052                                          region,
9053                                          x, y);
9054
9055   if (region != NULL)
9056     gdk_region_destroy (region);
9057 }
9058
9059 /**
9060  * gdk_window_input_shape_combine_region:
9061  * @window: a #GdkWindow
9062  * @shape_region: region of window to be non-transparent
9063  * @offset_x: X position of @shape_region in @window coordinates
9064  * @offset_y: Y position of @shape_region in @window coordinates
9065  *
9066  * Like gdk_window_shape_combine_region(), but the shape applies
9067  * only to event handling. Mouse events which happen while
9068  * the pointer position corresponds to an unset bit in the
9069  * mask will be passed on the window below @window.
9070  *
9071  * An input shape is typically used with RGBA windows.
9072  * The alpha channel of the window defines which pixels are
9073  * invisible and allows for nicely antialiased borders,
9074  * and the input shape controls where the window is
9075  * "clickable".
9076  *
9077  * On the X11 platform, this requires version 1.1 of the
9078  * shape extension.
9079  *
9080  * On the Win32 platform, this functionality is not present and the
9081  * function does nothing.
9082  *
9083  * Since: 2.10
9084  */
9085 void
9086 gdk_window_input_shape_combine_region (GdkWindow       *window,
9087                                        const GdkRegion *shape_region,
9088                                        gint             offset_x,
9089                                        gint             offset_y)
9090 {
9091   GdkWindowObject *private;
9092   GdkWindowImplIface *impl_iface;
9093
9094   g_return_if_fail (GDK_IS_WINDOW (window));
9095
9096   private = (GdkWindowObject *) window;
9097
9098   if (GDK_WINDOW_DESTROYED (window))
9099     return;
9100
9101   if (private->input_shape)
9102     gdk_region_destroy (private->input_shape);
9103
9104   if (shape_region)
9105     {
9106       private->input_shape = gdk_region_copy (shape_region);
9107       gdk_region_offset (private->input_shape, offset_x, offset_y);
9108     }
9109   else
9110     private->input_shape = NULL;
9111
9112   if (gdk_window_has_impl (private))
9113     {
9114       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
9115       impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
9116     }
9117
9118   /* Pointer may have e.g. moved outside window due to the input mask change */
9119   _gdk_synthesize_crossing_events_for_geometry_change (window);
9120 }
9121
9122 static void
9123 do_child_input_shapes (GdkWindow *window,
9124                        gboolean merge)
9125 {
9126   GdkWindowObject *private;
9127   GdkRectangle r;
9128   GdkRegion *region;
9129
9130   private = (GdkWindowObject *) window;
9131
9132   r.x = 0;
9133   r.y = 0;
9134   r.width = private->width;
9135   r.height = private->height;
9136
9137   region = gdk_region_rectangle (&r);
9138   remove_child_area (private, NULL, TRUE, region);
9139
9140   if (merge && private->shape)
9141     gdk_region_subtract (region, private->shape);
9142   if (merge && private->input_shape)
9143     gdk_region_subtract (region, private->input_shape);
9144
9145   gdk_window_input_shape_combine_region (window, region, 0, 0);
9146 }
9147
9148
9149 /**
9150  * gdk_window_set_child_input_shapes:
9151  * @window: a #GdkWindow
9152  *
9153  * Sets the input shape mask of @window to the union of input shape masks
9154  * for all children of @window, ignoring the input shape mask of @window
9155  * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
9156  * the input shape mask of @window in the masks to be merged.
9157  *
9158  * Since: 2.10
9159  **/
9160 void
9161 gdk_window_set_child_input_shapes (GdkWindow *window)
9162 {
9163   g_return_if_fail (GDK_IS_WINDOW (window));
9164
9165   do_child_input_shapes (window, FALSE);
9166 }
9167
9168 /**
9169  * gdk_window_merge_child_input_shapes:
9170  * @window: a #GdkWindow
9171  *
9172  * Merges the input shape masks for any child windows into the
9173  * input shape mask for @window. i.e. the union of all input masks
9174  * for @window and its children will become the new input mask
9175  * for @window. See gdk_window_input_shape_combine_mask().
9176  *
9177  * This function is distinct from gdk_window_set_child_input_shapes()
9178  * because it includes @window's input shape mask in the set of
9179  * shapes to be merged.
9180  *
9181  * Since: 2.10
9182  **/
9183 void
9184 gdk_window_merge_child_input_shapes (GdkWindow *window)
9185 {
9186   g_return_if_fail (GDK_IS_WINDOW (window));
9187
9188   do_child_input_shapes (window, TRUE);
9189 }
9190
9191
9192 /**
9193  * gdk_window_set_static_gravities:
9194  * @window: a #GdkWindow
9195  * @use_static: %TRUE to turn on static gravity
9196  *
9197  * Set the bit gravity of the given window to static, and flag it so
9198  * all children get static subwindow gravity. This is used if you are
9199  * implementing scary features that involve deep knowledge of the
9200  * windowing system. Don't worry about it unless you have to.
9201  *
9202  * Return value: %TRUE if the server supports static gravity
9203  */
9204 gboolean
9205 gdk_window_set_static_gravities (GdkWindow *window,
9206                                  gboolean   use_static)
9207 {
9208   GdkWindowObject *private;
9209   GdkWindowImplIface *impl_iface;
9210
9211   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9212
9213   private = (GdkWindowObject *) window;
9214
9215   if (gdk_window_has_impl (private))
9216     {
9217       impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
9218       return impl_iface->set_static_gravities (window, use_static);
9219     }
9220
9221   return FALSE;
9222 }
9223
9224 /**
9225  * gdk_window_get_composited:
9226  * @window: a #GdkWindow
9227  *
9228  * Determines whether @window is composited.
9229  *
9230  * See gdk_window_set_composited().
9231  *
9232  * Returns: %TRUE if the window is composited.
9233  *
9234  * Since: 2.22
9235  **/
9236 gboolean
9237 gdk_window_get_composited (GdkWindow *window)
9238 {
9239   GdkWindowObject *private;
9240
9241   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9242
9243   private = (GdkWindowObject *)window;
9244
9245   return private->composited;
9246 }
9247
9248 /**
9249  * gdk_window_set_composited:
9250  * @window: a #GdkWindow
9251  * @composited: %TRUE to set the window as composited
9252  *
9253  * Sets a #GdkWindow as composited, or unsets it. Composited
9254  * windows do not automatically have their contents drawn to
9255  * the screen. Drawing is redirected to an offscreen buffer
9256  * and an expose event is emitted on the parent of the composited
9257  * window. It is the responsibility of the parent's expose handler
9258  * to manually merge the off-screen content onto the screen in
9259  * whatever way it sees fit. See <xref linkend="composited-window-example"/>
9260  * for an example.
9261  *
9262  * It only makes sense for child windows to be composited; see
9263  * gdk_window_set_opacity() if you need translucent toplevel
9264  * windows.
9265  *
9266  * An additional effect of this call is that the area of this
9267  * window is no longer clipped from regions marked for
9268  * invalidation on its parent. Draws done on the parent
9269  * window are also no longer clipped by the child.
9270  *
9271  * This call is only supported on some systems (currently,
9272  * only X11 with new enough Xcomposite and Xdamage extensions).
9273  * You must call gdk_display_supports_composite() to check if
9274  * setting a window as composited is supported before
9275  * attempting to do so.
9276  *
9277  * Since: 2.12
9278  */
9279 void
9280 gdk_window_set_composited (GdkWindow *window,
9281                            gboolean   composited)
9282 {
9283   GdkWindowObject *private = (GdkWindowObject *)window;
9284   GdkDisplay *display;
9285
9286   g_return_if_fail (GDK_IS_WINDOW (window));
9287
9288   composited = composited != FALSE;
9289
9290   if (private->composited == composited)
9291     return;
9292
9293   if (composited)
9294     gdk_window_ensure_native (window);
9295
9296   display = gdk_drawable_get_display (GDK_DRAWABLE (window));
9297
9298   if (!gdk_display_supports_composite (display) && composited)
9299     {
9300       g_warning ("gdk_window_set_composited called but "
9301                  "compositing is not supported");
9302       return;
9303     }
9304
9305   _gdk_windowing_window_set_composited (window, composited);
9306
9307   recompute_visible_regions (private, TRUE, FALSE);
9308
9309   if (GDK_WINDOW_IS_MAPPED (window))
9310     gdk_window_invalidate_in_parent (private);
9311
9312   private->composited = composited;
9313 }
9314
9315
9316 static void
9317 remove_redirect_from_children (GdkWindowObject   *private,
9318                                GdkWindowRedirect *redirect)
9319 {
9320   GList *l;
9321   GdkWindowObject *child;
9322
9323   for (l = private->children; l != NULL; l = l->next)
9324     {
9325       child = l->data;
9326
9327       /* Don't redirect this child if it already has another redirect */
9328       if (child->redirect == redirect)
9329         {
9330           child->redirect = NULL;
9331           remove_redirect_from_children (child, redirect);
9332         }
9333     }
9334 }
9335
9336 /**
9337  * gdk_window_remove_redirection:
9338  * @window: a #GdkWindow
9339  *
9340  * Removes any active redirection started by
9341  * gdk_window_redirect_to_drawable().
9342  *
9343  * Since: 2.14
9344  **/
9345 void
9346 gdk_window_remove_redirection (GdkWindow *window)
9347 {
9348   GdkWindowObject *private;
9349
9350   g_return_if_fail (GDK_IS_WINDOW (window));
9351
9352   private = (GdkWindowObject *) window;
9353
9354   if (private->redirect &&
9355       private->redirect->redirected == private)
9356     {
9357       remove_redirect_from_children (private, private->redirect);
9358       gdk_window_redirect_free (private->redirect);
9359       private->redirect = NULL;
9360     }
9361 }
9362
9363 /**
9364  * gdk_window_get_modal_hint:
9365  * @window: A toplevel #GdkWindow.
9366  *
9367  * Determines whether or not the window manager is hinted that @window
9368  * has modal behaviour.
9369  *
9370  * Return value: whether or not the window has the modal hint set.
9371  *
9372  * Since: 2.22
9373  */
9374 gboolean
9375 gdk_window_get_modal_hint (GdkWindow *window)
9376 {
9377   GdkWindowObject *private;
9378
9379   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9380
9381   private = (GdkWindowObject*) window;
9382
9383   return private->modal_hint;
9384 }
9385
9386 /**
9387  * gdk_window_get_accept_focus:
9388  * @window: a toplevel #GdkWindow.
9389  *
9390  * Determines whether or not the desktop environment shuld be hinted that
9391  * the window does not want to receive input focus.
9392  *
9393  * Return value: whether or not the window should receive input focus.
9394  *
9395  * Since: 2.22
9396  */
9397 gboolean
9398 gdk_window_get_accept_focus (GdkWindow *window)
9399 {
9400   GdkWindowObject *private;
9401
9402   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9403
9404   private = (GdkWindowObject *)window;
9405
9406   return private->accept_focus;
9407 }
9408
9409 /**
9410  * gdk_window_get_focus_on_map:
9411  * @window: a toplevel #GdkWindow.
9412  *
9413  * Determines whether or not the desktop environment should be hinted that the
9414  * window does not want to receive input focus when it is mapped.
9415  *
9416  * Return value: whether or not the window wants to receive input focus when
9417  * it is mapped.
9418  *
9419  * Since: 2.22
9420  */
9421 gboolean
9422 gdk_window_get_focus_on_map (GdkWindow *window)
9423 {
9424   GdkWindowObject *private;
9425
9426   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9427
9428   private = (GdkWindowObject *)window;
9429
9430   return private->focus_on_map;
9431 }
9432
9433 /**
9434  * gdk_window_is_input_only:
9435  * @window: a toplevel #GdkWindow
9436  *
9437  * Determines whether or not the window is an input only window.
9438  *
9439  * Return value: %TRUE if @window is input only
9440  *
9441  * Since: 2.22
9442  */
9443 gboolean
9444 gdk_window_is_input_only (GdkWindow *window)
9445 {
9446   GdkWindowObject *private;
9447
9448   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9449
9450   private = (GdkWindowObject *)window;
9451
9452   return private->input_only;
9453 }
9454
9455 /**
9456  * gdk_window_is_shaped:
9457  * @window: a toplevel #GdkWindow
9458  *
9459  * Determines whether or not the window is shaped.
9460  *
9461  * Return value: %TRUE if @window is shaped
9462  *
9463  * Since: 2.22
9464  */
9465 gboolean
9466 gdk_window_is_shaped (GdkWindow *window)
9467 {
9468   GdkWindowObject *private;
9469
9470   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9471
9472   private = (GdkWindowObject *)window;
9473
9474   return private->shaped;
9475 }
9476
9477 static void
9478 apply_redirect_to_children (GdkWindowObject   *private,
9479                             GdkWindowRedirect *redirect)
9480 {
9481   GList *l;
9482   GdkWindowObject *child;
9483
9484   for (l = private->children; l != NULL; l = l->next)
9485     {
9486       child = l->data;
9487
9488       /* Don't redirect this child if it already has another redirect */
9489       if (!child->redirect)
9490         {
9491           child->redirect = redirect;
9492           apply_redirect_to_children (child, redirect);
9493         }
9494     }
9495 }
9496
9497 /**
9498  * gdk_window_redirect_to_drawable:
9499  * @window: a #GdkWindow
9500  * @drawable: a #GdkDrawable
9501  * @src_x: x position in @window
9502  * @src_y: y position in @window
9503  * @dest_x: x position in @drawable
9504  * @dest_y: y position in @drawable
9505  * @width: width of redirection, or -1 to use the width of @window
9506  * @height: height of redirection or -1 to use the height of @window
9507  *
9508  * Redirects drawing into @window so that drawing to the
9509  * window in the rectangle specified by @src_x, @src_y,
9510  * @width and @height is also drawn into @drawable at
9511  * @dest_x, @dest_y.
9512  *
9513  * Only drawing between gdk_window_begin_paint_region() or
9514  * gdk_window_begin_paint_rect() and gdk_window_end_paint() is
9515  * redirected.
9516  *
9517  * Redirection is active until gdk_window_remove_redirection()
9518  * is called.
9519  *
9520  * Since: 2.14
9521  **/
9522 void
9523 gdk_window_redirect_to_drawable (GdkWindow   *window,
9524                                  GdkDrawable *drawable,
9525                                  gint         src_x,
9526                                  gint         src_y,
9527                                  gint         dest_x,
9528                                  gint         dest_y,
9529                                  gint         width,
9530                                  gint         height)
9531 {
9532   GdkWindowObject *private;
9533
9534   g_return_if_fail (GDK_IS_WINDOW (window));
9535   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
9536   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
9537
9538   private = (GdkWindowObject *) window;
9539
9540   if (private->redirect)
9541     gdk_window_remove_redirection (window);
9542
9543   if (width == -1 || height == -1)
9544     {
9545       gint w, h;
9546       gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
9547       if (width == -1)
9548         width = w;
9549       if (height == -1)
9550         height = h;
9551     }
9552
9553   private->redirect = g_new0 (GdkWindowRedirect, 1);
9554   private->redirect->redirected = private;
9555   private->redirect->pixmap = g_object_ref (drawable);
9556   private->redirect->src_x = src_x;
9557   private->redirect->src_y = src_y;
9558   private->redirect->dest_x = dest_x;
9559   private->redirect->dest_y = dest_y;
9560   private->redirect->width = width;
9561   private->redirect->height = height;
9562
9563   apply_redirect_to_children (private, private->redirect);
9564 }
9565
9566 static void
9567 window_get_size_rectangle (GdkWindow    *window,
9568                            GdkRectangle *rect)
9569 {
9570   GdkWindowObject *private = (GdkWindowObject *) window;
9571
9572   rect->x = rect->y = 0;
9573   rect->width = private->width;
9574   rect->height = private->height;
9575 }
9576
9577 /* Calculates the real clipping region for a window, in window coordinates,
9578  * taking into account other windows, gc clip region and gc clip mask.
9579  */
9580 GdkRegion *
9581 _gdk_window_calculate_full_clip_region (GdkWindow *window,
9582                                         GdkWindow *base_window,
9583                                         gboolean   do_children,
9584                                         gint      *base_x_offset,
9585                                         gint      *base_y_offset)
9586 {
9587   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
9588   GdkRectangle visible_rect;
9589   GdkRegion *real_clip_region, *tmpreg;
9590   gint x_offset, y_offset;
9591   GdkWindowObject *parentwin, *lastwin;
9592
9593   if (base_x_offset)
9594     *base_x_offset = 0;
9595   if (base_y_offset)
9596     *base_y_offset = 0;
9597
9598   if (!private->viewable || private->input_only)
9599     return gdk_region_new ();
9600
9601   window_get_size_rectangle (window, &visible_rect);
9602
9603   /* real_clip_region is in window coordinates */
9604   real_clip_region = gdk_region_rectangle (&visible_rect);
9605
9606   x_offset = y_offset = 0;
9607
9608   lastwin = private;
9609   if (do_children)
9610     parentwin = lastwin;
9611   else
9612     parentwin = lastwin->parent;
9613
9614   /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
9615   for (; parentwin != NULL &&
9616          (parentwin == private || lastwin != (GdkWindowObject*) base_window);
9617        lastwin = parentwin, parentwin = lastwin->parent)
9618     {
9619       GList *cur;
9620       GdkRectangle real_clip_rect;
9621
9622       if (parentwin != private)
9623         {
9624           x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
9625           y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
9626         }
9627
9628       /* children is ordered in reverse stack order */
9629       for (cur = parentwin->children;
9630            cur && cur->data != lastwin;
9631            cur = cur->next)
9632         {
9633           GdkWindow *child = cur->data;
9634           GdkWindowObject *child_private = (GdkWindowObject *)child;
9635
9636           if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
9637             continue;
9638
9639           /* Ignore offscreen children, as they don't draw in their parent and
9640            * don't take part in the clipping */
9641           if (gdk_window_is_offscreen (child_private))
9642             continue;
9643
9644           window_get_size_rectangle (child, &visible_rect);
9645
9646           /* Convert rect to "window" coords */
9647           visible_rect.x += child_private->x - x_offset;
9648           visible_rect.y += child_private->y - y_offset;
9649
9650           /* This shortcut is really necessary for performance when there are a lot of windows */
9651           gdk_region_get_clipbox (real_clip_region, &real_clip_rect);
9652           if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
9653               visible_rect.x + visible_rect.width <= real_clip_rect.x ||
9654               visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
9655               visible_rect.y + visible_rect.height <= real_clip_rect.y)
9656             continue;
9657
9658           tmpreg = gdk_region_rectangle (&visible_rect);
9659           gdk_region_subtract (real_clip_region, tmpreg);
9660           gdk_region_destroy (tmpreg);
9661         }
9662
9663       /* Clip to the parent */
9664       window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
9665       /* Convert rect to "window" coords */
9666       visible_rect.x += - x_offset;
9667       visible_rect.y += - y_offset;
9668
9669       tmpreg = gdk_region_rectangle (&visible_rect);
9670       gdk_region_intersect (real_clip_region, tmpreg);
9671       gdk_region_destroy (tmpreg);
9672     }
9673
9674   if (base_x_offset)
9675     *base_x_offset = x_offset;
9676   if (base_y_offset)
9677     *base_y_offset = y_offset;
9678
9679   return real_clip_region;
9680 }
9681
9682 void
9683 _gdk_window_add_damage (GdkWindow *toplevel,
9684                         GdkRegion *damaged_region)
9685 {
9686   GdkDisplay *display;
9687   GdkEvent event = { 0, };
9688   event.expose.type = GDK_DAMAGE;
9689   event.expose.window = toplevel;
9690   event.expose.send_event = FALSE;
9691   event.expose.region = damaged_region;
9692   gdk_region_get_clipbox (event.expose.region, &event.expose.area);
9693   display = gdk_drawable_get_display (event.expose.window);
9694   _gdk_event_queue_append (display, gdk_event_copy (&event));
9695 }
9696
9697 static void
9698 gdk_window_redirect_free (GdkWindowRedirect *redirect)
9699 {
9700   g_object_unref (redirect->pixmap);
9701   g_free (redirect);
9702 }
9703
9704 /* Gets the toplevel for a window as used for events,
9705    i.e. including offscreen parents */
9706 static GdkWindowObject *
9707 get_event_parent (GdkWindowObject *window)
9708 {
9709   if (gdk_window_is_offscreen (window))
9710     return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
9711   else
9712     return window->parent;
9713 }
9714
9715 /* Gets the toplevel for a window as used for events,
9716    i.e. including offscreen parents going up to the native
9717    toplevel */
9718 static GdkWindow *
9719 get_event_toplevel (GdkWindow *w)
9720 {
9721   GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
9722   GdkWindowObject *parent;
9723
9724   while ((parent = get_event_parent (private)) != NULL &&
9725          (parent->window_type != GDK_WINDOW_ROOT))
9726     private = parent;
9727
9728   return GDK_WINDOW (private);
9729 }
9730
9731 gboolean
9732 _gdk_window_event_parent_of (GdkWindow *parent,
9733                              GdkWindow *child)
9734 {
9735   GdkWindow *w;
9736
9737   w = child;
9738   while (w != NULL)
9739     {
9740       if (w == parent)
9741         return TRUE;
9742
9743       w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
9744     }
9745
9746   return FALSE;
9747 }
9748
9749 static void
9750 update_cursor (GdkDisplay *display,
9751                GdkDevice  *device)
9752 {
9753   GdkWindowObject *cursor_window, *parent, *toplevel;
9754   GdkWindow *pointer_window;
9755   GdkWindowImplIface *impl_iface;
9756   GdkPointerWindowInfo *pointer_info;
9757   GdkDeviceGrabInfo *grab;
9758
9759   pointer_info = _gdk_display_get_pointer_info (display, device);
9760   pointer_window = pointer_info->window_under_pointer;
9761
9762   /* We ignore the serials here and just pick the last grab
9763      we've sent, as that would shortly be used anyway. */
9764   grab = _gdk_display_get_last_device_grab (display, device);
9765   if (/* have grab */
9766       grab != NULL &&
9767       /* the pointer is not in a descendant of the grab window */
9768       !_gdk_window_event_parent_of (grab->window, pointer_window))
9769     {
9770       /* use the cursor from the grab window */
9771       cursor_window = (GdkWindowObject *) grab->window;
9772     }
9773   else
9774     {
9775       /* otherwise use the cursor from the pointer window */
9776       cursor_window = (GdkWindowObject *) pointer_window;
9777     }
9778
9779   /* Find the first window with the cursor actually set, as
9780      the cursor is inherited from the parent */
9781   while (cursor_window->cursor == NULL &&
9782          (parent = get_event_parent (cursor_window)) != NULL &&
9783          parent->window_type != GDK_WINDOW_ROOT)
9784     cursor_window = parent;
9785
9786   /* Set all cursors on toplevel, otherwise its tricky to keep track of
9787    * which native window has what cursor set. */
9788   toplevel = (GdkWindowObject *) get_event_toplevel (pointer_window);
9789   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
9790   impl_iface->set_device_cursor ((GdkWindow *) toplevel, device,
9791                                  cursor_window->cursor);
9792 }
9793
9794 static gboolean
9795 point_in_window (GdkWindowObject *window,
9796                  gdouble          x,
9797                  gdouble          y)
9798 {
9799   return
9800     x >= 0 && x < window->width &&
9801     y >= 0 && y < window->height &&
9802     (window->shape == NULL ||
9803      gdk_region_point_in (window->shape,
9804                           x, y)) &&
9805     (window->input_shape == NULL ||
9806      gdk_region_point_in (window->input_shape,
9807                           x, y));
9808 }
9809
9810 static GdkWindow *
9811 convert_native_coords_to_toplevel (GdkWindow *window,
9812                                    gdouble    child_x,
9813                                    gdouble    child_y,
9814                                    gdouble   *toplevel_x,
9815                                    gdouble   *toplevel_y)
9816 {
9817   GdkWindowObject *private = (GdkWindowObject *)window;
9818   gdouble x, y;
9819
9820   x = child_x;
9821   y = child_y;
9822
9823   while (!gdk_window_is_toplevel (private))
9824     {
9825       x += private->x;
9826       y += private->y;
9827       private = private->parent;
9828     }
9829
9830   *toplevel_x = x;
9831   *toplevel_y = y;
9832
9833   return (GdkWindow *)private;
9834 }
9835
9836 static void
9837 convert_toplevel_coords_to_window (GdkWindow *window,
9838                                    gdouble    toplevel_x,
9839                                    gdouble    toplevel_y,
9840                                    gdouble   *window_x,
9841                                    gdouble   *window_y)
9842 {
9843   GdkWindowObject *private;
9844   GdkWindowObject *parent;
9845   gdouble x, y;
9846   GList *children, *l;
9847
9848   private = GDK_WINDOW_OBJECT (window);
9849
9850   x = toplevel_x;
9851   y = toplevel_y;
9852
9853   children = NULL;
9854   while ((parent = get_event_parent (private)) != NULL &&
9855          (parent->window_type != GDK_WINDOW_ROOT))
9856     {
9857       children = g_list_prepend (children, private);
9858       private = parent;
9859     }
9860
9861   for (l = children; l != NULL; l = l->next)
9862     gdk_window_coords_from_parent (l->data, x, y, &x, &y);
9863
9864   g_list_free (children);
9865
9866   *window_x = x;
9867   *window_y = y;
9868 }
9869
9870 static GdkWindowObject *
9871 pick_embedded_child (GdkWindowObject *window,
9872                      gdouble          x,
9873                      gdouble          y)
9874 {
9875   GdkWindowObject *res;
9876
9877   res = NULL;
9878   g_signal_emit (window,
9879                  signals[PICK_EMBEDDED_CHILD], 0,
9880                  x, y, &res);
9881
9882   return res;
9883 }
9884
9885 GdkWindow *
9886 _gdk_window_find_child_at (GdkWindow *window,
9887                            int        x,
9888                            int        y)
9889 {
9890   GdkWindowObject *private, *sub;
9891   double child_x, child_y;
9892   GList *l;
9893
9894   private = (GdkWindowObject *)window;
9895
9896   if (point_in_window (private, x, y))
9897     {
9898       /* Children is ordered in reverse stack order, i.e. first is topmost */
9899       for (l = private->children; l != NULL; l = l->next)
9900         {
9901           sub = l->data;
9902
9903           if (!GDK_WINDOW_IS_MAPPED (sub))
9904             continue;
9905
9906           gdk_window_coords_from_parent ((GdkWindow *)sub,
9907                                          x, y,
9908                                          &child_x, &child_y);
9909           if (point_in_window (sub, child_x, child_y))
9910             return (GdkWindow *)sub;
9911         }
9912
9913       if (private->num_offscreen_children > 0)
9914         {
9915           sub = pick_embedded_child (private,
9916                                      x, y);
9917           if (sub)
9918             return (GdkWindow *)sub;
9919         }
9920     }
9921
9922   return NULL;
9923 }
9924
9925 GdkWindow *
9926 _gdk_window_find_descendant_at (GdkWindow *toplevel,
9927                                 gdouble    x,
9928                                 gdouble    y,
9929                                 gdouble   *found_x,
9930                                 gdouble   *found_y)
9931 {
9932   GdkWindowObject *private, *sub;
9933   gdouble child_x, child_y;
9934   GList *l;
9935   gboolean found;
9936
9937   private = (GdkWindowObject *)toplevel;
9938
9939   if (point_in_window (private, x, y))
9940     {
9941       do
9942         {
9943           found = FALSE;
9944           /* Children is ordered in reverse stack order, i.e. first is topmost */
9945           for (l = private->children; l != NULL; l = l->next)
9946             {
9947               sub = l->data;
9948
9949               if (!GDK_WINDOW_IS_MAPPED (sub))
9950                 continue;
9951
9952               gdk_window_coords_from_parent ((GdkWindow *)sub,
9953                                              x, y,
9954                                              &child_x, &child_y);
9955               if (point_in_window (sub, child_x, child_y))
9956                 {
9957                   x = child_x;
9958                   y = child_y;
9959                   private = sub;
9960                   found = TRUE;
9961                   break;
9962                 }
9963             }
9964           if (!found &&
9965               private->num_offscreen_children > 0)
9966             {
9967               sub = pick_embedded_child (private,
9968                                          x, y);
9969               if (sub)
9970                 {
9971                   found = TRUE;
9972                   private = sub;
9973                   from_embedder (sub, x, y, &x, &y);
9974                 }
9975             }
9976         }
9977       while (found);
9978     }
9979   else
9980     {
9981       /* Not in window at all */
9982       private = NULL;
9983     }
9984
9985   if (found_x)
9986     *found_x = x;
9987   if (found_y)
9988     *found_y = y;
9989
9990   return (GdkWindow *)private;
9991 }
9992
9993 /**
9994  * gdk_window_beep:
9995  * @window: a toplevel #GdkWindow
9996  *
9997  * Emits a short beep associated to @window in the appropriate
9998  * display, if supported. Otherwise, emits a short beep on
9999  * the display just as gdk_display_beep().
10000  *
10001  * Since: 2.12
10002  **/
10003 void
10004 gdk_window_beep (GdkWindow *window)
10005 {
10006   GdkDisplay *display;
10007   GdkWindow *toplevel;
10008
10009   g_return_if_fail (GDK_IS_WINDOW (window));
10010
10011   if (GDK_WINDOW_DESTROYED (window))
10012     return;
10013
10014   toplevel = get_event_toplevel (window);
10015   display = gdk_drawable_get_display (GDK_DRAWABLE (window));
10016
10017   if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
10018     _gdk_windowing_window_beep (toplevel);
10019   else
10020     gdk_display_beep (display);
10021 }
10022
10023 /**
10024  * gdk_window_set_support_multidevice:
10025  * @window: a #GdkWindow.
10026  * @support_multidevice: %TRUE to enable multidevice support in @window.
10027  *
10028  * This function will enable multidevice features in @window.
10029  *
10030  * Multidevice aware windows will need to handle properly multiple,
10031  * per device enter/leave events, device grabs and grab ownerships.
10032  *
10033  * Since: 3.0
10034  **/
10035 void
10036 gdk_window_set_support_multidevice (GdkWindow *window,
10037                                     gboolean   support_multidevice)
10038 {
10039   GdkWindowObject *private = (GdkWindowObject *) window;
10040
10041   g_return_if_fail (GDK_IS_WINDOW (window));
10042
10043   if (GDK_WINDOW_DESTROYED (window))
10044     return;
10045
10046   if (private->support_multidevice == support_multidevice)
10047     return;
10048
10049   private->support_multidevice = support_multidevice;
10050
10051   /* FIXME: What to do if called when some pointers are inside the window ? */
10052 }
10053
10054 /**
10055  * gdk_window_get_support_multidevice:
10056  * @window: a #GdkWindow.
10057  *
10058  * Returns %TRUE if the window is aware of the existence of multiple
10059  * devices.
10060  *
10061  * Returns: %TRUE if the window handles multidevice features.
10062  *
10063  * Since: 3.0
10064  **/
10065 gboolean
10066 gdk_window_get_support_multidevice (GdkWindow *window)
10067 {
10068   GdkWindowObject *private = (GdkWindowObject *) window;
10069
10070   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
10071
10072   if (GDK_WINDOW_DESTROYED (window))
10073     return FALSE;
10074
10075   return private->support_multidevice;
10076 }
10077
10078 static const guint type_masks[] = {
10079   GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE                 = 0  */
10080   GDK_STRUCTURE_MASK, /* GDK_DESTROY                   = 1  */
10081   GDK_EXPOSURE_MASK, /* GDK_EXPOSE                     = 2  */
10082   GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY        = 3  */
10083   GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS           = 4  */
10084   GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS          = 5  */
10085   GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS          = 6  */
10086   GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE       = 7  */
10087   GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS                 = 8  */
10088   GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE             = 9  */
10089   GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY           = 10 */
10090   GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY           = 11 */
10091   GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE           = 12 */
10092   GDK_STRUCTURE_MASK, /* GDK_CONFIGURE                 = 13 */
10093   GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP               = 14 */
10094   GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP             = 15 */
10095   GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY     = 16 */
10096   GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR     = 17 */
10097   GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST   = 18 */
10098   GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY    = 19 */
10099   GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN           = 20 */
10100   GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT         = 21 */
10101   GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER               = 22 */
10102   GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE               = 23 */
10103   GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION              = 24 */
10104   GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS              = 25 */
10105   GDK_ALL_EVENTS_MASK, /* GDK_DROP_START               = 26 */
10106   GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED            = 27 */
10107   GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT             = 28 */
10108   GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
10109   GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE                  = 30 */
10110   GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
10111   0, /* GDK_WINDOW_STATE = 32 */
10112   0, /* GDK_SETTING = 33 */
10113   0, /* GDK_OWNER_CHANGE = 34 */
10114   0, /* GDK_GRAB_BROKEN = 35 */
10115   0, /* GDK_DAMAGE = 36 */
10116 };
10117 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
10118
10119 /* send motion events if the right buttons are down */
10120 static guint
10121 update_evmask_for_button_motion (guint           evmask,
10122                                  GdkModifierType mask)
10123 {
10124   if (evmask & GDK_BUTTON_MOTION_MASK &&
10125       mask & (GDK_BUTTON1_MASK |
10126               GDK_BUTTON2_MASK |
10127               GDK_BUTTON3_MASK |
10128               GDK_BUTTON4_MASK |
10129               GDK_BUTTON5_MASK))
10130     evmask |= GDK_POINTER_MOTION_MASK;
10131
10132   if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
10133       (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
10134       (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
10135     evmask |= GDK_POINTER_MOTION_MASK;
10136
10137   return evmask;
10138 }
10139
10140 static gboolean
10141 is_button_type (GdkEventType type)
10142 {
10143   return type == GDK_BUTTON_PRESS ||
10144          type == GDK_2BUTTON_PRESS ||
10145          type == GDK_3BUTTON_PRESS ||
10146          type == GDK_BUTTON_RELEASE ||
10147          type == GDK_SCROLL;
10148 }
10149
10150 static gboolean
10151 is_motion_type (GdkEventType type)
10152 {
10153   return type == GDK_MOTION_NOTIFY ||
10154          type == GDK_ENTER_NOTIFY ||
10155          type == GDK_LEAVE_NOTIFY;
10156 }
10157
10158 static GdkWindowObject *
10159 find_common_ancestor (GdkWindowObject *win1,
10160                       GdkWindowObject *win2)
10161 {
10162   GdkWindowObject *tmp;
10163   GList *path1 = NULL, *path2 = NULL;
10164   GList *list1, *list2;
10165
10166   tmp = win1;
10167   while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
10168     {
10169       path1 = g_list_prepend (path1, tmp);
10170       tmp = get_event_parent (tmp);
10171     }
10172
10173   tmp = win2;
10174   while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
10175     {
10176       path2 = g_list_prepend (path2, tmp);
10177       tmp = get_event_parent (tmp);
10178     }
10179
10180   list1 = path1;
10181   list2 = path2;
10182   tmp = NULL;
10183   while (list1 && list2 && (list1->data == list2->data))
10184     {
10185       tmp = (GdkWindowObject *)list1->data;
10186       list1 = g_list_next (list1);
10187       list2 = g_list_next (list2);
10188     }
10189   g_list_free (path1);
10190   g_list_free (path2);
10191
10192   return tmp;
10193 }
10194
10195 GdkEvent *
10196 _gdk_make_event (GdkWindow    *window,
10197                  GdkEventType  type,
10198                  GdkEvent     *event_in_queue,
10199                  gboolean      before_event)
10200 {
10201   GdkEvent *event = gdk_event_new (type);
10202   guint32 the_time;
10203   GdkModifierType the_state;
10204
10205   the_time = gdk_event_get_time (event_in_queue);
10206   gdk_event_get_state (event_in_queue, &the_state);
10207
10208   event->any.window = g_object_ref (window);
10209   event->any.send_event = FALSE;
10210   if (event_in_queue && event_in_queue->any.send_event)
10211     event->any.send_event = TRUE;
10212
10213   switch (type)
10214     {
10215     case GDK_MOTION_NOTIFY:
10216       event->motion.time = the_time;
10217       event->motion.axes = NULL;
10218       event->motion.state = the_state;
10219       break;
10220
10221     case GDK_BUTTON_PRESS:
10222     case GDK_2BUTTON_PRESS:
10223     case GDK_3BUTTON_PRESS:
10224     case GDK_BUTTON_RELEASE:
10225       event->button.time = the_time;
10226       event->button.axes = NULL;
10227       event->button.state = the_state;
10228       break;
10229
10230     case GDK_SCROLL:
10231       event->scroll.time = the_time;
10232       event->scroll.state = the_state;
10233       break;
10234
10235     case GDK_KEY_PRESS:
10236     case GDK_KEY_RELEASE:
10237       event->key.time = the_time;
10238       event->key.state = the_state;
10239       break;
10240
10241     case GDK_ENTER_NOTIFY:
10242     case GDK_LEAVE_NOTIFY:
10243       event->crossing.time = the_time;
10244       event->crossing.state = the_state;
10245       break;
10246
10247     case GDK_PROPERTY_NOTIFY:
10248       event->property.time = the_time;
10249       event->property.state = the_state;
10250       break;
10251
10252     case GDK_SELECTION_CLEAR:
10253     case GDK_SELECTION_REQUEST:
10254     case GDK_SELECTION_NOTIFY:
10255       event->selection.time = the_time;
10256       break;
10257
10258     case GDK_PROXIMITY_IN:
10259     case GDK_PROXIMITY_OUT:
10260       event->proximity.time = the_time;
10261       break;
10262
10263     case GDK_DRAG_ENTER:
10264     case GDK_DRAG_LEAVE:
10265     case GDK_DRAG_MOTION:
10266     case GDK_DRAG_STATUS:
10267     case GDK_DROP_START:
10268     case GDK_DROP_FINISHED:
10269       event->dnd.time = the_time;
10270       break;
10271
10272     case GDK_FOCUS_CHANGE:
10273     case GDK_CONFIGURE:
10274     case GDK_MAP:
10275     case GDK_UNMAP:
10276     case GDK_CLIENT_EVENT:
10277     case GDK_VISIBILITY_NOTIFY:
10278     case GDK_NO_EXPOSE:
10279     case GDK_DELETE:
10280     case GDK_DESTROY:
10281     case GDK_EXPOSE:
10282     default:
10283       break;
10284     }
10285
10286   if (event_in_queue)
10287     {
10288     if (before_event)
10289       _gdk_event_queue_insert_before (gdk_drawable_get_display (window), event_in_queue, event);
10290     else
10291       _gdk_event_queue_insert_after (gdk_drawable_get_display (window), event_in_queue, event);
10292     }
10293   else
10294     _gdk_event_queue_append (gdk_drawable_get_display (window), event);
10295
10296   return event;
10297 }
10298
10299 static void
10300 send_crossing_event (GdkDisplay                 *display,
10301                      GdkWindowObject            *toplevel,
10302                      GdkWindowObject            *window,
10303                      GdkEventType                type,
10304                      GdkCrossingMode             mode,
10305                      GdkNotifyType               notify_type,
10306                      GdkWindow                  *subwindow,
10307                      GdkDevice                  *device,
10308                      gint                        toplevel_x,
10309                      gint                        toplevel_y,
10310                      GdkModifierType             mask,
10311                      guint32                     time_,
10312                      GdkEvent                   *event_in_queue,
10313                      gulong                      serial)
10314 {
10315   GdkEvent *event;
10316   guint32 window_event_mask, type_event_mask;
10317   GdkDeviceGrabInfo *grab;
10318   gboolean block_event = FALSE;
10319
10320   grab = _gdk_display_has_device_grab (display, device, serial);
10321
10322   if (grab != NULL &&
10323       !grab->owner_events)
10324     {
10325       /* !owner_event => only report events wrt grab window, ignore rest */
10326       if ((GdkWindow *)window != grab->window)
10327         return;
10328       window_event_mask = grab->event_mask;
10329     }
10330   else
10331     window_event_mask = window->event_mask;
10332
10333   if (type == GDK_LEAVE_NOTIFY)
10334     {
10335       type_event_mask = GDK_LEAVE_NOTIFY_MASK;
10336       window->devices_inside = g_list_remove (window->devices_inside, device);
10337
10338       if (!window->support_multidevice && window->devices_inside)
10339         {
10340           /* Block leave events unless it's the last pointer */
10341           block_event = TRUE;
10342         }
10343     }
10344   else
10345     {
10346       type_event_mask = GDK_ENTER_NOTIFY_MASK;
10347
10348       if (!window->support_multidevice && window->devices_inside)
10349         {
10350           /* Only emit enter events for the first device */
10351           block_event = TRUE;
10352         }
10353
10354       if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
10355           device->mode != GDK_MODE_DISABLED &&
10356           !g_list_find (window->devices_inside, device))
10357         window->devices_inside = g_list_prepend (window->devices_inside, device);
10358     }
10359
10360   if (block_event)
10361     return;
10362
10363   if (window_event_mask & type_event_mask)
10364     {
10365       event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
10366       gdk_event_set_device (event, device);
10367       event->crossing.time = time_;
10368       event->crossing.subwindow = subwindow;
10369       if (subwindow)
10370         g_object_ref (subwindow);
10371       convert_toplevel_coords_to_window ((GdkWindow *)window,
10372                                          toplevel_x, toplevel_y,
10373                                          &event->crossing.x, &event->crossing.y);
10374       event->crossing.x_root = toplevel_x + toplevel->x;
10375       event->crossing.y_root = toplevel_y + toplevel->y;
10376       event->crossing.mode = mode;
10377       event->crossing.detail = notify_type;
10378       event->crossing.focus = FALSE;
10379       event->crossing.state = mask;
10380     }
10381 }
10382
10383
10384 /* The coordinates are in the toplevel window that src/dest are in.
10385  * src and dest are always (if != NULL) in the same toplevel, as
10386  * we get a leave-notify and set the window_under_pointer to null
10387  * before crossing to another toplevel.
10388  */
10389 void
10390 _gdk_synthesize_crossing_events (GdkDisplay                 *display,
10391                                  GdkWindow                  *src,
10392                                  GdkWindow                  *dest,
10393                                  GdkDevice                  *device,
10394                                  GdkCrossingMode             mode,
10395                                  gint                        toplevel_x,
10396                                  gint                        toplevel_y,
10397                                  GdkModifierType             mask,
10398                                  guint32                     time_,
10399                                  GdkEvent                   *event_in_queue,
10400                                  gulong                      serial,
10401                                  gboolean                    non_linear)
10402 {
10403   GdkWindowObject *c;
10404   GdkWindowObject *win, *last, *next;
10405   GList *path, *list;
10406   GdkWindowObject *a;
10407   GdkWindowObject *b;
10408   GdkWindowObject *toplevel;
10409   GdkNotifyType notify_type;
10410
10411   /* TODO: Don't send events to toplevel, as we get those from the windowing system */
10412
10413   a = (GdkWindowObject *)src;
10414   b = (GdkWindowObject *)dest;
10415   if (a == b)
10416     return; /* No crossings generated between src and dest */
10417
10418   if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
10419     {
10420       if (a && gdk_window_get_device_events (src, device) == 0)
10421         a = NULL;
10422
10423       if (b && gdk_window_get_device_events (dest, device) == 0)
10424         b = NULL;
10425     }
10426
10427   if (!a && !b)
10428     return;
10429
10430   c = find_common_ancestor (a, b);
10431
10432   non_linear |= (c != a) && (c != b);
10433
10434   if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
10435     {
10436       toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
10437
10438       /* Traverse up from a to (excluding) c sending leave events */
10439       if (non_linear)
10440         notify_type = GDK_NOTIFY_NONLINEAR;
10441       else if (c == a)
10442         notify_type = GDK_NOTIFY_INFERIOR;
10443       else
10444         notify_type = GDK_NOTIFY_ANCESTOR;
10445       send_crossing_event (display, toplevel,
10446                            a, GDK_LEAVE_NOTIFY,
10447                            mode,
10448                            notify_type,
10449                            NULL, device,
10450                            toplevel_x, toplevel_y,
10451                            mask, time_,
10452                            event_in_queue,
10453                            serial);
10454
10455       if (c != a)
10456         {
10457           if (non_linear)
10458             notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
10459           else
10460             notify_type = GDK_NOTIFY_VIRTUAL;
10461
10462           last = a;
10463           win = get_event_parent (a);
10464           while (win != c && win->window_type != GDK_WINDOW_ROOT)
10465             {
10466               send_crossing_event (display, toplevel,
10467                                    win, GDK_LEAVE_NOTIFY,
10468                                    mode,
10469                                    notify_type,
10470                                    (GdkWindow *)last,
10471                                    device,
10472                                    toplevel_x, toplevel_y,
10473                                    mask, time_,
10474                                    event_in_queue,
10475                                    serial);
10476
10477               last = win;
10478               win = get_event_parent (win);
10479             }
10480         }
10481     }
10482
10483   if (b) /* Might not be a dest, e.g. if we're moving out of the window */
10484     {
10485       toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
10486
10487       /* Traverse down from c to b */
10488       if (c != b)
10489         {
10490           path = NULL;
10491           win = get_event_parent (b);
10492           while (win != c && win->window_type != GDK_WINDOW_ROOT)
10493             {
10494               path = g_list_prepend (path, win);
10495               win = get_event_parent (win);
10496             }
10497
10498           if (non_linear)
10499             notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
10500           else
10501             notify_type = GDK_NOTIFY_VIRTUAL;
10502
10503           list = path;
10504           while (list)
10505             {
10506               win = (GdkWindowObject *)list->data;
10507               list = g_list_next (list);
10508               if (list)
10509                 next = (GdkWindowObject *)list->data;
10510               else
10511                 next = b;
10512
10513               send_crossing_event (display, toplevel,
10514                                    win, GDK_ENTER_NOTIFY,
10515                                    mode,
10516                                    notify_type,
10517                                    (GdkWindow *)next,
10518                                    device,
10519                                    toplevel_x, toplevel_y,
10520                                    mask, time_,
10521                                    event_in_queue,
10522                                    serial);
10523             }
10524           g_list_free (path);
10525         }
10526
10527
10528       if (non_linear)
10529         notify_type = GDK_NOTIFY_NONLINEAR;
10530       else if (c == a)
10531         notify_type = GDK_NOTIFY_ANCESTOR;
10532       else
10533         notify_type = GDK_NOTIFY_INFERIOR;
10534
10535       send_crossing_event (display, toplevel,
10536                            b, GDK_ENTER_NOTIFY,
10537                            mode,
10538                            notify_type,
10539                            NULL,
10540                            device,
10541                            toplevel_x, toplevel_y,
10542                            mask, time_,
10543                            event_in_queue,
10544                            serial);
10545     }
10546 }
10547
10548 /* Returns the window inside the event window with the pointer in it
10549  * at the specified coordinates, or NULL if its not in any child of
10550  * the toplevel. It also takes into account !owner_events grabs.
10551  */
10552 static GdkWindow *
10553 get_pointer_window (GdkDisplay *display,
10554                     GdkWindow *event_window,
10555                     GdkDevice *device,
10556                     gdouble toplevel_x,
10557                     gdouble toplevel_y,
10558                     gulong serial)
10559 {
10560   GdkWindow *pointer_window;
10561   GdkDeviceGrabInfo *grab;
10562   GdkPointerWindowInfo *pointer_info;
10563
10564   pointer_info = _gdk_display_get_pointer_info (display, device);
10565
10566   if (event_window == pointer_info->toplevel_under_pointer)
10567     pointer_window =
10568       _gdk_window_find_descendant_at (event_window,
10569                                       toplevel_x, toplevel_y,
10570                                       NULL, NULL);
10571   else
10572     pointer_window = NULL;
10573
10574   grab = _gdk_display_has_device_grab (display, device, serial);
10575   if (grab != NULL &&
10576       !grab->owner_events &&
10577       pointer_window != grab->window)
10578     pointer_window = NULL;
10579
10580   return pointer_window;
10581 }
10582
10583 void
10584 _gdk_display_set_window_under_pointer (GdkDisplay *display,
10585                                        GdkDevice  *device,
10586                                        GdkWindow  *window)
10587 {
10588   GdkPointerWindowInfo *device_info;
10589
10590   /* We don't track this if all native, and it can cause issues
10591      with the update_cursor call below */
10592   if (_gdk_native_windows)
10593     return;
10594
10595   device_info = _gdk_display_get_pointer_info (display, device);
10596
10597   if (device_info->window_under_pointer)
10598     g_object_unref (device_info->window_under_pointer);
10599   device_info->window_under_pointer = window;
10600
10601   if (window)
10602     {
10603       g_object_ref (window);
10604       update_cursor (display, device);
10605     }
10606
10607   _gdk_display_enable_motion_hints (display, device);
10608 }
10609
10610 /**
10611  * gdk_pointer_grab:
10612  * @window: the #GdkWindow which will own the grab (the grab window).
10613  * @owner_events: if %FALSE then all pointer events are reported with respect to
10614  *                @window and are only reported if selected by @event_mask. If %TRUE then pointer
10615  *                events for this application are reported as normal, but pointer events outside
10616  *                this application are reported with respect to @window and only if selected by
10617  *                @event_mask. In either mode, unreported events are discarded.
10618  * @event_mask: specifies the event mask, which is used in accordance with
10619  *              @owner_events. Note that only pointer events (i.e. button and motion events)
10620  *              may be selected.
10621  * @confine_to: If non-%NULL, the pointer will be confined to this
10622  *              window during the grab. If the pointer is outside @confine_to, it will
10623  *              automatically be moved to the closest edge of @confine_to and enter
10624  *              and leave events will be generated as necessary.
10625  * @cursor: the cursor to display while the grab is active. If this is %NULL then
10626  *          the normal cursors are used for @window and its descendants, and the cursor
10627  *          for @window is used for all other windows.
10628  * @time_: the timestamp of the event which led to this pointer grab. This usually
10629  *         comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
10630  *         the time isn't known.
10631  *
10632  * Grabs the pointer (usually a mouse) so that all events are passed to this
10633  * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
10634  * the grab window becomes unviewable.
10635  * This overrides any previous pointer grab by this client.
10636  *
10637  * Pointer grabs are used for operations which need complete control over mouse
10638  * events, even if the mouse leaves the application.
10639  * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
10640  * the #GtkHPaned and #GtkVPaned widgets, and for resizing columns in #GtkCList
10641  * widgets.
10642  *
10643  * Note that if the event mask of an X window has selected both button press and
10644  * button release events, then a button press event will cause an automatic
10645  * pointer grab until the button is released.
10646  * X does this automatically since most applications expect to receive button
10647  * press and release events in pairs.
10648  * It is equivalent to a pointer grab on the window with @owner_events set to
10649  * %TRUE.
10650  *
10651  * If you set up anything at the time you take the grab that needs to be cleaned
10652  * up when the grab ends, you should handle the #GdkEventGrabBroken events that
10653  * are emitted when the grab ends unvoluntarily.
10654  *
10655  * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
10656  *
10657  * Deprecated: 3.0: Use gdk_device_grab() instead.
10658  **/
10659 GdkGrabStatus
10660 gdk_pointer_grab (GdkWindow *     window,
10661                   gboolean        owner_events,
10662                   GdkEventMask    event_mask,
10663                   GdkWindow *     confine_to,
10664                   GdkCursor *     cursor,
10665                   guint32         time)
10666 {
10667   GdkWindow *native;
10668   GdkDisplay *display;
10669   GdkDeviceManager *device_manager;
10670   GdkDevice *device;
10671   GdkGrabStatus res = 0;
10672   gulong serial;
10673   GList *devices, *dev;
10674
10675   g_return_val_if_fail (window != NULL, 0);
10676   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
10677   g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
10678
10679   /* We need a native window for confine to to work, ensure we have one */
10680   if (confine_to)
10681     {
10682       if (!gdk_window_ensure_native (confine_to))
10683         {
10684           g_warning ("Can't confine to grabbed window, not native");
10685           confine_to = NULL;
10686         }
10687     }
10688
10689   /* Non-viewable client side window => fail */
10690   if (!_gdk_window_has_impl (window) &&
10691       !gdk_window_is_viewable (window))
10692     return GDK_GRAB_NOT_VIEWABLE;
10693
10694   if (_gdk_native_windows)
10695     native = window;
10696   else
10697     native = gdk_window_get_toplevel (window);
10698   while (gdk_window_is_offscreen ((GdkWindowObject *)native))
10699     {
10700       native = gdk_offscreen_window_get_embedder (native);
10701
10702       if (native == NULL ||
10703           (!_gdk_window_has_impl (native) &&
10704            !gdk_window_is_viewable (native)))
10705         return GDK_GRAB_NOT_VIEWABLE;
10706
10707       native = gdk_window_get_toplevel (native);
10708     }
10709
10710   display = gdk_drawable_get_display (window);
10711
10712   serial = _gdk_windowing_window_get_next_serial (display);
10713   device_manager = gdk_display_get_device_manager (display);
10714   devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
10715
10716   /* FIXME: Should this be generic to all backends? */
10717   /* FIXME: What happens with extended devices? */
10718   for (dev = devices; dev; dev = dev->next)
10719     {
10720       device = dev->data;
10721
10722       if (device->source != GDK_SOURCE_MOUSE)
10723         continue;
10724
10725       res = _gdk_windowing_device_grab (device,
10726                                         window,
10727                                         native,
10728                                         owner_events,
10729                                         get_native_grab_event_mask (event_mask),
10730                                         confine_to,
10731                                         cursor,
10732                                         time);
10733
10734       if (res == GDK_GRAB_SUCCESS)
10735         _gdk_display_add_device_grab (display,
10736                                       device,
10737                                       window,
10738                                       native,
10739                                       GDK_OWNERSHIP_NONE,
10740                                       owner_events,
10741                                       event_mask,
10742                                       serial,
10743                                       time,
10744                                       FALSE);
10745     }
10746
10747   /* FIXME: handle errors when grabbing */
10748
10749   g_list_free (devices);
10750
10751   return res;
10752 }
10753
10754 /**
10755  * gdk_keyboard_grab:
10756  * @window: the #GdkWindow which will own the grab (the grab window).
10757  * @owner_events: if %FALSE then all keyboard events are reported with respect to
10758  *                @window. If %TRUE then keyboard events for this application are
10759  *                reported as normal, but keyboard events outside this application
10760  *                are reported with respect to @window. Both key press and key
10761  *                release events are always reported, independant of the event mask
10762  *                set by the application.
10763  * @time: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
10764 available.
10765  *
10766  * Grabs the keyboard so that all events are passed to this
10767  * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
10768  * This overrides any previous keyboard grab by this client.
10769  *
10770  * If you set up anything at the time you take the grab that needs to be cleaned
10771  * up when the grab ends, you should handle the #GdkEventGrabBroken events that
10772  * are emitted when the grab ends unvoluntarily.
10773  *
10774  * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
10775  *
10776  * Deprecated: 3.0: Use gdk_device_grab() instead.
10777  **/
10778 GdkGrabStatus
10779 gdk_keyboard_grab (GdkWindow *window,
10780                    gboolean   owner_events,
10781                    guint32    time)
10782 {
10783   GdkWindow *native;
10784   GdkDisplay *display;
10785   GdkDeviceManager *device_manager;
10786   GdkDevice *device;
10787   GdkGrabStatus res = 0;
10788   gulong serial;
10789   GList *devices, *dev;
10790
10791   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
10792
10793   /* Non-viewable client side window => fail */
10794   if (!_gdk_window_has_impl (window) &&
10795       !gdk_window_is_viewable (window))
10796     return GDK_GRAB_NOT_VIEWABLE;
10797
10798   if (_gdk_native_windows)
10799     native = window;
10800   else
10801     native = gdk_window_get_toplevel (window);
10802
10803   while (gdk_window_is_offscreen ((GdkWindowObject *)native))
10804     {
10805       native = gdk_offscreen_window_get_embedder (native);
10806
10807       if (native == NULL ||
10808           (!_gdk_window_has_impl (native) &&
10809            !gdk_window_is_viewable (native)))
10810         return GDK_GRAB_NOT_VIEWABLE;
10811
10812       native = gdk_window_get_toplevel (native);
10813     }
10814
10815   display = gdk_drawable_get_display (window);
10816
10817   serial = _gdk_windowing_window_get_next_serial (display);
10818   device_manager = gdk_display_get_device_manager (display);
10819   devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
10820
10821   /* FIXME: Should this be generic to all backends? */
10822   /* FIXME: What happens with extended devices? */
10823   for (dev = devices; dev; dev = dev->next)
10824     {
10825       device = dev->data;
10826
10827       if (device->source != GDK_SOURCE_KEYBOARD)
10828         continue;
10829
10830       res = _gdk_windowing_device_grab (device,
10831                                         window,
10832                                         native,
10833                                         owner_events,
10834                                         GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
10835                                         NULL,
10836                                         NULL,
10837                                         time);
10838
10839       if (res == GDK_GRAB_SUCCESS)
10840         _gdk_display_add_device_grab (display,
10841                                       device,
10842                                       window,
10843                                       native,
10844                                       GDK_OWNERSHIP_NONE,
10845                                       owner_events, 0,
10846                                       serial,
10847                                       time,
10848                                       FALSE);
10849     }
10850
10851   /* FIXME: handle errors when grabbing */
10852
10853   g_list_free (devices);
10854
10855   return res;
10856 }
10857
10858 /**
10859  * gdk_window_geometry_changed:
10860  * @window: an embedded offscreen #GdkWindow
10861  *
10862  * This function informs GDK that the geometry of an embedded
10863  * offscreen window has changed. This is necessary for GDK to keep
10864  * track of which offscreen window the pointer is in.
10865  *
10866  * Since: 2.18
10867  */
10868 void
10869 gdk_window_geometry_changed (GdkWindow *window)
10870 {
10871   _gdk_synthesize_crossing_events_for_geometry_change (window);
10872 }
10873
10874 static gboolean
10875 do_synthesize_crossing_event (gpointer data)
10876 {
10877   GdkDisplay *display;
10878   GdkWindow *changed_toplevel;
10879   GdkWindowObject *changed_toplevel_priv;
10880   GHashTableIter iter;
10881   gpointer key, value;
10882   gulong serial;
10883
10884   changed_toplevel = data;
10885   changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
10886
10887   changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
10888
10889   if (GDK_WINDOW_DESTROYED (changed_toplevel))
10890     return FALSE;
10891
10892   display = gdk_drawable_get_display (changed_toplevel);
10893   serial = _gdk_windowing_window_get_next_serial (display);
10894   g_hash_table_iter_init (&iter, display->pointers_info);
10895
10896   while (g_hash_table_iter_next (&iter, &key, &value))
10897     {
10898       GdkWindow *new_window_under_pointer;
10899       GdkPointerWindowInfo *pointer_info = value;
10900       GdkDevice *device = key;
10901
10902       if (changed_toplevel == pointer_info->toplevel_under_pointer)
10903         {
10904           new_window_under_pointer =
10905             get_pointer_window (display, changed_toplevel,
10906                                 device,
10907                                 pointer_info->toplevel_x,
10908                                 pointer_info->toplevel_y,
10909                                 serial);
10910           if (new_window_under_pointer != pointer_info->window_under_pointer)
10911             {
10912               _gdk_synthesize_crossing_events (display,
10913                                                pointer_info->window_under_pointer,
10914                                                new_window_under_pointer,
10915                                                device,
10916                                                GDK_CROSSING_NORMAL,
10917                                                pointer_info->toplevel_x,
10918                                                pointer_info->toplevel_y,
10919                                                pointer_info->state,
10920                                                GDK_CURRENT_TIME,
10921                                                NULL,
10922                                                serial,
10923                                                FALSE);
10924               _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
10925             }
10926         }
10927     }
10928
10929   return FALSE;
10930 }
10931
10932 void
10933 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
10934 {
10935   GdkDisplay *display;
10936   GdkWindow *toplevel;
10937   GdkWindowObject *toplevel_priv;
10938
10939   if (_gdk_native_windows)
10940     return; /* We use the native crossing events if all native */
10941
10942   display = gdk_drawable_get_display (changed_window);
10943
10944   toplevel = get_event_toplevel (changed_window);
10945   toplevel_priv = (GdkWindowObject *) toplevel;
10946
10947   if (!toplevel_priv->synthesize_crossing_event_queued)
10948     {
10949       toplevel_priv->synthesize_crossing_event_queued = TRUE;
10950
10951       g_idle_add_full (GDK_PRIORITY_EVENTS - 1,
10952                        do_synthesize_crossing_event,
10953                        g_object_ref (toplevel),
10954                        g_object_unref);
10955     }
10956 }
10957
10958 /* Don't use for crossing events */
10959 static GdkWindow *
10960 get_event_window (GdkDisplay                 *display,
10961                   GdkDevice                  *device,
10962                   GdkWindow                  *pointer_window,
10963                   GdkEventType                type,
10964                   GdkModifierType             mask,
10965                   guint                      *evmask_out,
10966                   gulong                      serial)
10967 {
10968   guint evmask;
10969   GdkWindow *grab_window;
10970   GdkWindowObject *w;
10971   GdkDeviceGrabInfo *grab;
10972
10973   grab = _gdk_display_has_device_grab (display, device, serial);
10974
10975   if (grab != NULL && !grab->owner_events)
10976     {
10977       evmask = grab->event_mask;
10978       evmask = update_evmask_for_button_motion (evmask, mask);
10979
10980       grab_window = grab->window;
10981
10982       if (evmask & type_masks[type])
10983         {
10984           if (evmask_out)
10985             *evmask_out = evmask;
10986           return grab_window;
10987         }
10988       else
10989         return NULL;
10990     }
10991
10992   w = (GdkWindowObject *)pointer_window;
10993   while (w != NULL)
10994     {
10995       evmask = w->event_mask;
10996       evmask = update_evmask_for_button_motion (evmask, mask);
10997
10998       if (evmask & type_masks[type])
10999         {
11000           if (evmask_out)
11001             *evmask_out = evmask;
11002           return (GdkWindow *)w;
11003         }
11004
11005       w = get_event_parent (w);
11006     }
11007
11008   if (grab != NULL &&
11009       grab->owner_events)
11010     {
11011       evmask = grab->event_mask;
11012       evmask = update_evmask_for_button_motion (evmask, mask);
11013
11014       if (evmask & type_masks[type])
11015         {
11016           if (evmask_out)
11017             *evmask_out = evmask;
11018           return grab->window;
11019         }
11020       else
11021         return NULL;
11022     }
11023
11024   return NULL;
11025 }
11026
11027 static gboolean
11028 proxy_pointer_event (GdkDisplay                 *display,
11029                      GdkEvent                   *source_event,
11030                      gulong                      serial)
11031 {
11032   GdkWindow *toplevel_window, *event_window;
11033   GdkWindow *pointer_window;
11034   GdkPointerWindowInfo *pointer_info;
11035   GdkDevice *device;
11036   GdkEvent *event;
11037   guint state;
11038   gdouble toplevel_x, toplevel_y;
11039   guint32 time_;
11040   gboolean non_linear;
11041
11042   event_window = source_event->any.window;
11043   gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
11044   gdk_event_get_state (source_event, &state);
11045   time_ = gdk_event_get_time (source_event);
11046   device = gdk_event_get_device (source_event);
11047   pointer_info = _gdk_display_get_pointer_info (display, device);
11048   toplevel_window = convert_native_coords_to_toplevel (event_window,
11049                                                        toplevel_x, toplevel_y,
11050                                                        &toplevel_x, &toplevel_y);
11051
11052   non_linear = FALSE;
11053   if ((source_event->type == GDK_LEAVE_NOTIFY ||
11054        source_event->type == GDK_ENTER_NOTIFY) &&
11055       (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
11056        source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
11057     non_linear = TRUE;
11058
11059   /* If we get crossing events with subwindow unexpectedly being NULL
11060      that means there is a native subwindow that gdk doesn't know about.
11061      We track these and forward them, with the correct virtual window
11062      events inbetween.
11063      This is important to get right, as metacity uses gdk for the frame
11064      windows, but gdk doesn't know about the client windows reparented
11065      into the frame. */
11066   if (((source_event->type == GDK_LEAVE_NOTIFY &&
11067         source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
11068        (source_event->type == GDK_ENTER_NOTIFY &&
11069         (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
11070          source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
11071       source_event->crossing.subwindow == NULL)
11072     {
11073       /* Left for an unknown (to gdk) subwindow */
11074
11075       /* Send leave events from window under pointer to event window
11076          that will get the subwindow == NULL window */
11077       _gdk_synthesize_crossing_events (display,
11078                                        pointer_info->window_under_pointer,
11079                                        event_window,
11080                                        device,
11081                                        source_event->crossing.mode,
11082                                        toplevel_x, toplevel_y,
11083                                        state, time_,
11084                                        source_event,
11085                                        serial,
11086                                        non_linear);
11087
11088       /* Send subwindow == NULL event */
11089       send_crossing_event (display,
11090                            (GdkWindowObject *)toplevel_window,
11091                            (GdkWindowObject *)event_window,
11092                            source_event->type,
11093                            source_event->crossing.mode,
11094                            source_event->crossing.detail,
11095                            NULL,
11096                            device,
11097                            toplevel_x, toplevel_y,
11098                            state, time_,
11099                            source_event,
11100                            serial);
11101
11102       _gdk_display_set_window_under_pointer (display, device, NULL);
11103       return TRUE;
11104     }
11105
11106   pointer_window = get_pointer_window (display, toplevel_window, device,
11107                                        toplevel_x, toplevel_y, serial);
11108
11109   if (((source_event->type == GDK_ENTER_NOTIFY &&
11110         source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
11111        (source_event->type == GDK_LEAVE_NOTIFY &&
11112         (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
11113          source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
11114       source_event->crossing.subwindow == NULL)
11115     {
11116       /* Entered from an unknown (to gdk) subwindow */
11117
11118       /* Send subwindow == NULL event */
11119       send_crossing_event (display,
11120                            (GdkWindowObject *)toplevel_window,
11121                            (GdkWindowObject *)event_window,
11122                            source_event->type,
11123                            source_event->crossing.mode,
11124                            source_event->crossing.detail,
11125                            NULL,
11126                            device,
11127                            toplevel_x, toplevel_y,
11128                            state, time_,
11129                            source_event,
11130                            serial);
11131
11132       /* Send enter events from event window to pointer_window */
11133       _gdk_synthesize_crossing_events (display,
11134                                        event_window,
11135                                        pointer_window,
11136                                        device,
11137                                        source_event->crossing.mode,
11138                                        toplevel_x, toplevel_y,
11139                                        state, time_,
11140                                        source_event,
11141                                        serial, non_linear);
11142       _gdk_display_set_window_under_pointer (display, device, pointer_window);
11143       return TRUE;
11144     }
11145
11146   if (pointer_info->window_under_pointer != pointer_window)
11147     {
11148       /* Either a toplevel crossing notify that ended up inside a child window,
11149          or a motion notify that got into another child window  */
11150
11151       /* Different than last time, send crossing events */
11152       _gdk_synthesize_crossing_events (display,
11153                                        pointer_info->window_under_pointer,
11154                                        pointer_window,
11155                                        device,
11156                                        GDK_CROSSING_NORMAL,
11157                                        toplevel_x, toplevel_y,
11158                                        state, time_,
11159                                        source_event,
11160                                        serial, non_linear);
11161       _gdk_display_set_window_under_pointer (display, device, pointer_window);
11162     }
11163   else if (source_event->type == GDK_MOTION_NOTIFY)
11164     {
11165       GdkWindow *event_win;
11166       guint evmask;
11167       gboolean is_hint;
11168
11169       event_win = get_event_window (display,
11170                                     device,
11171                                     pointer_window,
11172                                     source_event->type,
11173                                     state,
11174                                     &evmask,
11175                                     serial);
11176
11177       if (event_win &&
11178           gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
11179           gdk_window_get_device_events (event_win, device) == 0)
11180         return TRUE;
11181
11182       is_hint = FALSE;
11183
11184       if (event_win &&
11185           (evmask & GDK_POINTER_MOTION_HINT_MASK))
11186         {
11187           gulong *device_serial;
11188
11189           device_serial = g_hash_table_lookup (display->motion_hint_info, device);
11190
11191           if (!device_serial ||
11192               (*device_serial != 0 &&
11193                serial < *device_serial))
11194             event_win = NULL; /* Ignore event */
11195           else
11196             {
11197               is_hint = TRUE;
11198               *device_serial = G_MAXULONG;
11199             }
11200         }
11201
11202       if (event_win && !display->ignore_core_events)
11203         {
11204           event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
11205           event->motion.time = time_;
11206           convert_toplevel_coords_to_window (event_win,
11207                                              toplevel_x, toplevel_y,
11208                                              &event->motion.x, &event->motion.y);
11209           event->motion.x_root = source_event->motion.x_root;
11210           event->motion.y_root = source_event->motion.y_root;
11211           event->motion.state = state;
11212           event->motion.is_hint = is_hint;
11213           event->motion.device = source_event->motion.device;
11214           event->motion.axes = g_memdup (source_event->motion.axes,
11215                                          sizeof (gdouble) * source_event->motion.device->num_axes);
11216         }
11217     }
11218
11219   /* unlink all move events from queue.
11220      We handle our own, including our emulated masks. */
11221   return TRUE;
11222 }
11223
11224 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
11225                              GDK_BUTTON2_MASK | \
11226                              GDK_BUTTON3_MASK | \
11227                              GDK_BUTTON4_MASK | \
11228                              GDK_BUTTON5_MASK)
11229
11230 static gboolean
11231 proxy_button_event (GdkEvent *source_event,
11232                     gulong serial)
11233 {
11234   GdkWindow *toplevel_window, *event_window;
11235   GdkWindow *event_win;
11236   GdkWindow *pointer_window;
11237   GdkWindowObject *parent;
11238   GdkEvent *event;
11239   guint state;
11240   guint32 time_;
11241   GdkEventType type;
11242   gdouble toplevel_x, toplevel_y;
11243   GdkDisplay *display;
11244   GdkWindowObject *w;
11245   GdkDevice *device;
11246
11247   type = source_event->any.type;
11248   event_window = source_event->any.window;
11249   gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
11250   gdk_event_get_state (source_event, &state);
11251   time_ = gdk_event_get_time (source_event);
11252   device = gdk_event_get_device (source_event);
11253   display = gdk_drawable_get_display (source_event->any.window);
11254   toplevel_window = convert_native_coords_to_toplevel (event_window,
11255                                                        toplevel_x, toplevel_y,
11256                                                        &toplevel_x, &toplevel_y);
11257
11258   if (type == GDK_BUTTON_PRESS &&
11259       !source_event->any.send_event &&
11260       _gdk_display_has_device_grab (display, device, serial) == NULL)
11261     {
11262       pointer_window =
11263         _gdk_window_find_descendant_at (toplevel_window,
11264                                         toplevel_x, toplevel_y,
11265                                         NULL, NULL);
11266
11267       /* Find the event window, that gets the grab */
11268       w = (GdkWindowObject *)pointer_window;
11269       while (w != NULL &&
11270              (parent = get_event_parent (w)) != NULL &&
11271              parent->window_type != GDK_WINDOW_ROOT)
11272         {
11273           if (w->event_mask & GDK_BUTTON_PRESS_MASK)
11274             break;
11275           w = parent;
11276         }
11277       pointer_window = (GdkWindow *)w;
11278
11279       _gdk_display_add_device_grab  (display,
11280                                      device,
11281                                      pointer_window,
11282                                      toplevel_window,
11283                                      GDK_OWNERSHIP_NONE,
11284                                      FALSE,
11285                                      gdk_window_get_events (pointer_window),
11286                                      serial,
11287                                       time_,
11288                                      TRUE);
11289       _gdk_display_device_grab_update (display, device, serial);
11290     }
11291
11292   pointer_window = get_pointer_window (display, toplevel_window, device,
11293                                        toplevel_x, toplevel_y,
11294                                        serial);
11295
11296   event_win = get_event_window (display,
11297                                 device,
11298                                 pointer_window,
11299                                 type, state,
11300                                 NULL, serial);
11301
11302   if (event_win == NULL || display->ignore_core_events)
11303     return TRUE;
11304
11305   if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
11306       gdk_window_get_device_events (event_win, device) == 0)
11307     return TRUE;
11308
11309   event = _gdk_make_event (event_win, type, source_event, FALSE);
11310
11311   switch (type)
11312     {
11313     case GDK_BUTTON_PRESS:
11314     case GDK_BUTTON_RELEASE:
11315       event->button.button = source_event->button.button;
11316       convert_toplevel_coords_to_window (event_win,
11317                                          toplevel_x, toplevel_y,
11318                                          &event->button.x, &event->button.y);
11319       event->button.x_root = source_event->button.x_root;
11320       event->button.y_root = source_event->button.y_root;
11321       event->button.state = state;
11322       event->button.device = source_event->button.device;
11323       event->button.axes = g_memdup (source_event->button.axes,
11324                                      sizeof (gdouble) * source_event->button.device->num_axes);
11325
11326       if (type == GDK_BUTTON_PRESS)
11327         _gdk_event_button_generate (display, event);
11328       return TRUE;
11329
11330     case GDK_SCROLL:
11331       event->scroll.direction = source_event->scroll.direction;
11332       convert_toplevel_coords_to_window (event_win,
11333                                          toplevel_x, toplevel_y,
11334                                          &event->scroll.x, &event->scroll.y);
11335       event->scroll.x_root = source_event->scroll.x_root;
11336       event->scroll.y_root = source_event->scroll.y_root;
11337       event->scroll.state = state;
11338       event->scroll.device = source_event->scroll.device;
11339       return TRUE;
11340
11341     default:
11342       return FALSE;
11343     }
11344
11345   return TRUE; /* Always unlink original, we want to obey the emulated event mask */
11346 }
11347
11348 #ifdef DEBUG_WINDOW_PRINTING
11349 static void
11350 gdk_window_print (GdkWindowObject *window,
11351                   int indent)
11352 {
11353   GdkRectangle r;
11354   const char *window_types[] = {
11355     "root",
11356     "toplevel",
11357     "child",
11358     "dialog",
11359     "temp",
11360     "foreign",
11361     "offscreen"
11362   };
11363
11364   g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
11365            window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
11366            window->x, window->y,
11367            window->width, window->height
11368            );
11369
11370   if (gdk_window_has_impl (window))
11371     {
11372 #ifdef GDK_WINDOWING_X11
11373       g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
11374 #endif
11375     }
11376
11377   if (window->window_type != GDK_WINDOW_CHILD)
11378     g_print (" %s", window_types[window->window_type]);
11379
11380   if (window->input_only)
11381     g_print (" input-only");
11382
11383   if (window->shaped)
11384     g_print (" shaped");
11385
11386   if (!gdk_window_is_visible ((GdkWindow *)window))
11387     g_print (" hidden");
11388
11389   g_print (" abs[%d,%d]",
11390            window->abs_x, window->abs_y);
11391
11392   gdk_region_get_clipbox (window->clip_region, &r);
11393   if (gdk_region_empty (window->clip_region))
11394     g_print (" clipbox[empty]");
11395   else
11396     g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
11397
11398   g_print ("\n");
11399 }
11400
11401
11402 static void
11403 gdk_window_print_tree (GdkWindow *window,
11404                        int indent,
11405                        gboolean include_input_only)
11406 {
11407   GdkWindowObject *private;
11408   GList *l;
11409
11410   private = (GdkWindowObject *)window;
11411
11412   if (private->input_only && !include_input_only)
11413     return;
11414
11415   gdk_window_print (private, indent);
11416
11417   for (l = private->children; l != NULL; l = l->next)
11418     gdk_window_print_tree (l->data, indent + 4, include_input_only);
11419 }
11420
11421 #endif /* DEBUG_WINDOW_PRINTING */
11422
11423 void
11424 _gdk_windowing_got_event (GdkDisplay *display,
11425                           GList      *event_link,
11426                           GdkEvent   *event,
11427                           gulong      serial)
11428 {
11429   GdkWindow *event_window;
11430   GdkWindowObject *event_private;
11431   gdouble x, y;
11432   gboolean unlink_event;
11433   guint old_state, old_button;
11434   GdkDeviceGrabInfo *button_release_grab;
11435   GdkPointerWindowInfo *pointer_info;
11436   GdkDevice *device;
11437   gboolean is_toplevel;
11438
11439   if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
11440     display->last_event_time = gdk_event_get_time (event);
11441
11442   device = gdk_event_get_device (event);
11443
11444   if (device)
11445     {
11446       GdkInputMode mode;
11447
11448       g_object_get (device, "input-mode", &mode, NULL);
11449       _gdk_display_device_grab_update (display, device, serial);
11450
11451       if (mode == GDK_MODE_DISABLED ||
11452           !_gdk_display_check_grab_ownership (display, device, serial))
11453         {
11454           /* Device events are blocked by another
11455            * device grab, or the device is disabled
11456            */
11457           unlink_event = TRUE;
11458           goto out;
11459         }
11460     }
11461
11462   event_window = event->any.window;
11463   if (!event_window)
11464     return;
11465
11466   pointer_info = _gdk_display_get_pointer_info (display, device);
11467   event_private = GDK_WINDOW_OBJECT (event_window);
11468
11469 #ifdef DEBUG_WINDOW_PRINTING
11470   if (event->type == GDK_KEY_PRESS &&
11471       (event->key.keyval == 0xa7 ||
11472        event->key.keyval == 0xbd))
11473     {
11474       gdk_window_print_tree (event_window, 0,
11475                              event->key.keyval == 0xbd);
11476     }
11477 #endif
11478
11479   if (_gdk_native_windows)
11480     {
11481       if (event->type == GDK_BUTTON_PRESS &&
11482           !event->any.send_event &&
11483           _gdk_display_has_device_grab (display, device, serial) == NULL)
11484         {
11485           _gdk_display_add_device_grab  (display,
11486                                          device,
11487                                          event_window,
11488                                          event_window,
11489                                          GDK_OWNERSHIP_NONE,
11490                                          FALSE,
11491                                          gdk_window_get_events (event_window),
11492                                          serial,
11493                                          gdk_event_get_time (event),
11494                                          TRUE);
11495           _gdk_display_device_grab_update (display, device, serial);
11496         }
11497       if (event->type == GDK_BUTTON_RELEASE &&
11498           !event->any.send_event)
11499         {
11500           button_release_grab =
11501             _gdk_display_has_device_grab (display, device, serial);
11502           if (button_release_grab &&
11503               button_release_grab->implicit &&
11504               (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
11505             {
11506               button_release_grab->serial_end = serial;
11507               button_release_grab->implicit_ungrab = FALSE;
11508               _gdk_display_device_grab_update (display, device, serial);
11509             }
11510         }
11511
11512       if (event->type == GDK_BUTTON_PRESS)
11513         _gdk_event_button_generate (display, event);
11514
11515       return;
11516     }
11517
11518   if (event->type == GDK_VISIBILITY_NOTIFY)
11519     {
11520       event_private->native_visibility = event->visibility.state;
11521       gdk_window_update_visibility_recursively (event_private,
11522                                                 event_private);
11523       return;
11524     }
11525
11526   if (!(is_button_type (event->type) ||
11527         is_motion_type (event->type)) ||
11528       event_private->window_type == GDK_WINDOW_ROOT)
11529     return;
11530
11531   is_toplevel = gdk_window_is_toplevel (event_private);
11532
11533   if ((event->type == GDK_ENTER_NOTIFY ||
11534        event->type == GDK_LEAVE_NOTIFY) &&
11535       (event->crossing.mode == GDK_CROSSING_GRAB ||
11536        event->crossing.mode == GDK_CROSSING_UNGRAB) &&
11537       (_gdk_display_has_device_grab (display, device, serial) ||
11538        event->crossing.detail == GDK_NOTIFY_INFERIOR))
11539     {
11540       /* We synthesize all crossing events due to grabs ourselves,
11541        * so we ignore the native ones caused by our native pointer_grab
11542        * calls. Otherwise we would proxy these crossing event and cause
11543        * multiple copies of crossing events for grabs.
11544        *
11545        * We do want to handle grabs from other clients though, as for
11546        * instance alt-tab in metacity causes grabs like these and
11547        * we want to handle those. Thus the has_pointer_grab check.
11548        *
11549        * Implicit grabs on child windows create some grabbing events
11550        * that are sent before the button press. This means we can't
11551        * detect these with the has_pointer_grab check (as the implicit
11552        * grab is only noticed when we get button press event), so we
11553        * detect these events by checking for INFERIOR enter or leave
11554        * events. These should never be a problem to filter out.
11555        */
11556
11557       /* We ended up in this window after some (perhaps other clients)
11558          grab, so update the toplevel_under_window state */
11559       if (is_toplevel &&
11560           event->type == GDK_ENTER_NOTIFY &&
11561           event->crossing.mode == GDK_CROSSING_UNGRAB)
11562         {
11563           if (pointer_info->toplevel_under_pointer)
11564             g_object_unref (pointer_info->toplevel_under_pointer);
11565           pointer_info->toplevel_under_pointer = g_object_ref (event_window);
11566         }
11567
11568       unlink_event = TRUE;
11569       goto out;
11570     }
11571
11572   /* Track toplevel_under_pointer */
11573   if (is_toplevel)
11574     {
11575       if (event->type == GDK_ENTER_NOTIFY &&
11576           event->crossing.detail != GDK_NOTIFY_INFERIOR)
11577         {
11578           if (pointer_info->toplevel_under_pointer)
11579             g_object_unref (pointer_info->toplevel_under_pointer);
11580           pointer_info->toplevel_under_pointer = g_object_ref (event_window);
11581         }
11582       else if (event->type == GDK_LEAVE_NOTIFY &&
11583                event->crossing.detail != GDK_NOTIFY_INFERIOR &&
11584                pointer_info->toplevel_under_pointer == event_window)
11585         {
11586           if (pointer_info->toplevel_under_pointer)
11587             g_object_unref (pointer_info->toplevel_under_pointer);
11588           pointer_info->toplevel_under_pointer = NULL;
11589         }
11590     }
11591
11592   /* Store last pointer window and position/state */
11593   old_state = pointer_info->state;
11594   old_button = pointer_info->button;
11595
11596   gdk_event_get_coords (event, &x, &y);
11597   convert_native_coords_to_toplevel (event_window, x, y,  &x, &y);
11598   pointer_info->toplevel_x = x;
11599   pointer_info->toplevel_y = y;
11600   gdk_event_get_state (event, &pointer_info->state);
11601   if (event->type == GDK_BUTTON_PRESS ||
11602       event->type == GDK_BUTTON_RELEASE)
11603     pointer_info->button = event->button.button;
11604
11605   if (device &&
11606       (pointer_info->state != old_state ||
11607        pointer_info->button != old_button))
11608     _gdk_display_enable_motion_hints (display, device);
11609
11610   unlink_event = FALSE;
11611   if (is_motion_type (event->type))
11612     unlink_event = proxy_pointer_event (display,
11613                                         event,
11614                                         serial);
11615   else if (is_button_type (event->type))
11616     unlink_event = proxy_button_event (event,
11617                                        serial);
11618
11619   if (event->type == GDK_BUTTON_RELEASE &&
11620       !event->any.send_event)
11621     {
11622       button_release_grab =
11623         _gdk_display_has_device_grab (display, device, serial);
11624       if (button_release_grab &&
11625           button_release_grab->implicit &&
11626           (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
11627         {
11628           button_release_grab->serial_end = serial;
11629           button_release_grab->implicit_ungrab = FALSE;
11630           _gdk_display_device_grab_update (display, device, serial);
11631         }
11632     }
11633
11634  out:
11635   if (unlink_event)
11636     {
11637       _gdk_event_queue_remove_link (display, event_link);
11638       g_list_free_1 (event_link);
11639       gdk_event_free (event);
11640     }
11641 }
11642
11643
11644 static GdkWindow *
11645 get_extension_event_window (GdkDisplay                 *display,
11646                             GdkWindow                  *pointer_window,
11647                             GdkEventType                type,
11648                             gulong                      serial)
11649 {
11650   guint evmask;
11651   GdkWindow *grab_window;
11652   GdkWindowObject *w;
11653   GdkDeviceGrabInfo *grab;
11654
11655   /* FIXME: which device? */
11656   grab = _gdk_display_has_device_grab (display, display->core_pointer, serial);
11657
11658   if (grab != NULL && !grab->owner_events)
11659     {
11660       evmask = grab->event_mask;
11661
11662       grab_window = grab->window;
11663
11664       if (evmask & type_masks[type])
11665         return grab_window;
11666       else
11667         return NULL;
11668     }
11669
11670   w = (GdkWindowObject *)pointer_window;
11671   while (w != NULL)
11672     {
11673       evmask = w->extension_events;
11674
11675       if (evmask & type_masks[type])
11676         return (GdkWindow *)w;
11677
11678       w = get_event_parent (w);
11679     }
11680
11681   if (grab != NULL &&
11682       grab->owner_events)
11683     {
11684       evmask = grab->event_mask;
11685
11686       if (evmask & type_masks[type])
11687         return grab->window;
11688       else
11689         return NULL;
11690     }
11691
11692   return NULL;
11693 }
11694
11695
11696 GdkWindow *
11697 _gdk_window_get_input_window_for_event (GdkWindow *native_window,
11698                                         GdkEventType event_type,
11699                                         int x, int y,
11700                                         gulong serial)
11701 {
11702   GdkDisplay *display;
11703   GdkWindow *toplevel_window;
11704   GdkWindow *pointer_window;
11705   GdkWindow *event_win;
11706   gdouble toplevel_x, toplevel_y;
11707
11708   toplevel_x = x;
11709   toplevel_y = y;
11710
11711   display = gdk_drawable_get_display (native_window);
11712   toplevel_window = convert_native_coords_to_toplevel (native_window,
11713                                                        toplevel_x, toplevel_y,
11714                                                        &toplevel_x, &toplevel_y);
11715   /* FIXME: which device? */
11716   pointer_window = get_pointer_window (display, toplevel_window, NULL,
11717                                        toplevel_x, toplevel_y, serial);
11718   event_win = get_extension_event_window (display,
11719                                           pointer_window,
11720                                           event_type,
11721                                           serial);
11722
11723   return event_win;
11724 }
11725
11726
11727 #define __GDK_WINDOW_C__
11728 #include "gdkaliasdef.c"