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