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