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