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