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