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