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