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