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