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