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