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