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