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