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