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