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