1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3 * Josh MacDonald, Ryan Lortie
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.
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.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdkwindow.h"
32 #ifdef GDK_WINDOWING_X11
33 #include "x11/gdkx.h" /* For workaround */
37 #include "gdk.h" /* For gdk_rectangle_union() */
38 #include "gdkinternals.h"
40 #include "gdkscreen.h"
41 #include "gdkdeviceprivate.h"
42 #include "gdkdrawable.h"
43 #include "gdkmarshalers.h"
44 #include "gdkpixmap.h"
45 #include "gdkscreen.h"
46 #include "gdkwindowimpl.h"
48 #undef DEBUG_WINDOW_PRINTING
53 * @Short_description: Onscreen display areas in the target window system
56 * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
57 * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
58 * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
59 * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
60 * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
63 * <refsect2 id="COMPOSITED-WINDOWS">
64 * <title>Composited Windows</title>
66 * Normally, the windowing system takes care of rendering the contents of a
67 * child window onto its parent window. This mechanism can be intercepted by
68 * calling gdk_window_set_composited() on the child window. For a
69 * <firstterm>composited</firstterm> window it is the responsibility of the
70 * application to render the window contents at the right spot.
72 * <example id="composited-window-example">
73 * <title>Composited windows</title>
75 * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../examples/gdk/composited-window-example.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include>
76 * </programlisting></example>
78 * In the example <xref linkend="composited-window-example"/>, a button is
79 * placed inside of an event box inside of a window. The event box is set as
80 * composited and therefore is no longer automatically drawn to the screen.
82 * When the contents of the event box change, an expose event is generated on
83 * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
84 * The expose handler for this widget is responsible for merging the changes
85 * back on the screen in the way that it wishes.
87 * In our case, we merge the contents with a 50% transparency. We also set the
88 * background colour of the window to red. The effect is that the background
89 * shows through the button.
92 * <refsect2 id="OFFSCREEN-WINDOWS">
93 * <title>Offscreen Windows</title>
95 * Offscreen windows are more general than composited windows, since they allow
96 * not only to modify the rendering of the child window onto its parent, but
97 * also to apply coordinate transformations.
99 * To integrate an offscreen window into a window hierarchy, one has to call
100 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
101 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
102 * select an offscreen child at given coordinates, and the
103 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
104 * offscreen window are used to translate coordinates between the embedder and
105 * the offscreen window.
107 * For rendering an offscreen window onto its embedder, the contents of the
108 * offscreen window are available as a pixmap, via
109 * gdk_offscreen_window_get_pixmap().
115 /* Historically a GdkWindow always matches a platform native window,
116 * be it a toplevel window or a child window. In this setup the
117 * GdkWindow (and other GdkDrawables) were platform independent classes,
118 * and the actual platform specific implementation was in a delegate
119 * object availible as "impl" in the window object.
121 * With the addition of client side windows and offscreen windows this
122 * changes a bit. The application-visible GdkWindow object behaves as
123 * it did before, but not all such windows now have a corresponding native
124 * window. Instead windows that are "client side" are emulated by the gdk
125 * code such that clipping, drawing, moving, events etc work as expected.
127 * For GdkWindows that have a native window the "impl" object is the
128 * same as before. However, for all client side windows the impl object
129 * is shared with its parent (i.e. all client windows descendants of one
130 * native window has the same impl.
132 * Additionally there is a new type of platform independent impl object,
133 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
134 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
135 * windows). Such windows work by allocating a GdkPixmap as the backing store
136 * for drawing operations, which is resized with the window.
138 * GdkWindows have a pointer to the "impl window" they are in, i.e.
139 * the topmost GdkWindow which have the same "impl" value. This is stored
140 * in impl_window, which is different from the window itself only for client
142 * All GdkWindows (native or not) track the position of the window in the parent
143 * (x, y), the size of the window (width, height), the position of the window
144 * with respect to the impl window (abs_x, abs_y). We also track the clip
145 * region of the window wrt parent windows and siblings, in window-relative
146 * coordinates with and without child windows included (clip_region,
147 * clip_region_with_children).
149 * All toplevel windows are native windows, but also child windows can be
150 * native (although not children of offscreens). We always listen to
151 * a basic set of events (see get_native_event_mask) for these windows
152 * so that we can emulate events for any client side children.
154 * For native windows we apply the calculated clip region as a window shape
155 * so that eg. client side siblings that overlap the native child properly
156 * draws over the native child window.
158 * In order to minimize flicker and for performance we use a couple of cacheing
159 * tricks. First of all, every time we do a window to window copy area, for instance
160 * when moving a client side window or when scrolling/moving a region in a window
161 * we store this in outstanding_moves instead of applying immediately. We then
162 * delay this move until we really need it (because something depends on being
163 * able to read it), or until we're handing a redraw from an expose/invalidation
164 * (actually we delay it past redraw, but before blitting the double buffer pixmap
165 * to the window). This gives us two advantages. First of all it minimizes the time
166 * from the window is moved to the exposes related to that move, secondly it allows
167 * us to be smart about how to do the copy. We combine multiple moves into one (when
168 * possible) and we don't actually do copies to anything that is or will be
169 * invalidated and exposed anyway.
171 * Secondly, we use something called a "implicit paint" during repaint handling.
172 * An implicit paint is similar to a regular paint for the paint stack, but it is
173 * not put on the stack. Instead, it is set on the impl window, and later when
174 * regular gdk_window_begin_paint_region() happen on a window of this impl window
175 * we reuse the pixmap from the implicit paint. During repaint we create and at the
176 * end flush an implicit paint, which means we can collect all the paints on
177 * multiple client side windows in the same backing store pixmap.
180 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
182 /* This adds a local value to the GdkVisibilityState enum */
183 #define GDK_VISIBILITY_NOT_VIEWABLE 3
186 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
199 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
203 struct _GdkWindowPaint
205 cairo_region_t *region;
206 cairo_surface_t *surface;
207 guint uses_implicit : 1;
213 cairo_region_t *dest_region; /* The destination region */
214 int dx, dy; /* The amount that the source was moved to reach dest_region */
215 } GdkWindowRegionMove;
219 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
220 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
223 static void gdk_window_drop_cairo_surface (GdkWindowObject *private);
224 static void gdk_window_set_cairo_clip (GdkDrawable *drawable,
227 static void gdk_window_real_get_size (GdkDrawable *drawable,
231 static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable);
232 static gint gdk_window_real_get_depth (GdkDrawable *drawable);
233 static GdkScreen* gdk_window_real_get_screen (GdkDrawable *drawable);
234 static void gdk_window_real_set_colormap (GdkDrawable *drawable,
236 static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
238 static GdkDrawable* gdk_window_get_source_drawable (GdkDrawable *drawable);
240 static cairo_region_t* gdk_window_get_clip_region (GdkDrawable *drawable);
241 static cairo_region_t* gdk_window_get_visible_region (GdkDrawable *drawable);
243 static void gdk_window_free_paint_stack (GdkWindow *window);
245 static void gdk_window_init (GdkWindowObject *window);
246 static void gdk_window_class_init (GdkWindowObjectClass *klass);
247 static void gdk_window_finalize (GObject *object);
249 static void gdk_window_set_property (GObject *object,
253 static void gdk_window_get_property (GObject *object,
258 static void gdk_window_clear_backing_region (GdkWindow *window,
259 cairo_region_t *region);
261 static void recompute_visible_regions (GdkWindowObject *private,
262 gboolean recalculate_siblings,
263 gboolean recalculate_children);
264 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
265 static void gdk_window_flush_recursive (GdkWindowObject *window);
266 static void do_move_region_bits_on_impl (GdkWindowObject *private,
267 cairo_region_t *region, /* In impl window coords */
269 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
270 static void move_native_children (GdkWindowObject *private);
271 static void update_cursor (GdkDisplay *display,
273 static void impl_window_add_update_area (GdkWindowObject *impl_window,
274 cairo_region_t *region);
275 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
276 static void gdk_window_invalidate_region_full (GdkWindow *window,
277 const cairo_region_t *region,
278 gboolean invalidate_children,
280 static void gdk_window_invalidate_rect_full (GdkWindow *window,
281 const GdkRectangle *rect,
282 gboolean invalidate_children,
285 static guint signals[LAST_SIGNAL] = { 0 };
287 static gpointer parent_class = NULL;
289 static const cairo_user_data_key_t gdk_window_cairo_key;
292 new_region_tag (void)
294 static guint32 tag = 0;
300 gdk_window_object_get_type (void)
302 static GType object_type = 0;
305 object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
307 sizeof (GdkWindowObjectClass),
308 (GClassInitFunc) gdk_window_class_init,
309 sizeof (GdkWindowObject),
310 (GInstanceInitFunc) gdk_window_init,
317 _gdk_paintable_get_type (void)
319 static GType paintable_type = 0;
323 const GTypeInfo paintable_info =
325 sizeof (GdkPaintableIface), /* class_size */
326 NULL, /* base_init */
327 NULL, /* base_finalize */
330 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
331 g_intern_static_string ("GdkPaintable"),
334 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
337 return paintable_type;
341 gdk_window_init (GdkWindowObject *window)
343 /* 0-initialization is good for all other fields. */
345 window->window_type = GDK_WINDOW_CHILD;
347 window->state = GDK_WINDOW_STATE_WITHDRAWN;
350 window->toplevel_window_type = -1;
352 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
353 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
354 /* Default to unobscured since some backends don't send visibility events */
355 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
358 /* Stop and return on the first non-NULL parent */
360 accumulate_get_window (GSignalInvocationHint *ihint,
362 const GValue *handler_return,
365 g_value_copy (handler_return, return_accu);
366 /* Continue while returning NULL */
367 return g_value_get_object (handler_return) == NULL;
370 static GQuark quark_pointer_window = 0;
373 gdk_window_class_init (GdkWindowObjectClass *klass)
375 GObjectClass *object_class = G_OBJECT_CLASS (klass);
376 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
378 parent_class = g_type_class_peek_parent (klass);
380 object_class->finalize = gdk_window_finalize;
381 object_class->set_property = gdk_window_set_property;
382 object_class->get_property = gdk_window_get_property;
384 drawable_class->get_depth = gdk_window_real_get_depth;
385 drawable_class->get_screen = gdk_window_real_get_screen;
386 drawable_class->get_size = gdk_window_real_get_size;
387 drawable_class->set_colormap = gdk_window_real_set_colormap;
388 drawable_class->get_colormap = gdk_window_real_get_colormap;
389 drawable_class->get_visual = gdk_window_real_get_visual;
390 drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
391 drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
392 drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
393 drawable_class->get_clip_region = gdk_window_get_clip_region;
394 drawable_class->get_visible_region = gdk_window_get_visible_region;
395 drawable_class->get_source_drawable = gdk_window_get_source_drawable;
397 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
405 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
406 * gdk_window_get_cursor() for details.
410 g_object_class_install_property (object_class,
412 g_param_spec_boxed ("cursor",
419 * GdkWindow::pick-embedded-child:
420 * @window: the window on which the signal is emitted
421 * @x: x coordinate in the window
422 * @y: y coordinate in the window
424 * The ::pick-embedded-child signal is emitted to find an embedded
425 * child at the given position.
427 * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
431 signals[PICK_EMBEDDED_CHILD] =
432 g_signal_new (g_intern_static_string ("pick-embedded-child"),
433 G_OBJECT_CLASS_TYPE (object_class),
436 accumulate_get_window, NULL,
437 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
444 * GdkWindow::to-embedder:
445 * @window: the offscreen window on which the signal is emitted
446 * @offscreen-x: x coordinate in the offscreen window
447 * @offscreen-y: y coordinate in the offscreen window
448 * @embedder-x: return location for the x coordinate in the embedder window
449 * @embedder-y: return location for the y coordinate in the embedder window
451 * The ::to-embedder signal is emitted to translate coordinates
452 * in an offscreen window to its embedder.
454 * See also #GtkWindow::from-embedder.
458 signals[TO_EMBEDDER] =
459 g_signal_new (g_intern_static_string ("to-embedder"),
460 G_OBJECT_CLASS_TYPE (object_class),
464 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
473 * GdkWindow::from-embedder:
474 * @window: the offscreen window on which the signal is emitted
475 * @embedder-x: x coordinate in the embedder window
476 * @embedder-y: y coordinate in the embedder window
477 * @offscreen-x: return location for the x coordinate in the offscreen window
478 * @offscreen-y: return location for the y coordinate in the offscreen window
480 * The ::from-embedder signal is emitted to translate coordinates
481 * in the embedder of an offscreen window to the offscreen window.
483 * See also #GtkWindow::to-embedder.
487 signals[FROM_EMBEDDER] =
488 g_signal_new (g_intern_static_string ("from-embedder"),
489 G_OBJECT_CLASS_TYPE (object_class),
493 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
503 device_removed_cb (GdkDeviceManager *device_manager,
507 GdkWindowObject *private;
509 private = (GdkWindowObject *) window;
511 private->devices_inside = g_list_remove (private->devices_inside, device);
512 g_hash_table_remove (private->device_cursor, device);
514 if (private->device_events)
515 g_hash_table_remove (private->device_events, device);
519 gdk_window_finalize (GObject *object)
521 GdkWindow *window = GDK_WINDOW (object);
522 GdkWindowObject *obj = (GdkWindowObject *) object;
523 GdkDeviceManager *device_manager;
525 device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (window)));
526 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
528 if (!GDK_WINDOW_DESTROYED (window))
530 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
532 g_warning ("losing last reference to undestroyed window\n");
533 _gdk_window_destroy (window, FALSE);
536 /* We use TRUE here, to keep us from actually calling
537 * XDestroyWindow() on the window
539 _gdk_window_destroy (window, TRUE);
544 g_object_unref (obj->impl);
548 if (obj->impl_window != obj)
550 g_object_unref (obj->impl_window);
551 obj->impl_window = NULL;
555 cairo_region_destroy (obj->shape);
557 if (obj->input_shape)
558 cairo_region_destroy (obj->input_shape);
561 gdk_cursor_unref (obj->cursor);
563 if (obj->device_cursor)
564 g_hash_table_destroy (obj->device_cursor);
566 if (obj->device_events)
567 g_hash_table_destroy (obj->device_events);
569 if (obj->devices_inside)
570 g_list_free (obj->devices_inside);
572 G_OBJECT_CLASS (parent_class)->finalize (object);
576 gdk_window_set_property (GObject *object,
581 GdkWindow *window = (GdkWindow *)object;
586 gdk_window_set_cursor (window, g_value_get_boxed (value));
590 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
596 gdk_window_get_property (GObject *object,
601 GdkWindow *window = (GdkWindow *) object;
606 g_value_set_boxed (value, gdk_window_get_cursor (window));
610 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
616 gdk_window_is_offscreen (GdkWindowObject *window)
618 return window->window_type == GDK_WINDOW_OFFSCREEN;
621 static GdkWindowObject *
622 gdk_window_get_impl_window (GdkWindowObject *window)
624 return window->impl_window;
628 _gdk_window_get_impl_window (GdkWindow *window)
630 return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
634 gdk_window_has_impl (GdkWindowObject *window)
636 return window->impl_window == window;
640 gdk_window_is_toplevel (GdkWindowObject *window)
643 window->parent == NULL ||
644 window->parent->window_type == GDK_WINDOW_ROOT;
648 _gdk_window_has_impl (GdkWindow *window)
650 return gdk_window_has_impl ((GdkWindowObject *)window);
654 gdk_window_has_no_impl (GdkWindowObject *window)
656 return window->impl_window != window;
660 remove_child_area (GdkWindowObject *private,
661 GdkWindowObject *until,
663 cairo_region_t *region)
665 GdkWindowObject *child;
666 cairo_region_t *child_region;
669 cairo_region_t *shape;
671 for (l = private->children; l; l = l->next)
678 /* If region is empty already, no need to do
679 anything potentially costly */
680 if (cairo_region_is_empty (region))
683 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
686 /* Ignore offscreen children, as they don't draw in their parent and
687 * don't take part in the clipping */
688 if (gdk_window_is_offscreen (child))
693 r.width = child->width;
694 r.height = child->height;
696 /* Bail early if child totally outside region */
697 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
700 child_region = cairo_region_create_rectangle (&r);
704 /* Adjust shape region to parent window coords */
705 cairo_region_translate (child->shape, child->x, child->y);
706 cairo_region_intersect (child_region, child->shape);
707 cairo_region_translate (child->shape, -child->x, -child->y);
709 else if (private->window_type == GDK_WINDOW_FOREIGN)
711 shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
714 cairo_region_intersect (child_region, shape);
715 cairo_region_destroy (shape);
721 if (child->input_shape)
722 cairo_region_intersect (child_region, child->input_shape);
723 else if (private->window_type == GDK_WINDOW_FOREIGN)
725 shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
728 cairo_region_intersect (child_region, shape);
729 cairo_region_destroy (shape);
734 cairo_region_subtract (region, child_region);
735 cairo_region_destroy (child_region);
740 static GdkVisibilityState
741 effective_visibility (GdkWindowObject *private)
743 GdkVisibilityState native;
745 if (!gdk_window_is_viewable ((GdkWindow *)private))
746 return GDK_VISIBILITY_NOT_VIEWABLE;
748 native = private->impl_window->native_visibility;
750 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
751 private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
752 return GDK_VISIBILITY_FULLY_OBSCURED;
753 else if (native == GDK_VISIBILITY_UNOBSCURED)
754 return private->visibility;
755 else /* native PARTIAL, private partial or unobscured */
756 return GDK_VISIBILITY_PARTIAL;
760 gdk_window_update_visibility (GdkWindowObject *private)
762 GdkVisibilityState new_visibility;
765 new_visibility = effective_visibility (private);
767 if (new_visibility != private->effective_visibility)
769 private->effective_visibility = new_visibility;
771 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
772 private->event_mask & GDK_VISIBILITY_NOTIFY)
774 event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
776 event->visibility.state = new_visibility;
782 gdk_window_update_visibility_recursively (GdkWindowObject *private,
783 GdkWindowObject *only_for_impl)
785 GdkWindowObject *child;
788 gdk_window_update_visibility (private);
789 for (l = private->children; l != NULL; l = l->next)
792 if ((only_for_impl == NULL) ||
793 (only_for_impl == child->impl_window))
794 gdk_window_update_visibility_recursively (child, only_for_impl);
799 should_apply_clip_as_shape (GdkWindowObject *private)
802 gdk_window_has_impl (private) &&
803 /* Not for offscreens */
804 !gdk_window_is_offscreen (private) &&
805 /* or for toplevels */
806 !gdk_window_is_toplevel (private) &&
807 /* or for foreign windows */
808 private->window_type != GDK_WINDOW_FOREIGN &&
809 /* or for the root window */
810 private->window_type != GDK_WINDOW_ROOT;
814 apply_shape (GdkWindowObject *private,
815 cairo_region_t *region)
817 GdkWindowImplIface *impl_iface;
819 /* We trash whether we applied a shape so that
820 we can avoid unsetting it many times, which
821 could happen in e.g. apply_clip_as_shape as
822 windows get resized */
823 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
825 impl_iface->shape_combine_region ((GdkWindow *)private,
827 else if (private->applied_shape)
828 impl_iface->shape_combine_region ((GdkWindow *)private,
831 private->applied_shape = region != NULL;
835 region_rect_equal (const cairo_region_t *region,
836 const GdkRectangle *rect)
838 GdkRectangle extents;
840 if (cairo_region_num_rectangles (region) != 1)
843 cairo_region_get_extents (region, &extents);
845 return extents.x == rect->x &&
846 extents.y == rect->y &&
847 extents.width == rect->width &&
848 extents.height == rect->height;
852 apply_clip_as_shape (GdkWindowObject *private)
857 r.width = private->width;
858 r.height = private->height;
860 /* We only apply the clip region if would differ
861 from the actual clip region implied by the size
862 of the window. This is to avoid unneccessarily
863 adding meaningless shapes to all native subwindows */
864 if (!region_rect_equal (private->clip_region, &r))
865 apply_shape (private, private->clip_region);
867 apply_shape (private, NULL);
871 recompute_visible_regions_internal (GdkWindowObject *private,
872 gboolean recalculate_clip,
873 gboolean recalculate_siblings,
874 gboolean recalculate_children)
878 GdkWindowObject *child;
879 cairo_region_t *new_clip, *old_clip_region_with_children;
880 gboolean clip_region_changed;
881 gboolean abs_pos_changed;
882 int old_abs_x, old_abs_y;
884 old_abs_x = private->abs_x;
885 old_abs_y = private->abs_y;
887 /* Update absolute position */
888 if (gdk_window_has_impl (private))
890 /* Native window starts here */
896 private->abs_x = private->parent->abs_x + private->x;
897 private->abs_y = private->parent->abs_y + private->y;
901 private->abs_x != old_abs_x ||
902 private->abs_y != old_abs_y;
904 /* Update clip region based on:
907 * siblings in parents above window
909 clip_region_changed = FALSE;
910 if (recalculate_clip)
912 if (private->viewable)
914 /* Calculate visible region (sans children) in parent window coords */
917 r.width = private->width;
918 r.height = private->height;
919 new_clip = cairo_region_create_rectangle (&r);
921 if (!gdk_window_is_toplevel (private))
923 cairo_region_intersect (new_clip, private->parent->clip_region);
925 /* Remove all overlapping children from parent.
926 * Unless we're all native, because then we don't need to take
927 * siblings into account since X does that clipping for us.
928 * This makes things like SWT that modify the raw X stacking
929 * order without GDKs knowledge work.
931 if (!_gdk_native_windows)
932 remove_child_area (private->parent, private, FALSE, new_clip);
935 /* Convert from parent coords to window coords */
936 cairo_region_translate (new_clip, -private->x, -private->y);
939 cairo_region_intersect (new_clip, private->shape);
942 new_clip = cairo_region_create ();
944 if (private->clip_region == NULL ||
945 !cairo_region_equal (private->clip_region, new_clip))
946 clip_region_changed = TRUE;
948 if (private->clip_region)
949 cairo_region_destroy (private->clip_region);
950 private->clip_region = new_clip;
952 old_clip_region_with_children = private->clip_region_with_children;
953 private->clip_region_with_children = cairo_region_copy (private->clip_region);
954 if (private->window_type != GDK_WINDOW_ROOT)
955 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
957 if (clip_region_changed ||
958 !cairo_region_equal (private->clip_region_with_children, old_clip_region_with_children))
959 private->clip_tag = new_region_tag ();
961 if (old_clip_region_with_children)
962 cairo_region_destroy (old_clip_region_with_children);
965 if (clip_region_changed)
967 GdkVisibilityState visibility;
968 gboolean fully_visible;
970 if (cairo_region_is_empty (private->clip_region))
971 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
976 fully_visible = cairo_region_equal (private->clip_region,
983 r.width = private->width;
984 r.height = private->height;
985 fully_visible = region_rect_equal (private->clip_region, &r);
989 visibility = GDK_VISIBILITY_UNOBSCURED;
991 visibility = GDK_VISIBILITY_PARTIAL;
994 if (private->visibility != visibility)
996 private->visibility = visibility;
997 gdk_window_update_visibility (private);
1001 /* Update all children, recursively (except for root, where children are not exact). */
1002 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1003 private->window_type != GDK_WINDOW_ROOT)
1005 for (l = private->children; l; l = l->next)
1008 /* Only recalculate clip if the the clip region changed, otherwise
1009 * there is no way the child clip region could change (its has not e.g. moved)
1010 * Except if recalculate_children is set to force child updates
1012 recompute_visible_regions_internal (child,
1013 recalculate_clip && (clip_region_changed || recalculate_children),
1018 if (clip_region_changed &&
1019 should_apply_clip_as_shape (private))
1020 apply_clip_as_shape (private);
1022 if (recalculate_siblings &&
1023 !gdk_window_is_toplevel (private))
1025 /* If we moved a child window in parent or changed the stacking order, then we
1026 * need to recompute the visible area of all the other children in the parent
1028 for (l = private->parent->children; l; l = l->next)
1032 if (child != private)
1033 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1036 /* We also need to recompute the _with_children clip for the parent */
1037 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1040 if (private->cairo_surface &&
1041 (!gdk_window_has_impl (private) ||
1042 !_gdk_windowing_set_cairo_surface_size (private->cairo_surface,
1046 cairo_surface_destroy (private->cairo_surface);
1047 private->cairo_surface = NULL;
1051 /* Call this when private has changed in one or more of these ways:
1055 * stacking order of window changed
1058 * It will recalculate abs_x/y and the clip regions
1060 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1061 * for recalculate_siblings. (Mostly used internally for the recursion)
1063 * If a child window was removed (and you can't use that child for
1064 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1067 recompute_visible_regions (GdkWindowObject *private,
1068 gboolean recalculate_siblings,
1069 gboolean recalculate_children)
1071 recompute_visible_regions_internal (private,
1073 recalculate_siblings,
1074 recalculate_children);
1078 _gdk_window_update_size (GdkWindow *window)
1080 recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1083 /* Find the native window that would be just above "child"
1084 * in the native stacking order if "child" was a native window
1085 * (it doesn't have to be native). If there is no such native
1086 * window inside this native parent then NULL is returned.
1087 * If child is NULL, find lowest native window in parent.
1089 static GdkWindowObject *
1090 find_native_sibling_above_helper (GdkWindowObject *parent,
1091 GdkWindowObject *child)
1098 l = g_list_find (parent->children, child);
1099 g_assert (l != NULL); /* Better be a child of its parent... */
1100 l = l->prev; /* Start looking at the one above the child */
1103 l = g_list_last (parent->children);
1105 for (; l != NULL; l = l->prev)
1109 if (gdk_window_has_impl (w))
1112 g_assert (parent != w);
1113 w = find_native_sibling_above_helper (w, NULL);
1122 static GdkWindowObject *
1123 find_native_sibling_above (GdkWindowObject *parent,
1124 GdkWindowObject *child)
1128 w = find_native_sibling_above_helper (parent, child);
1132 if (gdk_window_has_impl (parent))
1135 return find_native_sibling_above (parent->parent, parent);
1139 get_native_device_event_mask (GdkWindowObject *private,
1142 GdkEventMask event_mask;
1145 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1147 event_mask = private->event_mask;
1149 if (_gdk_native_windows ||
1150 private->window_type == GDK_WINDOW_ROOT ||
1151 private->window_type == GDK_WINDOW_FOREIGN)
1157 /* Do whatever the app asks to, since the app
1158 * may be asking for weird things for native windows,
1159 * but don't use motion hints as that may affect non-native
1160 * child windows that don't want it. Also, we need to
1161 * set all the app-specified masks since they will be picked
1162 * up by any implicit grabs (i.e. if they were not set as
1163 * native we would not get the events we need). */
1164 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1166 /* We need thse for all native windows so we can
1167 emulate events on children: */
1170 GDK_VISIBILITY_NOTIFY_MASK |
1171 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1173 /* Additionally we select for pointer and button events
1174 * for toplevels as we need to get these to emulate
1175 * them for non-native subwindows. Even though we don't
1176 * select on them for all native windows we will get them
1177 * as the events are propagated out to the first window
1178 * that select for them.
1179 * Not selecting for button press on all windows is an
1180 * important thing, because in X only one client can do
1181 * so, and we don't want to unexpectedly prevent another
1182 * client from doing it.
1184 * We also need to do the same if the app selects for button presses
1185 * because then we will get implicit grabs for this window, and the
1186 * event mask used for that grab is based on the rest of the mask
1187 * for the window, but we might need more events than this window
1188 * lists due to some non-native child window.
1190 if (gdk_window_is_toplevel (private) ||
1191 mask & GDK_BUTTON_PRESS_MASK)
1193 GDK_POINTER_MOTION_MASK |
1194 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1202 get_native_grab_event_mask (GdkEventMask grab_mask)
1204 /* Similar to the above but for pointer events only */
1206 GDK_POINTER_MOTION_MASK |
1207 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1208 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1211 ~GDK_POINTER_MOTION_HINT_MASK);
1215 get_native_event_mask (GdkWindowObject *private)
1217 return get_native_device_event_mask (private, NULL);
1220 /* Puts the native window in the right order wrt the other native windows
1221 * in the hierarchy, given the position it has in the client side data.
1222 * This is useful if some operation changed the stacking order.
1223 * This calls assumes the native window is now topmost in its native parent.
1226 sync_native_window_stack_position (GdkWindow *window)
1228 GdkWindowObject *above;
1229 GdkWindowObject *private;
1230 GdkWindowImplIface *impl_iface;
1231 GList listhead = {0};
1233 private = (GdkWindowObject *) window;
1234 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1236 above = find_native_sibling_above (private->parent, private);
1239 listhead.data = window;
1240 impl_iface->restack_under ((GdkWindow *)above,
1247 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1248 * the default root window for the default display.
1249 * @attributes: attributes of the new window
1250 * @attributes_mask: mask indicating which fields in @attributes are valid
1252 * Creates a new #GdkWindow using the attributes from
1253 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1254 * more details. Note: to use this on displays other than the default
1255 * display, @parent must be specified.
1257 * Return value: (transfer none): the new #GdkWindow
1260 gdk_window_new (GdkWindow *parent,
1261 GdkWindowAttr *attributes,
1262 gint attributes_mask)
1265 GdkWindowObject *private;
1270 GdkEventMask event_mask;
1271 GdkWindow *real_parent;
1272 GdkDeviceManager *device_manager;
1274 g_return_val_if_fail (attributes != NULL, NULL);
1278 GDK_NOTE (MULTIHEAD,
1279 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1281 screen = gdk_screen_get_default ();
1282 parent = gdk_screen_get_root_window (screen);
1285 screen = gdk_drawable_get_screen (parent);
1287 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1289 if (GDK_WINDOW_DESTROYED (parent))
1291 g_warning ("gdk_window_new(): parent is destroyed\n");
1295 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1296 _gdk_native_windows)
1298 g_warning ("Offscreen windows not supported with native-windows gdk");
1302 window = g_object_new (GDK_TYPE_WINDOW, NULL);
1303 private = (GdkWindowObject *) window;
1305 /* Windows with a foreign parent are treated as if they are children
1306 * of the root window, except for actual creation.
1308 real_parent = parent;
1309 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1310 parent = gdk_screen_get_root_window (screen);
1312 private->parent = (GdkWindowObject *)parent;
1314 private->accept_focus = TRUE;
1315 private->focus_on_map = TRUE;
1317 if (attributes_mask & GDK_WA_X)
1322 if (attributes_mask & GDK_WA_Y)
1329 private->width = (attributes->width > 1) ? (attributes->width) : (1);
1330 private->height = (attributes->height > 1) ? (attributes->height) : (1);
1332 #ifdef GDK_WINDOWING_X11
1333 /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1334 * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1336 if (attributes->wclass == GDK_INPUT_ONLY &&
1337 private->parent->window_type == GDK_WINDOW_ROOT &&
1338 !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1340 g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1341 attributes->wclass = GDK_INPUT_OUTPUT;
1345 if (attributes->wclass == GDK_INPUT_ONLY)
1347 /* Backwards compatiblity - we've always ignored
1348 * attributes->window_type for input-only windows
1351 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1352 private->window_type = GDK_WINDOW_TEMP;
1354 private->window_type = GDK_WINDOW_CHILD;
1357 private->window_type = attributes->window_type;
1360 switch (private->window_type)
1362 case GDK_WINDOW_TOPLEVEL:
1363 case GDK_WINDOW_TEMP:
1364 case GDK_WINDOW_OFFSCREEN:
1365 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1366 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1367 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1368 case GDK_WINDOW_CHILD:
1372 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1376 if (attributes_mask & GDK_WA_VISUAL)
1377 visual = attributes->visual;
1379 visual = gdk_screen_get_system_visual (screen);
1381 private->event_mask = attributes->event_mask;
1383 if (attributes->wclass == GDK_INPUT_OUTPUT)
1385 private->input_only = FALSE;
1386 private->depth = visual->depth;
1388 /* XXX: Cache this somehow? */
1389 private->background = cairo_pattern_create_rgb (0, 0, 0);
1394 private->input_only = TRUE;
1397 if (private->parent)
1398 private->parent->children = g_list_prepend (private->parent->children, window);
1400 native = _gdk_native_windows; /* Default */
1401 if (private->parent->window_type == GDK_WINDOW_ROOT)
1402 native = TRUE; /* Always use native windows for toplevels */
1403 else if (!private->input_only &&
1404 ((attributes_mask & GDK_WA_COLORMAP &&
1405 attributes->colormap != gdk_drawable_get_colormap ((GdkDrawable *)private->parent)) ||
1406 (attributes_mask & GDK_WA_VISUAL &&
1407 attributes->visual != gdk_drawable_get_visual ((GdkDrawable *)private->parent))))
1408 native = TRUE; /* InputOutput window with different colormap or visual than parent, needs native window */
1410 if (gdk_window_is_offscreen (private))
1412 _gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask);
1413 private->impl_window = private;
1417 event_mask = get_native_event_mask (private);
1419 /* Create the impl */
1420 _gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask);
1421 private->impl_window = private;
1423 /* This will put the native window topmost in the native parent, which may
1424 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1425 if (!_gdk_window_has_impl (real_parent))
1426 sync_native_window_stack_position (window);
1430 private->impl_window = g_object_ref (private->parent->impl_window);
1431 private->impl = g_object_ref (private->impl_window->impl);
1434 recompute_visible_regions (private, TRUE, FALSE);
1436 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1437 (attributes->cursor) :
1440 private->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1441 (GDestroyNotify) gdk_cursor_unref);
1443 device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (parent)));
1444 g_signal_connect (device_manager, "device-removed",
1445 G_CALLBACK (device_removed_cb), window);
1451 is_parent_of (GdkWindow *parent,
1462 w = gdk_window_get_parent (w);
1469 change_impl (GdkWindowObject *private,
1470 GdkWindowObject *impl_window,
1474 GdkWindowObject *child;
1475 GdkDrawable *old_impl;
1476 GdkWindowObject *old_impl_window;
1478 old_impl = private->impl;
1479 old_impl_window = private->impl_window;
1480 if (private != impl_window)
1481 private->impl_window = g_object_ref (impl_window);
1483 private->impl_window = private;
1484 private->impl = g_object_ref (new);
1485 if (old_impl_window != private)
1486 g_object_unref (old_impl_window);
1487 g_object_unref (old_impl);
1489 for (l = private->children; l != NULL; l = l->next)
1493 if (child->impl == old_impl)
1494 change_impl (child, impl_window, new);
1499 reparent_to_impl (GdkWindowObject *private)
1502 GdkWindowObject *child;
1504 GdkWindowImplIface *impl_iface;
1506 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1508 /* Enumerate in reverse order so we get the right order for the native
1509 windows (first in childrens list is topmost, and reparent places on top) */
1510 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1514 if (child->impl == private->impl)
1515 reparent_to_impl (child);
1518 show = impl_iface->reparent ((GdkWindow *)child,
1519 (GdkWindow *)private,
1520 child->x, child->y);
1522 gdk_window_show_unraised ((GdkWindow *)child);
1529 * gdk_window_reparent:
1530 * @window: a #GdkWindow
1531 * @new_parent: new parent to move @window into
1532 * @x: X location inside the new parent
1533 * @y: Y location inside the new parent
1535 * Reparents @window into the given @new_parent. The window being
1536 * reparented will be unmapped as a side effect.
1540 gdk_window_reparent (GdkWindow *window,
1541 GdkWindow *new_parent,
1545 GdkWindowObject *private;
1546 GdkWindowObject *new_parent_private;
1547 GdkWindowObject *old_parent;
1549 gboolean show, was_mapped, applied_clip_as_shape;
1550 gboolean do_reparent_to_impl;
1551 GdkEventMask old_native_event_mask;
1552 GdkWindowImplIface *impl_iface;
1554 g_return_if_fail (GDK_IS_WINDOW (window));
1555 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1556 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1558 if (GDK_WINDOW_DESTROYED (window) ||
1559 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1562 screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
1564 new_parent = gdk_screen_get_root_window (screen);
1566 private = (GdkWindowObject *) window;
1567 new_parent_private = (GdkWindowObject *)new_parent;
1569 /* No input-output children of input-only windows */
1570 if (new_parent_private->input_only && !private->input_only)
1573 /* Don't create loops in hierarchy */
1574 if (is_parent_of (window, new_parent))
1577 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1578 To make sure we're ok, just wipe it. */
1579 gdk_window_drop_cairo_surface (private);
1581 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1582 old_parent = private->parent;
1584 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1587 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1588 if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1589 new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1590 gdk_window_ensure_native (window);
1592 applied_clip_as_shape = should_apply_clip_as_shape (private);
1594 old_native_event_mask = 0;
1595 do_reparent_to_impl = FALSE;
1596 if (gdk_window_has_impl (private))
1598 old_native_event_mask = get_native_event_mask (private);
1600 show = impl_iface->reparent (window, new_parent, x, y);
1604 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1605 g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1606 new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1609 gdk_window_hide (window);
1611 do_reparent_to_impl = TRUE;
1612 change_impl (private,
1613 new_parent_private->impl_window,
1614 new_parent_private->impl);
1617 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1620 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1622 new_parent = gdk_screen_get_root_window (screen);
1623 new_parent_private = (GdkWindowObject *)new_parent;
1627 old_parent->children = g_list_remove (old_parent->children, window);
1629 private->parent = new_parent_private;
1633 new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1635 /* Switch the window type as appropriate */
1637 switch (GDK_WINDOW_TYPE (new_parent))
1639 case GDK_WINDOW_ROOT:
1640 case GDK_WINDOW_FOREIGN:
1641 if (private->toplevel_window_type != -1)
1642 GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1643 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1644 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1646 case GDK_WINDOW_OFFSCREEN:
1647 case GDK_WINDOW_TOPLEVEL:
1648 case GDK_WINDOW_CHILD:
1649 case GDK_WINDOW_TEMP:
1650 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1651 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1653 /* Save the original window type so we can restore it if the
1654 * window is reparented back to be a toplevel
1656 private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1657 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1661 /* We might have changed window type for a native windows, so we
1662 need to change the event mask too. */
1663 if (gdk_window_has_impl (private))
1665 GdkEventMask native_event_mask = get_native_event_mask (private);
1667 if (native_event_mask != old_native_event_mask)
1668 impl_iface->set_events (window, native_event_mask);
1671 _gdk_window_update_viewable (window);
1673 recompute_visible_regions (private, TRUE, FALSE);
1674 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1675 recompute_visible_regions (old_parent, FALSE, TRUE);
1677 /* We used to apply the clip as the shape, but no more.
1678 Reset this to the real shape */
1679 if (gdk_window_has_impl (private) &&
1680 applied_clip_as_shape &&
1681 !should_apply_clip_as_shape (private))
1682 apply_shape (private, private->shape);
1684 if (do_reparent_to_impl)
1685 reparent_to_impl (private);
1688 /* The reparent will have put the native window topmost in the native parent,
1689 * which may be wrong wrt other native windows in the non-native hierarchy,
1691 if (!gdk_window_has_impl (new_parent_private))
1692 sync_native_window_stack_position (window);
1696 gdk_window_show_unraised (window);
1698 _gdk_synthesize_crossing_events_for_geometry_change (window);
1702 temporary_disable_extension_events (GdkWindowObject *window)
1704 GdkWindowObject *child;
1708 if (window->extension_events != 0)
1710 g_object_set_data (G_OBJECT (window),
1711 "gdk-window-extension-events",
1712 GINT_TO_POINTER (window->extension_events));
1713 gdk_input_set_extension_events ((GdkWindow *)window, 0,
1714 GDK_EXTENSION_EVENTS_NONE);
1719 for (l = window->children; l != NULL; l = l->next)
1723 if (window->impl_window == child->impl_window)
1724 res |= temporary_disable_extension_events (child);
1731 reenable_extension_events (GdkWindowObject *window)
1733 GdkWindowObject *child;
1737 mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1738 "gdk-window-extension-events"));
1742 /* We don't have the mode here, so we pass in cursor.
1743 This works with the current code since mode is not
1744 stored except as part of the mask, and cursor doesn't
1746 gdk_input_set_extension_events ((GdkWindow *)window, mask,
1747 GDK_EXTENSION_EVENTS_CURSOR);
1748 g_object_set_data (G_OBJECT (window),
1749 "gdk-window-extension-events",
1753 for (l = window->children; l != NULL; l = l->next)
1757 if (window->impl_window == child->impl_window)
1758 reenable_extension_events (window);
1763 * gdk_window_ensure_native:
1764 * @window: a #GdkWindow
1766 * Tries to ensure that there is a window-system native window for this
1767 * GdkWindow. This may fail in some situations, returning %FALSE.
1769 * Offscreen window and children of them can never have native windows.
1771 * Some backends may not support native child windows.
1773 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1778 gdk_window_ensure_native (GdkWindow *window)
1780 GdkWindowObject *private;
1781 GdkWindowObject *impl_window;
1782 GdkDrawable *new_impl, *old_impl;
1785 GdkWindowAttr attributes;
1786 GdkWindowObject *above;
1788 GdkWindowImplIface *impl_iface;
1789 gboolean disabled_extension_events;
1791 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1793 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1794 GDK_WINDOW_DESTROYED (window))
1797 private = (GdkWindowObject *) window;
1799 impl_window = gdk_window_get_impl_window (private);
1801 if (gdk_window_is_offscreen (impl_window))
1802 return FALSE; /* native in offscreens not supported */
1804 if (impl_window == private)
1805 /* Already has an impl, and its not offscreen . */
1808 /* Need to create a native window */
1810 /* First we disable any extension events on the window or its
1811 descendants to handle the native input window moving */
1812 disabled_extension_events = FALSE;
1813 if (impl_window->input_window)
1814 disabled_extension_events = temporary_disable_extension_events (private);
1816 gdk_window_drop_cairo_surface (private);
1818 screen = gdk_drawable_get_screen (window);
1819 visual = gdk_drawable_get_visual (window);
1821 attributes.colormap = gdk_drawable_get_colormap (window);
1823 old_impl = private->impl;
1824 _gdk_window_impl_new (window, (GdkWindow *)private->parent,
1826 get_native_event_mask (private),
1827 &attributes, GDK_WA_COLORMAP);
1828 new_impl = private->impl;
1830 private->impl = old_impl;
1831 change_impl (private, private, new_impl);
1833 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1835 /* Native window creation will put the native window topmost in the
1836 * native parent, which may be wrong wrt the position of the previous
1837 * non-native window wrt to the other non-native children, so correct this.
1839 above = find_native_sibling_above (private->parent, private);
1842 listhead.data = window;
1843 listhead.prev = NULL;
1844 listhead.next = NULL;
1845 impl_iface->restack_under ((GdkWindow *)above, &listhead);
1848 recompute_visible_regions (private, FALSE, FALSE);
1850 /* The shape may not have been set, as the clip region doesn't actually
1851 change, so do it here manually */
1852 if (should_apply_clip_as_shape (private))
1853 apply_clip_as_shape (private);
1855 reparent_to_impl (private);
1857 if (!private->input_only)
1859 impl_iface->set_background (window, private->background);
1862 impl_iface->input_shape_combine_region (window,
1863 private->input_shape,
1866 if (gdk_window_is_viewable (window))
1867 impl_iface->show (window, FALSE);
1869 if (disabled_extension_events)
1870 reenable_extension_events (private);
1876 window_remove_filters (GdkWindow *window)
1878 GdkWindowObject *obj = (GdkWindowObject*) window;
1884 for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
1885 g_free (tmp_list->data);
1887 g_list_free (obj->filters);
1888 obj->filters = NULL;
1893 update_pointer_info_foreach (GdkDisplay *display,
1895 GdkPointerWindowInfo *pointer_info,
1898 GdkWindow *window = user_data;
1900 if (pointer_info->toplevel_under_pointer == window)
1902 g_object_unref (pointer_info->toplevel_under_pointer);
1903 pointer_info->toplevel_under_pointer = NULL;
1908 window_remove_from_pointer_info (GdkWindow *window,
1909 GdkDisplay *display)
1911 _gdk_display_pointer_info_foreach (display,
1912 update_pointer_info_foreach,
1917 * _gdk_window_destroy_hierarchy:
1918 * @window: a #GdkWindow
1919 * @recursing: If TRUE, then this is being called because a parent
1921 * @recursing_native: If TRUE, then this is being called because a native parent
1922 * was destroyed. This generally means that the call to the
1923 * windowing system to destroy the window can be omitted, since
1924 * it will be destroyed as a result of the parent being destroyed.
1925 * Unless @foreign_destroy.
1926 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1927 * external agency. The window has already been destroyed and no
1928 * windowing system calls should be made. (This may never happen
1929 * for some windowing systems.)
1931 * Internal function to destroy a window. Like gdk_window_destroy(),
1932 * but does not drop the reference count created by gdk_window_new().
1935 _gdk_window_destroy_hierarchy (GdkWindow *window,
1937 gboolean recursing_native,
1938 gboolean foreign_destroy)
1940 GdkWindowObject *private;
1941 GdkWindowObject *temp_private;
1942 GdkWindowImplIface *impl_iface;
1943 GdkWindow *temp_window;
1945 GdkDisplay *display;
1949 g_return_if_fail (GDK_IS_WINDOW (window));
1951 private = (GdkWindowObject*) window;
1953 if (GDK_WINDOW_DESTROYED (window))
1956 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
1957 screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
1958 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1959 if (temp_window == window)
1960 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1963 switch (private->window_type)
1965 case GDK_WINDOW_ROOT:
1966 if (!screen->closed)
1968 g_error ("attempted to destroy root window");
1971 /* else fall thru */
1972 case GDK_WINDOW_TOPLEVEL:
1973 case GDK_WINDOW_CHILD:
1974 case GDK_WINDOW_TEMP:
1975 case GDK_WINDOW_FOREIGN:
1976 case GDK_WINDOW_OFFSCREEN:
1977 if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
1979 /* Logically, it probably makes more sense to send
1980 * a "destroy yourself" message to the foreign window
1981 * whether or not it's in our hierarchy; but for historical
1982 * reasons, we only send "destroy yourself" messages to
1983 * foreign windows in our hierarchy.
1985 if (private->parent)
1986 _gdk_windowing_window_destroy_foreign (window);
1988 /* Also for historical reasons, we remove any filters
1989 * on a foreign window when it or a parent is destroyed;
1990 * this likely causes problems if two separate portions
1991 * of code are maintaining filter lists on a foreign window.
1993 window_remove_filters (window);
1997 if (private->parent)
1999 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
2001 if (parent_private->children)
2002 parent_private->children = g_list_remove (parent_private->children, window);
2005 GDK_WINDOW_IS_MAPPED (window))
2007 recompute_visible_regions (private, TRUE, FALSE);
2008 gdk_window_invalidate_in_parent (private);
2012 gdk_window_free_paint_stack (window);
2014 gdk_window_set_background_pattern (window, NULL);
2016 if (private->background)
2018 cairo_pattern_destroy (private->background);
2019 private->background = NULL;
2022 if (private->window_type == GDK_WINDOW_FOREIGN)
2023 g_assert (private->children == NULL);
2026 children = tmp = private->children;
2027 private->children = NULL;
2031 temp_window = tmp->data;
2034 temp_private = (GdkWindowObject*) temp_window;
2036 _gdk_window_destroy_hierarchy (temp_window,
2038 recursing_native || gdk_window_has_impl (private),
2042 g_list_free (children);
2045 _gdk_window_clear_update_area (window);
2047 gdk_window_drop_cairo_surface (private);
2049 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2051 if (gdk_window_has_impl (private))
2052 impl_iface->destroy (window, recursing_native,
2056 /* hide to make sure we repaint and break grabs */
2057 gdk_window_hide (window);
2060 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2061 private->parent = NULL;
2062 private->destroyed = TRUE;
2064 window_remove_filters (window);
2066 gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
2068 window_remove_from_pointer_info (window, display);
2070 if (private->clip_region)
2072 cairo_region_destroy (private->clip_region);
2073 private->clip_region = NULL;
2076 if (private->clip_region_with_children)
2078 cairo_region_destroy (private->clip_region_with_children);
2079 private->clip_region_with_children = NULL;
2082 if (private->outstanding_moves)
2084 g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2085 g_list_free (private->outstanding_moves);
2086 private->outstanding_moves = NULL;
2094 * _gdk_window_destroy:
2095 * @window: a #GdkWindow
2096 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2097 * external agency. The window has already been destroyed and no
2098 * windowing system calls should be made. (This may never happen
2099 * for some windowing systems.)
2101 * Internal function to destroy a window. Like gdk_window_destroy(),
2102 * but does not drop the reference count created by gdk_window_new().
2105 _gdk_window_destroy (GdkWindow *window,
2106 gboolean foreign_destroy)
2108 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2112 * gdk_window_destroy:
2113 * @window: a #GdkWindow
2115 * Destroys the window system resources associated with @window and decrements @window's
2116 * reference count. The window system resources for all children of @window are also
2117 * destroyed, but the children's reference counts are not decremented.
2119 * Note that a window will not be destroyed automatically when its reference count
2120 * reaches zero. You must call this function yourself before that happens.
2124 gdk_window_destroy (GdkWindow *window)
2126 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2127 g_object_unref (window);
2131 * gdk_window_set_user_data:
2132 * @window: a #GdkWindow
2133 * @user_data: user data
2135 * For most purposes this function is deprecated in favor of
2136 * g_object_set_data(). However, for historical reasons GTK+ stores
2137 * the #GtkWidget that owns a #GdkWindow as user data on the
2138 * #GdkWindow. So, custom widget implementations should use
2139 * this function for that. If GTK+ receives an event for a #GdkWindow,
2140 * and the user data for the window is non-%NULL, GTK+ will assume the
2141 * user data is a #GtkWidget, and forward the event to that widget.
2145 gdk_window_set_user_data (GdkWindow *window,
2148 g_return_if_fail (GDK_IS_WINDOW (window));
2150 ((GdkWindowObject*)window)->user_data = user_data;
2154 * gdk_window_get_user_data:
2155 * @window: a #GdkWindow
2156 * @data: return location for user data
2158 * Retrieves the user data for @window, which is normally the widget
2159 * that @window belongs to. See gdk_window_set_user_data().
2163 gdk_window_get_user_data (GdkWindow *window,
2166 g_return_if_fail (GDK_IS_WINDOW (window));
2168 *data = ((GdkWindowObject*)window)->user_data;
2172 * gdk_window_get_window_type:
2173 * @window: a #GdkWindow
2175 * Gets the type of the window. See #GdkWindowType.
2177 * Return value: type of window
2180 gdk_window_get_window_type (GdkWindow *window)
2182 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2184 return GDK_WINDOW_TYPE (window);
2188 * gdk_window_is_destroyed:
2189 * @window: a #GdkWindow
2191 * Check to see if a window is destroyed..
2193 * Return value: %TRUE if the window is destroyed
2198 gdk_window_is_destroyed (GdkWindow *window)
2200 return GDK_WINDOW_DESTROYED (window);
2204 to_embedder (GdkWindowObject *window,
2205 gdouble offscreen_x,
2206 gdouble offscreen_y,
2207 gdouble *embedder_x,
2208 gdouble *embedder_y)
2210 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2211 offscreen_x, offscreen_y,
2212 embedder_x, embedder_y);
2216 from_embedder (GdkWindowObject *window,
2219 gdouble *offscreen_x,
2220 gdouble *offscreen_y)
2222 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2223 embedder_x, embedder_y,
2224 offscreen_x, offscreen_y);
2228 * gdk_window_has_native:
2229 * @window: a #GdkWindow
2231 * Checks whether the window has a native window or not. Note that
2232 * you can use gdk_window_ensure_native() if a native window is needed.
2234 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2239 gdk_window_has_native (GdkWindow *window)
2243 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2245 w = GDK_WINDOW_OBJECT (window);
2247 return w->parent == NULL || w->parent->impl != w->impl;
2251 * gdk_window_get_position:
2252 * @window: a #GdkWindow
2253 * @x: X coordinate of window
2254 * @y: Y coordinate of window
2256 * Obtains the position of the window as reported in the
2257 * most-recently-processed #GdkEventConfigure. Contrast with
2258 * gdk_window_get_geometry() which queries the X server for the
2259 * current window position, regardless of which events have been
2260 * received or processed.
2262 * The position coordinates are relative to the window's parent window.
2266 gdk_window_get_position (GdkWindow *window,
2270 GdkWindowObject *obj;
2272 g_return_if_fail (GDK_IS_WINDOW (window));
2274 obj = (GdkWindowObject*) window;
2283 * gdk_window_get_parent:
2284 * @window: a #GdkWindow
2286 * Obtains the parent of @window, as known to GDK. Does not query the
2287 * X server; thus this returns the parent as passed to gdk_window_new(),
2288 * not the actual parent. This should never matter unless you're using
2289 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2290 * matter for toplevel windows, because the window manager may choose
2293 * Note that you should use gdk_window_get_effective_parent() when
2294 * writing generic code that walks up a window hierarchy, because
2295 * gdk_window_get_parent() will most likely not do what you expect if
2296 * there are offscreen windows in the hierarchy.
2298 * Return value: (transfer none): parent of @window
2301 gdk_window_get_parent (GdkWindow *window)
2303 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2305 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2309 * gdk_window_get_effective_parent:
2310 * @window: a #GdkWindow
2312 * Obtains the parent of @window, as known to GDK. Works like
2313 * gdk_window_get_parent() for normal windows, but returns the
2314 * window's embedder for offscreen windows.
2316 * See also: gdk_offscreen_window_get_embedder()
2318 * Return value: (transfer none): effective parent of @window
2323 gdk_window_get_effective_parent (GdkWindow *window)
2325 GdkWindowObject *obj;
2327 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2329 obj = (GdkWindowObject *)window;
2331 if (gdk_window_is_offscreen (obj))
2332 return gdk_offscreen_window_get_embedder (window);
2334 return (GdkWindow *) obj->parent;
2338 * gdk_window_get_toplevel:
2339 * @window: a #GdkWindow
2341 * Gets the toplevel window that's an ancestor of @window.
2343 * Any window type but %GDK_WINDOW_CHILD is considered a
2344 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2345 * has a root window as parent.
2347 * Note that you should use gdk_window_get_effective_toplevel() when
2348 * you want to get to a window's toplevel as seen on screen, because
2349 * gdk_window_get_toplevel() will most likely not do what you expect
2350 * if there are offscreen windows in the hierarchy.
2352 * Return value: (transfer none): the toplevel window containing @window
2355 gdk_window_get_toplevel (GdkWindow *window)
2357 GdkWindowObject *obj;
2359 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2361 obj = (GdkWindowObject *)window;
2363 while (obj->window_type == GDK_WINDOW_CHILD)
2365 if (gdk_window_is_toplevel (obj))
2370 return GDK_WINDOW (obj);
2374 * gdk_window_get_effective_toplevel:
2375 * @window: a #GdkWindow
2377 * Gets the toplevel window that's an ancestor of @window.
2379 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2380 * embedder as its parent, using gdk_window_get_effective_parent().
2382 * See also: gdk_offscreen_window_get_embedder()
2384 * Return value: (transfer none): the effective toplevel window containing @window
2389 gdk_window_get_effective_toplevel (GdkWindow *window)
2393 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2395 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2396 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2403 * gdk_window_get_children:
2404 * @window: a #GdkWindow
2406 * Gets the list of children of @window known to GDK.
2407 * This function only returns children created via GDK,
2408 * so for example it's useless when used with the root window;
2409 * it only returns windows an application created itself.
2411 * The returned list must be freed, but the elements in the
2414 * Return value: (transfer container) (element-type GdkWindow):
2415 * list of child windows inside @window
2418 gdk_window_get_children (GdkWindow *window)
2420 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2422 if (GDK_WINDOW_DESTROYED (window))
2425 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2429 * gdk_window_peek_children:
2430 * @window: a #GdkWindow
2432 * Like gdk_window_get_children(), but does not copy the list of
2433 * children, so the list does not need to be freed.
2435 * Return value: (transfer none) (element-type GdkWindow):
2436 * a reference to the list of child windows in @window
2439 gdk_window_peek_children (GdkWindow *window)
2441 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2443 if (GDK_WINDOW_DESTROYED (window))
2446 return GDK_WINDOW_OBJECT (window)->children;
2450 * gdk_window_add_filter:
2451 * @window: a #GdkWindow
2452 * @function: filter callback
2453 * @data: data to pass to filter callback
2455 * Adds an event filter to @window, allowing you to intercept events
2456 * before they reach GDK. This is a low-level operation and makes it
2457 * easy to break GDK and/or GTK+, so you have to know what you're
2458 * doing. Pass %NULL for @window to get all events for all windows,
2459 * instead of events for a specific window.
2461 * See gdk_display_add_client_message_filter() if you are interested
2462 * in X ClientMessage events.
2465 gdk_window_add_filter (GdkWindow *window,
2466 GdkFilterFunc function,
2469 GdkWindowObject *private;
2471 GdkEventFilter *filter;
2473 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2475 private = (GdkWindowObject*) window;
2476 if (private && GDK_WINDOW_DESTROYED (window))
2479 /* Filters are for the native events on the native window, so
2480 ensure there is a native window. */
2482 gdk_window_ensure_native (window);
2485 tmp_list = private->filters;
2487 tmp_list = _gdk_default_filters;
2491 filter = (GdkEventFilter *)tmp_list->data;
2492 if ((filter->function == function) && (filter->data == data))
2494 tmp_list = tmp_list->next;
2497 filter = g_new (GdkEventFilter, 1);
2498 filter->function = function;
2499 filter->data = data;
2502 private->filters = g_list_append (private->filters, filter);
2504 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2508 * gdk_window_remove_filter:
2509 * @window: a #GdkWindow
2510 * @function: previously-added filter function
2511 * @data: user data for previously-added filter function
2513 * Remove a filter previously added with gdk_window_add_filter().
2517 gdk_window_remove_filter (GdkWindow *window,
2518 GdkFilterFunc function,
2521 GdkWindowObject *private;
2522 GList *tmp_list, *node;
2523 GdkEventFilter *filter;
2525 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2527 private = (GdkWindowObject*) window;
2530 tmp_list = private->filters;
2532 tmp_list = _gdk_default_filters;
2536 filter = (GdkEventFilter *)tmp_list->data;
2538 tmp_list = tmp_list->next;
2540 if ((filter->function == function) && (filter->data == data))
2543 private->filters = g_list_remove_link (private->filters, node);
2545 _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
2546 g_list_free_1 (node);
2555 * gdk_screen_get_toplevel_windows:
2556 * @screen: The #GdkScreen where the toplevels are located.
2558 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2559 * A toplevel window is a child of the root window (see
2560 * gdk_get_default_root_window()).
2562 * The returned list should be freed with g_list_free(), but
2563 * its elements need not be freed.
2565 * Return value: (transfer container) (element-type GdkWindow):
2566 * list of toplevel windows, free with g_list_free()
2571 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2573 GdkWindow * root_window;
2574 GList *new_list = NULL;
2577 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2579 root_window = gdk_screen_get_root_window (screen);
2581 tmp_list = ((GdkWindowObject *)root_window)->children;
2584 GdkWindowObject *w = tmp_list->data;
2586 if (w->window_type != GDK_WINDOW_FOREIGN)
2587 new_list = g_list_prepend (new_list, w);
2588 tmp_list = tmp_list->next;
2595 * gdk_window_is_visible:
2596 * @window: a #GdkWindow
2598 * Checks whether the window has been mapped (with gdk_window_show() or
2599 * gdk_window_show_unraised()).
2601 * Return value: %TRUE if the window is mapped
2604 gdk_window_is_visible (GdkWindow *window)
2606 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2608 return GDK_WINDOW_IS_MAPPED (window);
2612 * gdk_window_is_viewable:
2613 * @window: a #GdkWindow
2615 * Check if the window and all ancestors of the window are
2616 * mapped. (This is not necessarily "viewable" in the X sense, since
2617 * we only check as far as we have GDK window parents, not to the root
2620 * Return value: %TRUE if the window is viewable
2623 gdk_window_is_viewable (GdkWindow *window)
2625 GdkWindowObject *private = (GdkWindowObject *)window;
2627 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2629 if (private->destroyed)
2632 return private->viewable;
2636 * gdk_window_get_state:
2637 * @window: a #GdkWindow
2639 * Gets the bitwise OR of the currently active window state flags,
2640 * from the #GdkWindowState enumeration.
2642 * Return value: window state bitfield
2645 gdk_window_get_state (GdkWindow *window)
2647 GdkWindowObject *private = (GdkWindowObject *)window;
2649 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2651 return private->state;
2655 /* This creates an empty "implicit" paint region for the impl window.
2656 * By itself this does nothing, but real paints to this window
2657 * or children of it can use this pixmap as backing to avoid allocating
2658 * multiple pixmaps for subwindow rendering. When doing so they
2659 * add to the region of the implicit paint region, which will be
2660 * pushed to the window when the implicit paint region is ended.
2661 * Such paints should not copy anything to the window on paint end, but
2662 * should rely on the implicit paint end.
2663 * The implicit paint will be automatically ended if someone draws
2664 * directly to the window or a child window.
2667 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2669 GdkWindowObject *private = (GdkWindowObject *)window;
2670 GdkWindowPaint *paint;
2672 g_assert (gdk_window_has_impl (private));
2674 if (_gdk_native_windows)
2675 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2677 if (GDK_IS_PAINTABLE (private->impl))
2678 return FALSE; /* Implementation does double buffering */
2680 if (private->paint_stack != NULL ||
2681 private->implicit_paint != NULL)
2682 return FALSE; /* Don't stack implicit paints */
2684 if (private->outstanding_surfaces != 0)
2685 return FALSE; /* May conflict with direct drawing to cairo surface */
2687 /* Never do implicit paints for foreign windows, they don't need
2688 * double buffer combination since they have no client side children,
2689 * and creating pixmaps for them is risky since they could disappear
2692 if (private->window_type == GDK_WINDOW_FOREIGN)
2695 paint = g_new (GdkWindowPaint, 1);
2696 paint->region = cairo_region_create (); /* Empty */
2697 paint->uses_implicit = FALSE;
2698 paint->flushed = FALSE;
2699 paint->surface = gdk_window_create_similar_surface (window,
2700 CAIRO_CONTENT_COLOR,
2701 MAX (rect->width, 1),
2702 MAX (rect->height, 1));
2703 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2705 private->implicit_paint = paint;
2710 /* Ensure that all content related to this (sub)window is pushed to the
2711 native region. If there is an active paint then that area is not
2712 pushed, in order to not show partially finished double buffers. */
2714 gdk_window_flush_implicit_paint (GdkWindow *window)
2716 GdkWindowObject *private = (GdkWindowObject *)window;
2717 GdkWindowObject *impl_window;
2718 GdkWindowPaint *paint;
2719 cairo_region_t *region;
2722 impl_window = gdk_window_get_impl_window (private);
2723 if (impl_window->implicit_paint == NULL)
2726 paint = impl_window->implicit_paint;
2727 paint->flushed = TRUE;
2728 region = cairo_region_copy (private->clip_region_with_children);
2730 /* Don't flush active double buffers, as that may show partially done
2732 for (list = private->paint_stack; list != NULL; list = list->next)
2734 GdkWindowPaint *tmp_paint = list->data;
2736 cairo_region_subtract (region, tmp_paint->region);
2739 cairo_region_translate (region, -private->abs_x, -private->abs_y);
2740 cairo_region_intersect (region, paint->region);
2742 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2746 /* Remove flushed region from the implicit paint */
2747 cairo_region_subtract (paint->region, region);
2749 /* Some regions are valid, push these to window now */
2750 cr = gdk_cairo_create (private->impl);
2751 gdk_cairo_region (cr, region);
2753 cairo_set_source_surface (cr, paint->surface, 0, 0);
2754 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2759 cairo_region_destroy (region);
2762 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2764 gdk_window_end_implicit_paint (GdkWindow *window)
2766 GdkWindowObject *private = (GdkWindowObject *)window;
2767 GdkWindowPaint *paint;
2769 g_assert (gdk_window_has_impl (private));
2771 g_assert (private->implicit_paint != NULL);
2773 paint = private->implicit_paint;
2775 private->implicit_paint = NULL;
2777 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2781 /* Some regions are valid, push these to window now */
2782 cr = gdk_cairo_create (private->impl);
2783 gdk_cairo_region (cr, paint->region);
2785 cairo_set_source_surface (cr, paint->surface, 0, 0);
2786 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2791 cairo_region_destroy (paint->region);
2793 cairo_surface_destroy (paint->surface);
2798 * gdk_window_begin_paint_rect:
2799 * @window: a #GdkWindow
2800 * @rectangle: rectangle you intend to draw to
2802 * A convenience wrapper around gdk_window_begin_paint_region() which
2803 * creates a rectangular region for you. See
2804 * gdk_window_begin_paint_region() for details.
2808 gdk_window_begin_paint_rect (GdkWindow *window,
2809 const GdkRectangle *rectangle)
2811 cairo_region_t *region;
2813 g_return_if_fail (GDK_IS_WINDOW (window));
2815 region = cairo_region_create_rectangle (rectangle);
2816 gdk_window_begin_paint_region (window, region);
2817 cairo_region_destroy (region);
2821 * gdk_window_begin_paint_region:
2822 * @window: a #GdkWindow
2823 * @region: region you intend to draw to
2825 * Indicates that you are beginning the process of redrawing @region.
2826 * A backing store (offscreen buffer) large enough to contain @region
2827 * will be created. The backing store will be initialized with the
2828 * background color or background pixmap for @window. Then, all
2829 * drawing operations performed on @window will be diverted to the
2830 * backing store. When you call gdk_window_end_paint(), the backing
2831 * store will be copied to @window, making it visible onscreen. Only
2832 * the part of @window contained in @region will be modified; that is,
2833 * drawing operations are clipped to @region.
2835 * The net result of all this is to remove flicker, because the user
2836 * sees the finished product appear all at once when you call
2837 * gdk_window_end_paint(). If you draw to @window directly without
2838 * calling gdk_window_begin_paint_region(), the user may see flicker
2839 * as individual drawing operations are performed in sequence. The
2840 * clipping and background-initializing features of
2841 * gdk_window_begin_paint_region() are conveniences for the
2842 * programmer, so you can avoid doing that work yourself.
2844 * When using GTK+, the widget system automatically places calls to
2845 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2846 * emissions of the expose_event signal. That is, if you're writing an
2847 * expose event handler, you can assume that the exposed area in
2848 * #GdkEventExpose has already been cleared to the window background,
2849 * is already set as the clip region, and already has a backing store.
2850 * Therefore in most cases, application code need not call
2851 * gdk_window_begin_paint_region(). (You can disable the automatic
2852 * calls around expose events on a widget-by-widget basis by calling
2853 * gtk_widget_set_double_buffered().)
2855 * If you call this function multiple times before calling the
2856 * matching gdk_window_end_paint(), the backing stores are pushed onto
2857 * a stack. gdk_window_end_paint() copies the topmost backing store
2858 * onscreen, subtracts the topmost region from all other regions in
2859 * the stack, and pops the stack. All drawing operations affect only
2860 * the topmost backing store in the stack. One matching call to
2861 * gdk_window_end_paint() is required for each call to
2862 * gdk_window_begin_paint_region().
2866 gdk_window_begin_paint_region (GdkWindow *window,
2867 const cairo_region_t *region)
2869 #ifdef USE_BACKING_STORE
2870 GdkWindowObject *private = (GdkWindowObject *)window;
2871 GdkRectangle clip_box;
2872 GdkWindowPaint *paint, *implicit_paint;
2873 GdkWindowObject *impl_window;
2876 g_return_if_fail (GDK_IS_WINDOW (window));
2878 if (GDK_WINDOW_DESTROYED (window))
2881 if (GDK_IS_PAINTABLE (private->impl))
2883 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
2885 if (iface->begin_paint_region)
2886 iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
2891 impl_window = gdk_window_get_impl_window (private);
2892 implicit_paint = impl_window->implicit_paint;
2894 paint = g_new (GdkWindowPaint, 1);
2895 paint->region = cairo_region_copy (region);
2896 paint->region_tag = new_region_tag ();
2898 cairo_region_intersect (paint->region, private->clip_region_with_children);
2899 cairo_region_get_extents (paint->region, &clip_box);
2901 cairo_region_translate (paint->region, private->abs_x, private->abs_y);
2903 /* Mark the region as valid on the implicit paint */
2906 cairo_region_union (implicit_paint->region, paint->region);
2908 /* Convert back to normal coords */
2909 cairo_region_translate (paint->region, -private->abs_x, -private->abs_y);
2913 paint->uses_implicit = TRUE;
2914 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
2915 private->abs_x + clip_box.x,
2916 private->abs_y + clip_box.y,
2917 MAX (clip_box.width, 1),
2918 MAX (clip_box.height, 1));
2922 paint->uses_implicit = FALSE;
2923 paint->surface = gdk_window_create_similar_surface (window,
2924 CAIRO_CONTENT_COLOR,
2925 MAX (clip_box.width, 1),
2926 MAX (clip_box.height, 1));
2928 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
2930 for (list = private->paint_stack; list != NULL; list = list->next)
2932 GdkWindowPaint *tmp_paint = list->data;
2934 cairo_region_subtract (tmp_paint->region, paint->region);
2937 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
2939 if (!cairo_region_is_empty (paint->region))
2941 gdk_window_clear_backing_region (window,
2945 #endif /* USE_BACKING_STORE */
2949 * gdk_window_end_paint:
2950 * @window: a #GdkWindow
2952 * Indicates that the backing store created by the most recent call to
2953 * gdk_window_begin_paint_region() should be copied onscreen and
2954 * deleted, leaving the next-most-recent backing store or no backing
2955 * store at all as the active paint region. See
2956 * gdk_window_begin_paint_region() for full details. It is an error to
2957 * call this function without a matching
2958 * gdk_window_begin_paint_region() first.
2962 gdk_window_end_paint (GdkWindow *window)
2964 #ifdef USE_BACKING_STORE
2965 GdkWindowObject *private = (GdkWindowObject *)window;
2966 GdkWindowObject *composited;
2967 GdkWindowPaint *paint;
2968 GdkRectangle clip_box;
2969 cairo_region_t *full_clip;
2971 g_return_if_fail (GDK_IS_WINDOW (window));
2973 if (GDK_WINDOW_DESTROYED (window))
2976 if (GDK_IS_PAINTABLE (private->impl))
2978 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
2980 if (iface->end_paint)
2981 iface->end_paint ((GdkPaintable*)private->impl);
2985 if (private->paint_stack == NULL)
2987 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
2991 paint = private->paint_stack->data;
2993 private->paint_stack = g_slist_delete_link (private->paint_stack,
2994 private->paint_stack);
2996 cairo_region_get_extents (paint->region, &clip_box);
2998 if (!paint->uses_implicit)
3002 gdk_window_flush_outstanding_moves (window);
3004 full_clip = cairo_region_copy (private->clip_region_with_children);
3005 cairo_region_intersect (full_clip, paint->region);
3007 cr = gdk_cairo_create (private->impl);
3008 cairo_set_source_surface (cr, paint->surface, 0, 0);
3009 gdk_cairo_region (cr, full_clip);
3013 cairo_region_destroy (full_clip);
3016 cairo_surface_destroy (paint->surface);
3017 cairo_region_destroy (paint->region);
3020 /* find a composited window in our hierarchy to signal its
3021 * parent to redraw, calculating the clip box as we go...
3023 * stop if parent becomes NULL since then we'd have nowhere
3024 * to draw (ie: 'composited' will always be non-NULL here).
3026 for (composited = private;
3028 composited = composited->parent)
3032 gdk_drawable_get_size (GDK_DRAWABLE (composited->parent),
3035 clip_box.x += composited->x;
3036 clip_box.y += composited->y;
3037 clip_box.width = MIN (clip_box.width, width - clip_box.x);
3038 clip_box.height = MIN (clip_box.height, height - clip_box.y);
3040 if (composited->composited)
3042 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3047 #endif /* USE_BACKING_STORE */
3051 gdk_window_free_paint_stack (GdkWindow *window)
3053 GdkWindowObject *private = (GdkWindowObject *)window;
3055 if (private->paint_stack)
3057 GSList *tmp_list = private->paint_stack;
3061 GdkWindowPaint *paint = tmp_list->data;
3063 if (tmp_list == private->paint_stack)
3064 cairo_surface_destroy (paint->surface);
3066 cairo_region_destroy (paint->region);
3069 tmp_list = tmp_list->next;
3072 g_slist_free (private->paint_stack);
3073 private->paint_stack = NULL;
3078 do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3079 cairo_region_t *dest_region, /* In impl window coords */
3082 GdkWindowImplIface *impl_iface;
3084 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (impl_window->impl);
3086 impl_iface->translate ((GdkWindow *) impl_window, dest_region, dx, dy);
3089 static GdkWindowRegionMove *
3090 gdk_window_region_move_new (cairo_region_t *region,
3093 GdkWindowRegionMove *move;
3095 move = g_slice_new (GdkWindowRegionMove);
3096 move->dest_region = cairo_region_copy (region);
3104 gdk_window_region_move_free (GdkWindowRegionMove *move)
3106 cairo_region_destroy (move->dest_region);
3107 g_slice_free (GdkWindowRegionMove, move);
3111 append_move_region (GdkWindowObject *impl_window,
3112 cairo_region_t *new_dest_region,
3115 GdkWindowRegionMove *move, *old_move;
3116 cairo_region_t *new_total_region, *old_total_region;
3117 cairo_region_t *source_overlaps_destination;
3118 cairo_region_t *non_overwritten;
3119 gboolean added_move;
3122 if (cairo_region_is_empty (new_dest_region))
3125 /* In principle this could just append the move to the list of outstanding
3126 moves that will be replayed before drawing anything when we're handling
3127 exposes. However, we'd like to do a bit better since its commonly the case
3128 that we get multiple copies where A is copied to B and then B is copied
3129 to C, and we'd like to express this as a simple copy A to C operation. */
3131 /* We approach this by taking the new move and pushing it ahead of moves
3132 starting at the end of the list and stopping when its not safe to do so.
3133 It's not safe to push past a move if either the source of the new move
3134 is in the destination of the old move, or if the destination of the new
3135 move is in the source of the new move, or if the destination of the new
3136 move overlaps the destination of the old move. We simplify this by
3137 just comparing the total regions (src + dest) */
3138 new_total_region = cairo_region_copy (new_dest_region);
3139 cairo_region_translate (new_total_region, -dx, -dy);
3140 cairo_region_union (new_total_region, new_dest_region);
3143 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3148 old_total_region = cairo_region_copy (old_move->dest_region);
3149 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3150 cairo_region_union (old_total_region, old_move->dest_region);
3152 cairo_region_intersect (old_total_region, new_total_region);
3153 /* If these regions intersect then its not safe to push the
3154 new region before the old one */
3155 if (!cairo_region_is_empty (old_total_region))
3157 /* The area where the new moves source overlaps the old ones
3159 source_overlaps_destination = cairo_region_copy (new_dest_region);
3160 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3161 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3162 cairo_region_translate (source_overlaps_destination, dx, dy);
3164 /* We can do all sort of optimizations here, but to do things safely it becomes
3165 quite complicated. However, a very common case is that you copy something first,
3166 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3167 in the same direction). We'd like to detect this case and optimize it to one
3169 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3171 /* This means we might be able to replace the old move and the new one
3172 with the new one read from the old ones source, and a second copy of
3173 the non-overwritten parts of the old move. However, such a split
3174 is only valid if the source in the old move isn't overwritten
3175 by the destination of the new one */
3177 /* the new destination of old move if split is ok: */
3178 non_overwritten = cairo_region_copy (old_move->dest_region);
3179 cairo_region_subtract (non_overwritten, new_dest_region);
3180 /* move to source region */
3181 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3183 cairo_region_intersect (non_overwritten, new_dest_region);
3184 if (cairo_region_is_empty (non_overwritten))
3187 move = gdk_window_region_move_new (new_dest_region,
3191 impl_window->outstanding_moves =
3192 g_list_insert_before (impl_window->outstanding_moves,
3194 cairo_region_subtract (old_move->dest_region, new_dest_region);
3196 cairo_region_destroy (non_overwritten);
3199 cairo_region_destroy (source_overlaps_destination);
3200 cairo_region_destroy (old_total_region);
3203 cairo_region_destroy (old_total_region);
3206 cairo_region_destroy (new_total_region);
3210 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3213 impl_window->outstanding_moves =
3214 g_list_prepend (impl_window->outstanding_moves,
3217 impl_window->outstanding_moves =
3218 g_list_insert_before (impl_window->outstanding_moves,
3223 /* Moves bits and update area by dx/dy in impl window.
3224 Takes ownership of region to avoid copy (because we may change it) */
3226 move_region_on_impl (GdkWindowObject *impl_window,
3227 cairo_region_t *region, /* In impl window coords */
3230 if ((dx == 0 && dy == 0) ||
3231 cairo_region_is_empty (region))
3233 cairo_region_destroy (region);
3237 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3239 /* Move any old invalid regions in the copy source area by dx/dy */
3240 if (impl_window->update_area)
3242 cairo_region_t *update_area;
3244 update_area = cairo_region_copy (region);
3246 /* Convert from target to source */
3247 cairo_region_translate (update_area, -dx, -dy);
3248 cairo_region_intersect (update_area, impl_window->update_area);
3249 /* We only copy the area, so keep the old update area invalid.
3250 It would be safe to remove it too, as code that uses
3251 move_region_on_impl generally also invalidate the source
3252 area. However, it would just use waste cycles. */
3255 cairo_region_translate (update_area, dx, dy);
3256 cairo_region_union (impl_window->update_area, update_area);
3258 /* This area of the destination is now invalid,
3259 so no need to copy to it. */
3260 cairo_region_subtract (region, update_area);
3262 cairo_region_destroy (update_area);
3265 /* If we're currently exposing this window, don't copy to this
3266 destination, as it will be overdrawn when the expose is done,
3267 instead invalidate it and repaint later. */
3268 if (impl_window->implicit_paint)
3270 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3271 cairo_region_t *exposing;
3273 exposing = cairo_region_copy (implicit_paint->region);
3274 cairo_region_intersect (exposing, region);
3275 cairo_region_subtract (region, exposing);
3277 impl_window_add_update_area (impl_window, exposing);
3278 cairo_region_destroy (exposing);
3281 if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3282 append_move_region (impl_window, region, dx, dy);
3284 do_move_region_bits_on_impl (impl_window,
3287 cairo_region_destroy (region);
3290 /* Flushes all outstanding changes to the window, call this
3291 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3294 gdk_window_flush_outstanding_moves (GdkWindow *window)
3296 GdkWindowObject *private;
3297 GdkWindowObject *impl_window;
3298 GList *l, *outstanding;
3299 GdkWindowRegionMove *move;
3301 private = (GdkWindowObject *) window;
3303 impl_window = gdk_window_get_impl_window (private);
3304 outstanding = impl_window->outstanding_moves;
3305 impl_window->outstanding_moves = NULL;
3307 for (l = outstanding; l != NULL; l = l->next)
3311 do_move_region_bits_on_impl (impl_window,
3312 move->dest_region, move->dx, move->dy);
3314 gdk_window_region_move_free (move);
3317 g_list_free (outstanding);
3322 * @window: a #GdkWindow
3324 * Flush all outstanding cached operations on a window, leaving the
3325 * window in a state which reflects all that has been drawn before.
3327 * Gdk uses multiple kinds of caching to get better performance and
3328 * nicer drawing. For instance, during exposes all paints to a window
3329 * using double buffered rendering are keep on a pixmap until the last
3330 * window has been exposed. It also delays window moves/scrolls until
3331 * as long as possible until next update to avoid tearing when moving
3334 * Normally this should be completely invisible to applications, as
3335 * we automatically flush the windows when required, but this might
3336 * be needed if you for instance mix direct native drawing with
3337 * gdk drawing. For Gtk widgets that don't use double buffering this
3338 * will be called automatically before sending the expose event.
3343 gdk_window_flush (GdkWindow *window)
3345 gdk_window_flush_outstanding_moves (window);
3346 gdk_window_flush_implicit_paint (window);
3349 /* If we're about to move/resize or otherwise change the
3350 * hierarchy of a client side window in an impl and we're
3351 * called from an expose event handler then we need to
3352 * flush any already painted parts of the implicit paint
3353 * that are not part of the current paint, as these may
3354 * be used when scrolling or may overdraw the changes
3355 * caused by the hierarchy change.
3358 gdk_window_flush_if_exposing (GdkWindow *window)
3360 GdkWindowObject *private;
3361 GdkWindowObject *impl_window;
3363 private = (GdkWindowObject *) window;
3364 impl_window = gdk_window_get_impl_window (private);
3366 /* If we're in an implicit paint (i.e. in an expose handler, flush
3367 all the already finished exposes to get things to an uptodate state. */
3368 if (impl_window->implicit_paint)
3369 gdk_window_flush (window);
3374 gdk_window_flush_recursive_helper (GdkWindowObject *window,
3377 GdkWindowObject *child;
3380 for (l = window->children; l != NULL; l = l->next)
3384 if (child->impl == impl)
3385 /* Same impl, ignore */
3386 gdk_window_flush_recursive_helper (child, impl);
3388 gdk_window_flush_recursive (child);
3393 gdk_window_flush_recursive (GdkWindowObject *window)
3395 gdk_window_flush ((GdkWindow *)window);
3396 gdk_window_flush_recursive_helper (window, window->impl);
3399 static GdkDrawable *
3400 gdk_window_get_source_drawable (GdkDrawable *drawable)
3402 GdkWindow *window = GDK_WINDOW (drawable);
3403 GdkWindowObject *private;
3405 private = (GdkWindowObject *) window;
3406 if (GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable)
3407 return GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable (private->impl);
3412 static cairo_region_t*
3413 gdk_window_get_clip_region (GdkDrawable *drawable)
3415 GdkWindowObject *private = (GdkWindowObject *)drawable;
3416 cairo_region_t *result;
3418 result = cairo_region_copy (private->clip_region);
3420 if (private->paint_stack)
3422 cairo_region_t *paint_region = cairo_region_create ();
3423 GSList *tmp_list = private->paint_stack;
3427 GdkWindowPaint *paint = tmp_list->data;
3429 cairo_region_union (paint_region, paint->region);
3431 tmp_list = tmp_list->next;
3434 cairo_region_intersect (result, paint_region);
3435 cairo_region_destroy (paint_region);
3441 static cairo_region_t*
3442 gdk_window_get_visible_region (GdkDrawable *drawable)
3444 GdkWindowObject *private = (GdkWindowObject*) drawable;
3446 return cairo_region_copy (private->clip_region);
3450 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3452 GdkWindowObject *private = (GdkWindowObject *) window;
3453 GdkWindowObject *bg_private;
3454 cairo_pattern_t *pattern = NULL;
3455 int x_offset = 0, y_offset = 0;
3458 cr = cairo_create (paint->surface);
3460 for (bg_private = private; bg_private; bg_private = bg_private->parent)
3462 pattern = gdk_window_get_background_pattern ((GdkWindow *) bg_private);
3466 x_offset += bg_private->x;
3467 y_offset += bg_private->y;
3472 cairo_translate (cr, -x_offset, -y_offset);
3473 cairo_set_source (cr, pattern);
3474 cairo_translate (cr, x_offset, y_offset);
3477 cairo_set_source_rgb (cr, 0, 0, 0);
3483 gdk_window_clear_backing_region (GdkWindow *window,
3484 cairo_region_t *region)
3486 GdkWindowObject *private = (GdkWindowObject *)window;
3487 GdkWindowPaint *paint = private->paint_stack->data;
3488 cairo_region_t *clip;
3489 GdkRectangle clipbox;
3492 if (GDK_WINDOW_DESTROYED (window))
3495 cr = setup_backing_rect (window, paint, 0, 0);
3497 clip = cairo_region_copy (paint->region);
3498 cairo_region_intersect (clip, region);
3499 cairo_region_get_extents (clip, &clipbox);
3501 gdk_cairo_region (cr, clip);
3506 cairo_region_destroy (clip);
3510 gdk_window_clear_backing_region_direct (GdkWindow *window,
3511 cairo_region_t *region)
3513 GdkWindowObject *private = (GdkWindowObject *)window;
3514 GdkWindowPaint paint;
3515 cairo_region_t *clip;
3516 GdkRectangle clipbox;
3519 if (GDK_WINDOW_DESTROYED (window))
3522 paint.surface = _gdk_drawable_ref_cairo_surface (window);
3524 cr = setup_backing_rect (window, &paint, 0, 0);
3526 clip = cairo_region_copy (private->clip_region_with_children);
3527 cairo_region_intersect (clip, region);
3528 cairo_region_get_extents (clip, &clipbox);
3530 gdk_cairo_region (cr, clip);
3535 cairo_region_destroy (clip);
3536 cairo_surface_destroy (paint.surface);
3542 * @window: a #GdkWindow
3544 * Clears an entire @window to the background color or background pixmap.
3547 gdk_window_clear (GdkWindow *window)
3551 g_return_if_fail (GDK_IS_WINDOW (window));
3553 gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
3555 gdk_window_clear_area (window, 0, 0,
3560 gdk_window_clear_region_internal (GdkWindow *window,
3561 cairo_region_t *region)
3563 GdkWindowObject *private = (GdkWindowObject *)window;
3565 if (private->paint_stack)
3566 gdk_window_clear_backing_region (window, region);
3568 gdk_window_clear_backing_region_direct (window, region);
3572 * gdk_window_clear_area:
3573 * @window: a #GdkWindow
3574 * @x: x coordinate of rectangle to clear
3575 * @y: y coordinate of rectangle to clear
3576 * @width: width of rectangle to clear
3577 * @height: height of rectangle to clear
3579 * Clears an area of @window to the background color or background pixmap.
3583 gdk_window_clear_area (GdkWindow *window,
3590 cairo_region_t *region;
3592 g_return_if_fail (GDK_IS_WINDOW (window));
3594 if (GDK_WINDOW_DESTROYED (window))
3597 /* Terminate early to avoid weird interpretation of
3598 zero width/height by XClearArea */
3599 if (width == 0 || height == 0)
3605 rect.height = height;
3607 region = cairo_region_create_rectangle (&rect);
3608 gdk_window_clear_region_internal (window,
3610 cairo_region_destroy (region);
3614 gdk_window_real_get_size (GdkDrawable *drawable,
3618 GdkWindowObject *private = (GdkWindowObject *)drawable;
3621 *width = private->width;
3623 *height = private->height;
3627 gdk_window_real_get_visual (GdkDrawable *drawable)
3629 GdkColormap *colormap;
3631 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
3633 colormap = gdk_drawable_get_colormap (drawable);
3634 return colormap ? gdk_colormap_get_visual (colormap) : NULL;
3638 gdk_window_real_get_depth (GdkDrawable *drawable)
3640 g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
3642 return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
3646 gdk_window_real_get_screen (GdkDrawable *drawable)
3648 return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
3652 gdk_window_real_set_colormap (GdkDrawable *drawable,
3655 GdkWindowObject *private;
3657 g_return_if_fail (GDK_IS_WINDOW (drawable));
3659 if (GDK_WINDOW_DESTROYED (drawable))
3662 private = (GdkWindowObject *)drawable;
3664 /* different colormap than parent, requires native window */
3665 if (!private->input_only &&
3666 cmap != gdk_drawable_get_colormap ((GdkDrawable *)(private->parent)))
3667 gdk_window_ensure_native ((GdkWindow *)drawable);
3669 gdk_drawable_set_colormap (private->impl, cmap);
3673 gdk_window_real_get_colormap (GdkDrawable *drawable)
3675 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
3677 if (GDK_WINDOW_DESTROYED (drawable))
3680 return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
3684 gdk_window_drop_cairo_surface (GdkWindowObject *private)
3686 if (private->cairo_surface)
3688 cairo_surface_finish (private->cairo_surface);
3689 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3695 gdk_window_cairo_surface_destroy (void *data)
3697 GdkWindowObject *private = (GdkWindowObject*) data;
3699 private->cairo_surface = NULL;
3700 private->impl_window->outstanding_surfaces--;
3703 static cairo_surface_t *
3704 gdk_window_create_cairo_surface (GdkDrawable *drawable,
3708 GdkWindowObject *private = GDK_WINDOW_OBJECT(drawable);
3709 cairo_surface_t *surface, *subsurface;
3711 surface =_gdk_drawable_ref_cairo_surface (private->impl);
3712 if (gdk_window_has_impl (private))
3715 subsurface = cairo_surface_create_for_rectangle (surface,
3720 cairo_surface_destroy (surface);
3725 static cairo_surface_t *
3726 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
3728 GdkWindowObject *private = (GdkWindowObject*) drawable;
3729 cairo_surface_t *surface;
3731 if (private->paint_stack)
3733 GdkWindowPaint *paint = private->paint_stack->data;
3735 surface = paint->surface;
3736 cairo_surface_reference (surface);
3741 /* This will be drawing directly to the window, so flush implicit paint */
3742 gdk_window_flush ((GdkWindow *)drawable);
3744 if (!private->cairo_surface)
3746 private->cairo_surface = _gdk_drawable_create_cairo_surface (drawable,
3750 if (private->cairo_surface)
3752 private->impl_window->outstanding_surfaces++;
3754 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3755 drawable, gdk_window_cairo_surface_destroy);
3759 cairo_surface_reference (private->cairo_surface);
3761 surface = private->cairo_surface;
3768 gdk_window_set_cairo_clip (GdkDrawable *drawable,
3771 GdkWindowObject *private = (GdkWindowObject*) drawable;
3773 if (!private->paint_stack)
3775 cairo_reset_clip (cr);
3778 cairo_identity_matrix (cr);
3780 cairo_new_path (cr);
3781 gdk_cairo_region (cr, private->clip_region_with_children);
3788 GdkWindowPaint *paint = private->paint_stack->data;
3790 /* Only needs to clip to region if piggybacking
3791 on an implicit paint pixmap */
3792 cairo_reset_clip (cr);
3793 if (paint->uses_implicit)
3796 cairo_identity_matrix (cr);
3798 cairo_new_path (cr);
3799 gdk_cairo_region (cr, paint->region);
3807 /* Code for dirty-region queueing
3809 static GSList *update_windows = NULL;
3810 static guint update_idle = 0;
3811 static gboolean debug_updates = FALSE;
3813 static inline gboolean
3814 gdk_window_is_ancestor (GdkWindow *window,
3815 GdkWindow *ancestor)
3819 GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
3821 if (parent == ancestor)
3831 gdk_window_add_update_window (GdkWindow *window)
3834 GSList *prev = NULL;
3835 gboolean has_ancestor_in_list = FALSE;
3837 for (tmp = update_windows; tmp; tmp = tmp->next)
3839 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
3841 /* check if tmp is an ancestor of "window"; if it is, set a
3842 * flag indicating that all following windows are either
3843 * children of "window" or from a differen hierarchy
3845 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3846 has_ancestor_in_list = TRUE;
3848 /* insert in reverse stacking order when adding around siblings,
3849 * so processing updates properly paints over lower stacked windows
3851 if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
3853 gint index = g_list_index (parent->children, window);
3854 for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
3856 gint sibling_index = g_list_index (parent->children, tmp->data);
3857 if (index > sibling_index)
3861 /* here, tmp got advanced past all lower stacked siblings */
3862 tmp = g_slist_prepend (tmp, window);
3866 update_windows = tmp;
3870 /* if "window" has an ancestor in the list and tmp is one of
3871 * "window's" children, insert "window" before tmp
3873 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3875 tmp = g_slist_prepend (tmp, window);
3880 update_windows = tmp;
3884 /* if we're at the end of the list and had an ancestor it it,
3885 * append to the list
3887 if (! tmp->next && has_ancestor_in_list)
3889 tmp = g_slist_append (tmp, window);
3896 /* if all above checks failed ("window" is from a different
3897 * hierarchy than what is already in the list) or the list is
3900 update_windows = g_slist_prepend (update_windows, window);
3904 gdk_window_remove_update_window (GdkWindow *window)
3906 update_windows = g_slist_remove (update_windows, window);
3910 gdk_window_update_idle (gpointer data)
3912 gdk_window_process_all_updates ();
3918 gdk_window_is_toplevel_frozen (GdkWindow *window)
3920 GdkWindowObject *toplevel;
3922 toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
3924 return toplevel->update_and_descendants_freeze_count > 0;
3928 gdk_window_schedule_update (GdkWindow *window)
3931 (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
3932 gdk_window_is_toplevel_frozen (window)))
3937 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
3938 gdk_window_update_idle,
3943 _gdk_window_process_updates_recurse (GdkWindow *window,
3944 cairo_region_t *expose_region)
3946 GdkWindowObject *private = (GdkWindowObject *)window;
3947 GdkWindowObject *child;
3948 cairo_region_t *child_region;
3950 GList *l, *children;
3952 if (cairo_region_is_empty (expose_region))
3955 if (gdk_window_is_offscreen (private->impl_window) &&
3956 private == private->impl_window)
3957 _gdk_window_add_damage ((GdkWindow *) private->impl_window, expose_region);
3959 /* Make this reentrancy safe for expose handlers freeing windows */
3960 children = g_list_copy (private->children);
3961 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3963 /* Iterate over children, starting at topmost */
3964 for (l = children; l != NULL; l = l->next)
3968 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3971 /* Ignore offscreen children, as they don't draw in their parent and
3972 * don't take part in the clipping */
3973 if (gdk_window_is_offscreen (child))
3978 r.width = child->width;
3979 r.height = child->height;
3981 child_region = cairo_region_create_rectangle (&r);
3984 /* Adjust shape region to parent window coords */
3985 cairo_region_translate (child->shape, child->x, child->y);
3986 cairo_region_intersect (child_region, child->shape);
3987 cairo_region_translate (child->shape, -child->x, -child->y);
3990 if (child->impl == private->impl)
3992 /* Client side child, expose */
3993 cairo_region_intersect (child_region, expose_region);
3994 cairo_region_subtract (expose_region, child_region);
3995 cairo_region_translate (child_region, -child->x, -child->y);
3996 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
4000 /* Native child, just remove area from expose region */
4001 cairo_region_subtract (expose_region, child_region);
4003 cairo_region_destroy (child_region);
4006 g_list_foreach (children, (GFunc)g_object_unref, NULL);
4007 g_list_free (children);
4009 if (!cairo_region_is_empty (expose_region) &&
4010 !private->destroyed)
4012 if (private->event_mask & GDK_EXPOSURE_MASK)
4016 event.expose.type = GDK_EXPOSE;
4017 event.expose.window = g_object_ref (window);
4018 event.expose.send_event = FALSE;
4019 event.expose.count = 0;
4020 event.expose.region = expose_region;
4021 cairo_region_get_extents (expose_region, &event.expose.area);
4023 (*_gdk_event_func) (&event, _gdk_event_data);
4025 g_object_unref (window);
4027 else if (private->window_type != GDK_WINDOW_FOREIGN)
4029 /* No exposure mask set, so nothing will be drawn, the
4030 * app relies on the background being what it specified
4031 * for the window. So, we need to clear this manually.
4033 * For foreign windows if expose is not set that generally
4034 * means some other client paints them, so don't clear
4037 * We use begin/end_paint around the clear so that we can
4038 * piggyback on the implicit paint */
4040 gdk_window_begin_paint_region (window, expose_region);
4041 gdk_window_clear_region_internal (window, expose_region);
4042 gdk_window_end_paint (window);
4047 /* Process and remove any invalid area on the native window by creating
4048 * expose events for the window and all non-native descendants.
4049 * Also processes any outstanding moves on the window before doing
4050 * any drawing. Note that its possible to have outstanding moves without
4051 * any invalid area as we use the update idle mechanism to coalesce
4052 * multiple moves as well as multiple invalidations.
4055 gdk_window_process_updates_internal (GdkWindow *window)
4057 GdkWindowObject *private = (GdkWindowObject *)window;
4058 GdkWindowImplIface *impl_iface;
4059 gboolean save_region = FALSE;
4060 GdkRectangle clip_box;
4062 /* Ensure the window lives while updating it */
4063 g_object_ref (window);
4065 /* If an update got queued during update processing, we can get a
4066 * window in the update queue that has an empty update_area.
4069 if (private->update_area)
4071 cairo_region_t *update_area = private->update_area;
4072 private->update_area = NULL;
4074 if (_gdk_event_func && gdk_window_is_viewable (window))
4076 cairo_region_t *expose_region;
4077 gboolean end_implicit;
4079 /* Clip to part visible in toplevel */
4080 cairo_region_intersect (update_area, private->clip_region);
4084 /* Make sure we see the red invalid area before redrawing. */
4085 gdk_display_sync (gdk_drawable_get_display (window));
4089 /* At this point we will be completely redrawing all of update_area.
4090 * If we have any outstanding moves that end up moving stuff inside
4091 * this area we don't actually need to move that as that part would
4092 * be overdrawn by the expose anyway. So, in order to copy less data
4093 * we remove these areas from the outstanding moves.
4095 if (private->outstanding_moves)
4097 GdkWindowRegionMove *move;
4098 cairo_region_t *remove;
4101 remove = cairo_region_copy (update_area);
4102 /* We iterate backwards, starting from the state that would be
4103 if we had applied all the moves. */
4104 for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
4109 /* Don't need this area */
4110 cairo_region_subtract (move->dest_region, remove);
4112 /* However if any of the destination we do need has a source
4113 in the updated region we do need that as a destination for
4114 the earlier moves */
4115 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
4116 cairo_region_subtract (remove, move->dest_region);
4118 if (cairo_region_is_empty (move->dest_region))
4120 gdk_window_region_move_free (move);
4121 private->outstanding_moves =
4122 g_list_delete_link (private->outstanding_moves, l);
4124 else /* move back */
4125 cairo_region_translate (move->dest_region, move->dx, move->dy);
4127 cairo_region_destroy (remove);
4130 /* By now we a set of window moves that should be applied, and then
4131 * an update region that should be repainted. A trivial implementation
4132 * would just do that in order, however in order to get nicer drawing
4133 * we do some tricks:
4135 * First of all, each subwindow expose may be double buffered by
4136 * itself (depending on widget setting) via
4137 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
4138 * creating a single pixmap the size of the invalid area on the
4139 * native window which all the individual normal paints will draw
4140 * into. This way in the normal case there will be only one pixmap
4141 * allocated and only once pixmap draw done for all the windows
4142 * in this native window.
4143 * There are a couple of reasons this may fail, for instance, some
4144 * backends (like quartz) do its own double buffering, so we disable
4145 * gdk double buffering there. Secondly, some subwindow could be
4146 * non-double buffered and draw directly to the window outside a
4147 * begin/end_paint pair. That will be lead to a gdk_window_flush
4148 * which immediately executes all outstanding moves and paints+removes
4149 * the implicit paint (further paints will allocate their own pixmap).
4151 * Secondly, in the case of implicit double buffering we expose all
4152 * the child windows into the implicit pixmap before we execute
4153 * the outstanding moves. This way we minimize the time between
4154 * doing the moves and rendering the new update area, thus minimizing
4155 * flashing. Of course, if any subwindow is non-double buffered we
4156 * well flush earlier than that.
4158 * Thirdly, after having done the outstanding moves we queue an
4159 * "antiexpose" on the area that will be drawn by the expose, which
4160 * means that any invalid region on the native window side before
4161 * the first expose drawing operation will be discarded, as it
4162 * has by then been overdrawn with valid data. This means we can
4163 * avoid doing the unnecessary repaint any outstanding expose events.
4166 cairo_region_get_extents (update_area, &clip_box);
4167 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
4168 expose_region = cairo_region_copy (update_area);
4171 /* Rendering is not double buffered by gdk, do outstanding
4172 * moves and queue antiexposure immediately. No need to do
4174 gdk_window_flush_outstanding_moves (window);
4175 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4176 save_region = impl_iface->queue_antiexpose (window, update_area);
4179 /* Render the invalid areas to the implicit paint, by sending exposes.
4180 * May flush if non-double buffered widget draw. */
4181 _gdk_windowing_window_process_updates_recurse (window, expose_region);
4185 /* Do moves right before exposes are rendered to the window */
4186 gdk_window_flush_outstanding_moves (window);
4188 /* By this time we know that any outstanding expose for this
4189 * area is invalid and we can avoid it, so queue an antiexpose.
4190 * However, it may be that due to an non-double buffered expose
4191 * we have already started drawing to the window, so it would
4192 * be to late to anti-expose now. Since this is merely an
4193 * optimization we just avoid doing it at all in that case.
4195 if (private->implicit_paint != NULL &&
4196 !private->implicit_paint->flushed)
4198 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4199 save_region = impl_iface->queue_antiexpose (window, update_area);
4202 gdk_window_end_implicit_paint (window);
4204 cairo_region_destroy (expose_region);
4207 cairo_region_destroy (update_area);
4210 if (private->outstanding_moves)
4212 /* Flush any outstanding moves, may happen if we moved a window but got
4213 no actual invalid area */
4214 gdk_window_flush_outstanding_moves (window);
4217 g_object_unref (window);
4221 flush_all_displays (void)
4223 GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4226 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
4227 gdk_display_flush (tmp_list->data);
4229 g_slist_free (displays);
4232 /* Currently it is not possible to override
4233 * gdk_window_process_all_updates in the same manner as
4234 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4235 * by implementing the GdkPaintable interface. If in the future a
4236 * backend would need this, the right solution would be to add a
4237 * method to GdkDisplay that can be optionally
4238 * NULL. gdk_window_process_all_updates can then walk the list of open
4239 * displays and call the mehod.
4243 * gdk_window_process_all_updates:
4245 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4246 * in the application.
4250 gdk_window_process_all_updates (void)
4252 GSList *old_update_windows = update_windows;
4253 GSList *tmp_list = update_windows;
4254 static gboolean in_process_all_updates = FALSE;
4255 static gboolean got_recursive_update = FALSE;
4257 if (in_process_all_updates)
4259 /* We can't do this now since that would recurse, so
4260 delay it until after the recursion is done. */
4261 got_recursive_update = TRUE;
4266 in_process_all_updates = TRUE;
4267 got_recursive_update = FALSE;
4270 g_source_remove (update_idle);
4272 update_windows = NULL;
4275 _gdk_windowing_before_process_all_updates ();
4277 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4281 GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
4283 if (!GDK_WINDOW_DESTROYED (tmp_list->data))
4285 if (private->update_freeze_count ||
4286 gdk_window_is_toplevel_frozen (tmp_list->data))
4287 gdk_window_add_update_window ((GdkWindow *) private);
4289 gdk_window_process_updates_internal (tmp_list->data);
4292 g_object_unref (tmp_list->data);
4293 tmp_list = tmp_list->next;
4296 g_slist_free (old_update_windows);
4298 flush_all_displays ();
4300 _gdk_windowing_after_process_all_updates ();
4302 in_process_all_updates = FALSE;
4304 /* If we ignored a recursive call, schedule a
4305 redraw now so that it eventually happens,
4306 otherwise we could miss an update if nothing
4307 else schedules an update. */
4308 if (got_recursive_update && !update_idle)
4310 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4311 gdk_window_update_idle,
4316 * gdk_window_process_updates:
4317 * @window: a #GdkWindow
4318 * @update_children: whether to also process updates for child windows
4320 * Sends one or more expose events to @window. The areas in each
4321 * expose event will cover the entire update area for the window (see
4322 * gdk_window_invalidate_region() for details). Normally GDK calls
4323 * gdk_window_process_all_updates() on your behalf, so there's no
4324 * need to call this function unless you want to force expose events
4325 * to be delivered immediately and synchronously (vs. the usual
4326 * case, where GDK delivers them in an idle handler). Occasionally
4327 * this is useful to produce nicer scrolling behavior, for example.
4331 gdk_window_process_updates (GdkWindow *window,
4332 gboolean update_children)
4334 GdkWindowObject *private = (GdkWindowObject *)window;
4335 GdkWindowObject *impl_window;
4337 g_return_if_fail (GDK_IS_WINDOW (window));
4339 if (GDK_WINDOW_DESTROYED (window))
4342 /* Make sure the window lives during the expose callouts */
4343 g_object_ref (window);
4345 impl_window = gdk_window_get_impl_window (private);
4346 if ((impl_window->update_area ||
4347 impl_window->outstanding_moves) &&
4348 !impl_window->update_freeze_count &&
4349 !gdk_window_is_toplevel_frozen (window) &&
4351 /* Don't recurse into process_updates_internal, we'll
4352 * do the update later when idle instead. */
4353 impl_window->implicit_paint == NULL)
4355 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4356 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4359 if (update_children)
4361 /* process updates in reverse stacking order so composition or
4362 * painting over achieves the desired effect for offscreen windows
4364 GList *node, *children;
4366 children = g_list_copy (private->children);
4367 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4369 for (node = g_list_last (children); node; node = node->prev)
4371 gdk_window_process_updates (node->data, TRUE);
4372 g_object_unref (node->data);
4375 g_list_free (children);
4378 g_object_unref (window);
4382 gdk_window_invalidate_rect_full (GdkWindow *window,
4383 const GdkRectangle *rect,
4384 gboolean invalidate_children,
4387 GdkRectangle window_rect;
4388 cairo_region_t *region;
4389 GdkWindowObject *private = (GdkWindowObject *)window;
4391 g_return_if_fail (GDK_IS_WINDOW (window));
4393 if (GDK_WINDOW_DESTROYED (window))
4396 if (private->input_only || !private->viewable)
4403 gdk_drawable_get_size (GDK_DRAWABLE (window),
4405 &window_rect.height);
4406 rect = &window_rect;
4409 region = cairo_region_create_rectangle (rect);
4410 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4411 cairo_region_destroy (region);
4415 * gdk_window_invalidate_rect:
4416 * @window: a #GdkWindow
4417 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4419 * @invalidate_children: whether to also invalidate child windows
4421 * A convenience wrapper around gdk_window_invalidate_region() which
4422 * invalidates a rectangular region. See
4423 * gdk_window_invalidate_region() for details.
4426 gdk_window_invalidate_rect (GdkWindow *window,
4427 const GdkRectangle *rect,
4428 gboolean invalidate_children)
4430 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4434 draw_ugly_color (GdkWindow *window,
4435 const cairo_region_t *region)
4439 cr = gdk_cairo_create (window);
4440 /* Draw ugly color all over the newly-invalid region */
4441 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4442 gdk_cairo_region (cr, region);
4449 impl_window_add_update_area (GdkWindowObject *impl_window,
4450 cairo_region_t *region)
4452 if (impl_window->update_area)
4453 cairo_region_union (impl_window->update_area, region);
4456 gdk_window_add_update_window ((GdkWindow *)impl_window);
4457 impl_window->update_area = cairo_region_copy (region);
4458 gdk_window_schedule_update ((GdkWindow *)impl_window);
4462 /* clear_bg controls if the region will be cleared to
4463 * the background color/pixmap if the exposure mask is not
4464 * set for the window, whereas this might not otherwise be
4465 * done (unless necessary to emulate background settings).
4466 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4467 * need to clear the background, such as when exposing the area beneath a
4468 * hidden or moved window, but not when an app requests repaint or when the
4469 * windowing system exposes a newly visible area (because then the windowing
4470 * system has already cleared the area).
4473 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4474 const cairo_region_t *region,
4476 gboolean (*child_func) (GdkWindow *,
4480 GdkWindowObject *private = (GdkWindowObject *)window;
4481 GdkWindowObject *impl_window;
4482 cairo_region_t *visible_region;
4485 g_return_if_fail (GDK_IS_WINDOW (window));
4487 if (GDK_WINDOW_DESTROYED (window))
4490 if (private->input_only ||
4491 !private->viewable ||
4492 cairo_region_is_empty (region) ||
4493 private->window_type == GDK_WINDOW_ROOT)
4496 visible_region = gdk_drawable_get_visible_region (window);
4497 cairo_region_intersect (visible_region, region);
4499 tmp_list = private->children;
4502 GdkWindowObject *child = tmp_list->data;
4504 if (!child->input_only)
4506 cairo_region_t *child_region;
4507 GdkRectangle child_rect;
4509 child_rect.x = child->x;
4510 child_rect.y = child->y;
4511 child_rect.width = child->width;
4512 child_rect.height = child->height;
4513 child_region = cairo_region_create_rectangle (&child_rect);
4515 /* remove child area from the invalid area of the parent */
4516 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4517 !child->composited &&
4518 !gdk_window_is_offscreen (child))
4519 cairo_region_subtract (visible_region, child_region);
4521 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4523 cairo_region_t *tmp = cairo_region_copy (region);
4525 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4526 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4527 cairo_region_intersect (child_region, tmp);
4529 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4530 child_region, clear_bg, child_func, user_data);
4532 cairo_region_destroy (tmp);
4535 cairo_region_destroy (child_region);
4538 tmp_list = tmp_list->next;
4541 impl_window = gdk_window_get_impl_window (private);
4543 if (!cairo_region_is_empty (visible_region) ||
4544 /* Even if we're not exposing anything, make sure we process
4545 idles for windows with outstanding moves */
4546 (impl_window->outstanding_moves != NULL &&
4547 impl_window->update_area == NULL))
4550 draw_ugly_color (window, region);
4552 /* Convert to impl coords */
4553 cairo_region_translate (visible_region, private->abs_x, private->abs_y);
4555 /* Only invalidate area if app requested expose events or if
4556 we need to clear the area (by request or to emulate background
4557 clearing for non-native windows or native windows with no support
4558 for window backgrounds */
4559 if (private->event_mask & GDK_EXPOSURE_MASK ||
4560 clear_bg == CLEAR_BG_ALL ||
4561 clear_bg == CLEAR_BG_WINCLEARED)
4562 impl_window_add_update_area (impl_window, visible_region);
4565 cairo_region_destroy (visible_region);
4569 * gdk_window_invalidate_maybe_recurse:
4570 * @window: a #GdkWindow
4571 * @region: a #cairo_region_t
4572 * @child_func: function to use to decide if to recurse to a child,
4573 * %NULL means never recurse.
4574 * @user_data: data passed to @child_func
4576 * Adds @region to the update area for @window. The update area is the
4577 * region that needs to be redrawn, or "dirty region." The call
4578 * gdk_window_process_updates() sends one or more expose events to the
4579 * window, which together cover the entire update area. An
4580 * application would normally redraw the contents of @window in
4581 * response to those expose events.
4583 * GDK will call gdk_window_process_all_updates() on your behalf
4584 * whenever your program returns to the main loop and becomes idle, so
4585 * normally there's no need to do that manually, you just need to
4586 * invalidate regions that you know should be redrawn.
4588 * The @child_func parameter controls whether the region of
4589 * each child window that intersects @region will also be invalidated.
4590 * Only children for which @child_func returns TRUE will have the area
4594 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4595 const cairo_region_t *region,
4596 gboolean (*child_func) (GdkWindow *,
4600 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4601 child_func, user_data);
4605 true_predicate (GdkWindow *window,
4612 gdk_window_invalidate_region_full (GdkWindow *window,
4613 const cairo_region_t *region,
4614 gboolean invalidate_children,
4617 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4618 invalidate_children ?
4619 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4624 * gdk_window_invalidate_region:
4625 * @window: a #GdkWindow
4626 * @region: a #cairo_region_t
4627 * @invalidate_children: %TRUE to also invalidate child windows
4629 * Adds @region to the update area for @window. The update area is the
4630 * region that needs to be redrawn, or "dirty region." The call
4631 * gdk_window_process_updates() sends one or more expose events to the
4632 * window, which together cover the entire update area. An
4633 * application would normally redraw the contents of @window in
4634 * response to those expose events.
4636 * GDK will call gdk_window_process_all_updates() on your behalf
4637 * whenever your program returns to the main loop and becomes idle, so
4638 * normally there's no need to do that manually, you just need to
4639 * invalidate regions that you know should be redrawn.
4641 * The @invalidate_children parameter controls whether the region of
4642 * each child window that intersects @region will also be invalidated.
4643 * If %FALSE, then the update area for child windows will remain
4644 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4645 * fine grained control over which children are invalidated.
4648 gdk_window_invalidate_region (GdkWindow *window,
4649 const cairo_region_t *region,
4650 gboolean invalidate_children)
4652 gdk_window_invalidate_maybe_recurse (window, region,
4653 invalidate_children ?
4654 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4659 * _gdk_window_invalidate_for_expose:
4660 * @window: a #GdkWindow
4661 * @region: a #cairo_region_t
4663 * Adds @region to the update area for @window. The update area is the
4664 * region that needs to be redrawn, or "dirty region." The call
4665 * gdk_window_process_updates() sends one or more expose events to the
4666 * window, which together cover the entire update area. An
4667 * application would normally redraw the contents of @window in
4668 * response to those expose events.
4670 * GDK will call gdk_window_process_all_updates() on your behalf
4671 * whenever your program returns to the main loop and becomes idle, so
4672 * normally there's no need to do that manually, you just need to
4673 * invalidate regions that you know should be redrawn.
4675 * This version of invalidation is used when you recieve expose events
4676 * from the native window system. It exposes the native window, plus
4677 * any non-native child windows (but not native child windows, as those would
4678 * have gotten their own expose events).
4681 _gdk_window_invalidate_for_expose (GdkWindow *window,
4682 cairo_region_t *region)
4684 GdkWindowObject *private = (GdkWindowObject *) window;
4685 GdkWindowRegionMove *move;
4686 cairo_region_t *move_region;
4689 /* Any invalidations comming from the windowing system will
4690 be in areas that may be moved by outstanding moves,
4691 so we need to modify the expose region correspondingly,
4692 otherwise we would expose in the wrong place, as the
4693 outstanding moves will be copied before we draw the
4695 for (l = private->outstanding_moves; l != NULL; l = l->next)
4699 /* covert to move source region */
4700 move_region = cairo_region_copy (move->dest_region);
4701 cairo_region_translate (move_region, -move->dx, -move->dy);
4703 /* Move area of region that intersects with move source
4704 by dx, dy of the move*/
4705 cairo_region_intersect (move_region, region);
4706 cairo_region_subtract (region, move_region);
4707 cairo_region_translate (move_region, move->dx, move->dy);
4708 cairo_region_union (region, move_region);
4710 cairo_region_destroy (move_region);
4713 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4714 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4720 * gdk_window_get_update_area:
4721 * @window: a #GdkWindow
4723 * Transfers ownership of the update area from @window to the caller
4724 * of the function. That is, after calling this function, @window will
4725 * no longer have an invalid/dirty region; the update area is removed
4726 * from @window and handed to you. If a window has no update area,
4727 * gdk_window_get_update_area() returns %NULL. You are responsible for
4728 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4730 * Return value: the update area for @window
4733 gdk_window_get_update_area (GdkWindow *window)
4735 GdkWindowObject *private = (GdkWindowObject *)window;
4736 GdkWindowObject *impl_window;
4737 cairo_region_t *tmp_region;
4739 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4741 impl_window = gdk_window_get_impl_window (private);
4743 if (impl_window->update_area)
4745 tmp_region = cairo_region_copy (private->clip_region_with_children);
4746 /* Convert to impl coords */
4747 cairo_region_translate (tmp_region, private->abs_x, private->abs_y);
4748 cairo_region_intersect (tmp_region, impl_window->update_area);
4750 if (cairo_region_is_empty (tmp_region))
4752 cairo_region_destroy (tmp_region);
4757 cairo_region_subtract (impl_window->update_area, tmp_region);
4759 if (cairo_region_is_empty (impl_window->update_area) &&
4760 impl_window->outstanding_moves == NULL)
4762 cairo_region_destroy (impl_window->update_area);
4763 impl_window->update_area = NULL;
4765 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4768 /* Convert from impl coords */
4769 cairo_region_translate (tmp_region, -private->abs_x, -private->abs_y);
4779 * _gdk_window_clear_update_area:
4780 * @window: a #GdkWindow.
4782 * Internal function to clear the update area for a window. This
4783 * is called when the window is hidden or destroyed.
4786 _gdk_window_clear_update_area (GdkWindow *window)
4788 GdkWindowObject *private = (GdkWindowObject *)window;
4790 g_return_if_fail (GDK_IS_WINDOW (window));
4792 if (private->update_area)
4794 gdk_window_remove_update_window (window);
4796 cairo_region_destroy (private->update_area);
4797 private->update_area = NULL;
4802 * gdk_window_freeze_updates:
4803 * @window: a #GdkWindow
4805 * Temporarily freezes a window such that it won't receive expose
4806 * events. The window will begin receiving expose events again when
4807 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4808 * has been called more than once, gdk_window_thaw_updates() must be called
4809 * an equal number of times to begin processing exposes.
4812 gdk_window_freeze_updates (GdkWindow *window)
4814 GdkWindowObject *private = (GdkWindowObject *)window;
4815 GdkWindowObject *impl_window;
4817 g_return_if_fail (GDK_IS_WINDOW (window));
4819 impl_window = gdk_window_get_impl_window (private);
4820 impl_window->update_freeze_count++;
4824 * gdk_window_thaw_updates:
4825 * @window: a #GdkWindow
4827 * Thaws a window frozen with gdk_window_freeze_updates().
4830 gdk_window_thaw_updates (GdkWindow *window)
4832 GdkWindowObject *private = (GdkWindowObject *)window;
4833 GdkWindowObject *impl_window;
4835 g_return_if_fail (GDK_IS_WINDOW (window));
4837 impl_window = gdk_window_get_impl_window (private);
4839 g_return_if_fail (impl_window->update_freeze_count > 0);
4841 if (--impl_window->update_freeze_count == 0)
4842 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4846 * gdk_window_freeze_toplevel_updates_libgtk_only:
4847 * @window: a #GdkWindow
4849 * Temporarily freezes a window and all its descendants such that it won't
4850 * receive expose events. The window will begin receiving expose events
4851 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4852 * gdk_window_freeze_toplevel_updates_libgtk_only()
4853 * has been called more than once,
4854 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4855 * an equal number of times to begin processing exposes.
4857 * This function is not part of the GDK public API and is only
4861 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4863 GdkWindowObject *private = (GdkWindowObject *)window;
4865 g_return_if_fail (GDK_IS_WINDOW (window));
4866 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4868 private->update_and_descendants_freeze_count++;
4872 * gdk_window_thaw_toplevel_updates_libgtk_only:
4873 * @window: a #GdkWindow
4875 * Thaws a window frozen with
4876 * gdk_window_freeze_toplevel_updates_libgtk_only().
4878 * This function is not part of the GDK public API and is only
4882 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4884 GdkWindowObject *private = (GdkWindowObject *)window;
4886 g_return_if_fail (GDK_IS_WINDOW (window));
4887 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4888 g_return_if_fail (private->update_and_descendants_freeze_count > 0);
4890 private->update_and_descendants_freeze_count--;
4892 gdk_window_schedule_update (window);
4896 * gdk_window_set_debug_updates:
4897 * @setting: %TRUE to turn on update debugging
4899 * With update debugging enabled, calls to
4900 * gdk_window_invalidate_region() clear the invalidated region of the
4901 * screen to a noticeable color, and GDK pauses for a short time
4902 * before sending exposes to windows during
4903 * gdk_window_process_updates(). The net effect is that you can see
4904 * the invalid region for each window and watch redraws as they
4905 * occur. This allows you to diagnose inefficiencies in your application.
4907 * In essence, because the GDK rendering model prevents all flicker,
4908 * if you are redrawing the same region 400 times you may never
4909 * notice, aside from noticing a speed problem. Enabling update
4910 * debugging causes GTK to flicker slowly and noticeably, so you can
4911 * see exactly what's being redrawn when, in what order.
4913 * The --gtk-debug=updates command line option passed to GTK+ programs
4914 * enables this debug option at application startup time. That's
4915 * usually more useful than calling gdk_window_set_debug_updates()
4916 * yourself, though you might want to use this function to enable
4917 * updates sometime after application startup time.
4921 gdk_window_set_debug_updates (gboolean setting)
4923 debug_updates = setting;
4927 * gdk_window_constrain_size:
4928 * @geometry: a #GdkGeometry structure
4929 * @flags: a mask indicating what portions of @geometry are set
4930 * @width: desired width of window
4931 * @height: desired height of the window
4932 * @new_width: location to store resulting width
4933 * @new_height: location to store resulting height
4935 * Constrains a desired width and height according to a
4936 * set of geometry hints (such as minimum and maximum size).
4939 gdk_window_constrain_size (GdkGeometry *geometry,
4946 /* This routine is partially borrowed from fvwm.
4948 * Copyright 1993, Robert Nation
4949 * You may use this code for any purpose, as long as the original
4950 * copyright remains in the source code and all documentation
4952 * which in turn borrows parts of the algorithm from uwm
4955 gint min_height = 0;
4956 gint base_width = 0;
4957 gint base_height = 0;
4960 gint max_width = G_MAXINT;
4961 gint max_height = G_MAXINT;
4963 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4965 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4967 base_width = geometry->base_width;
4968 base_height = geometry->base_height;
4969 min_width = geometry->min_width;
4970 min_height = geometry->min_height;
4972 else if (flags & GDK_HINT_BASE_SIZE)
4974 base_width = geometry->base_width;
4975 base_height = geometry->base_height;
4976 min_width = geometry->base_width;
4977 min_height = geometry->base_height;
4979 else if (flags & GDK_HINT_MIN_SIZE)
4981 base_width = geometry->min_width;
4982 base_height = geometry->min_height;
4983 min_width = geometry->min_width;
4984 min_height = geometry->min_height;
4987 if (flags & GDK_HINT_MAX_SIZE)
4989 max_width = geometry->max_width ;
4990 max_height = geometry->max_height;
4993 if (flags & GDK_HINT_RESIZE_INC)
4995 xinc = MAX (xinc, geometry->width_inc);
4996 yinc = MAX (yinc, geometry->height_inc);
4999 /* clamp width and height to min and max values
5001 width = CLAMP (width, min_width, max_width);
5002 height = CLAMP (height, min_height, max_height);
5004 /* shrink to base + N * inc
5006 width = base_width + FLOOR (width - base_width, xinc);
5007 height = base_height + FLOOR (height - base_height, yinc);
5009 /* constrain aspect ratio, according to:
5012 * min_aspect <= -------- <= max_aspect
5016 if (flags & GDK_HINT_ASPECT &&
5017 geometry->min_aspect > 0 &&
5018 geometry->max_aspect > 0)
5022 if (geometry->min_aspect * height > width)
5024 delta = FLOOR (height - width / geometry->min_aspect, yinc);
5025 if (height - delta >= min_height)
5029 delta = FLOOR (height * geometry->min_aspect - width, xinc);
5030 if (width + delta <= max_width)
5035 if (geometry->max_aspect * height < width)
5037 delta = FLOOR (width - height * geometry->max_aspect, xinc);
5038 if (width - delta >= min_width)
5042 delta = FLOOR (width / geometry->max_aspect - height, yinc);
5043 if (height + delta <= max_height)
5052 *new_height = height;
5056 * gdk_window_get_pointer:
5057 * @window: a #GdkWindow
5058 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
5059 * return the X coordinate
5060 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
5061 * return the Y coordinate
5062 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
5065 * Obtains the current pointer position and modifier state.
5066 * The position is given in coordinates relative to the upper left
5067 * corner of @window.
5069 * Return value: (transfer none): the window containing the pointer (as with
5070 * gdk_window_at_pointer()), or %NULL if the window containing the
5071 * pointer isn't known to GDK
5073 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
5076 gdk_window_get_pointer (GdkWindow *window,
5079 GdkModifierType *mask)
5081 GdkDisplay *display;
5083 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5085 display = gdk_drawable_get_display (window);
5087 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
5091 * gdk_window_get_device_position:
5092 * @window: a #GdkWindow.
5093 * @device: #GdkDevice to query to.
5094 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
5095 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
5096 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
5098 * Obtains the current device position and modifier state.
5099 * The position is given in coordinates relative to the upper left
5100 * corner of @window.
5102 * Return value: (transfer none): The window underneath @device (as with
5103 * gdk_display_get_window_at_device_position()), or %NULL if the
5104 * window is not known to GDK.
5109 gdk_window_get_device_position (GdkWindow *window,
5113 GdkModifierType *mask)
5115 GdkDisplay *display;
5117 GdkModifierType tmp_mask;
5120 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5121 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
5123 display = gdk_drawable_get_display (window);
5124 child = display->device_hooks->window_get_device_position (display, device, window,
5125 &tmp_x, &tmp_y, &tmp_mask);
5134 _gdk_display_enable_motion_hints (display, device);
5140 * gdk_window_at_pointer:
5141 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
5142 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
5144 * Obtains the window underneath the mouse pointer, returning the
5145 * location of that window in @win_x, @win_y. Returns %NULL if the
5146 * window under the mouse pointer is not known to GDK (if the window
5147 * belongs to another application and a #GdkWindow hasn't been created
5148 * for it with gdk_window_foreign_new())
5150 * NOTE: For multihead-aware widgets or applications use
5151 * gdk_display_get_window_at_pointer() instead.
5153 * Return value: (transfer none): window under the mouse pointer
5155 * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
5158 gdk_window_at_pointer (gint *win_x,
5161 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
5165 * gdk_get_default_root_window:
5167 * Obtains the root window (parent all other windows are inside)
5168 * for the default display and screen.
5170 * Return value: the default root window
5173 gdk_get_default_root_window (void)
5175 return gdk_screen_get_root_window (gdk_screen_get_default ());
5179 * gdk_window_foreign_new:
5180 * @anid: a native window handle.
5182 * Wraps a native window for the default display in a #GdkWindow.
5183 * This may fail if the window has been destroyed.
5185 * For example in the X backend, a native window handle is an Xlib
5188 * Return value: the newly-created #GdkWindow wrapper for the
5189 * native window or %NULL if the window has been destroyed.
5192 gdk_window_foreign_new (GdkNativeWindow anid)
5194 return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
5198 get_all_native_children (GdkWindowObject *private,
5201 GdkWindowObject *child;
5204 for (l = private->children; l != NULL; l = l->next)
5208 if (gdk_window_has_impl (child))
5209 *native = g_list_prepend (*native, child);
5211 get_all_native_children (child, native);
5217 gdk_window_raise_internal (GdkWindow *window)
5219 GdkWindowObject *private = (GdkWindowObject *)window;
5220 GdkWindowObject *parent = private->parent;
5221 GdkWindowObject *above;
5222 GList *native_children;
5224 GdkWindowImplIface *impl_iface;
5228 parent->children = g_list_remove (parent->children, window);
5229 parent->children = g_list_prepend (parent->children, window);
5232 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5233 /* Just do native raise for toplevels */
5234 if (gdk_window_is_toplevel (private) ||
5235 /* The restack_under codepath should work correctly even if the parent
5236 is native, but it relies on the order of ->children to be correct,
5237 and some apps like SWT reorder the x windows without gdks knowledge,
5238 so we use raise directly in order to make these behave as before
5239 when using native windows */
5240 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5242 impl_iface->raise (window);
5244 else if (gdk_window_has_impl (private))
5246 above = find_native_sibling_above (parent, private);
5249 listhead.data = window;
5250 listhead.next = NULL;
5251 listhead.prev = NULL;
5252 impl_iface->restack_under ((GdkWindow *)above,
5256 impl_iface->raise (window);
5260 native_children = NULL;
5261 get_all_native_children (private, &native_children);
5262 if (native_children != NULL)
5264 above = find_native_sibling_above (parent, private);
5267 impl_iface->restack_under ((GdkWindow *)above,
5271 /* Right order, since native_children is bottom-topmost first */
5272 for (l = native_children; l != NULL; l = l->next)
5273 impl_iface->raise (l->data);
5276 g_list_free (native_children);
5282 /* Returns TRUE If the native window was mapped or unmapped */
5284 set_viewable (GdkWindowObject *w,
5287 GdkWindowObject *child;
5288 GdkWindowImplIface *impl_iface;
5291 if (w->viewable == val)
5297 recompute_visible_regions (w, FALSE, FALSE);
5299 for (l = w->children; l != NULL; l = l->next)
5303 if (GDK_WINDOW_IS_MAPPED (child) &&
5304 child->window_type != GDK_WINDOW_FOREIGN)
5305 set_viewable (child, val);
5308 if (!_gdk_native_windows &&
5309 gdk_window_has_impl (w) &&
5310 w->window_type != GDK_WINDOW_FOREIGN &&
5311 !gdk_window_is_toplevel (w))
5313 /* For most native windows we show/hide them not when they are
5314 * mapped/unmapped, because that may not produce the correct results.
5315 * For instance, if a native window have a non-native parent which is
5316 * hidden, but its native parent is viewable then showing the window
5317 * would make it viewable to X but its not viewable wrt the non-native
5318 * hierarchy. In order to handle this we track the gdk side viewability
5319 * and only map really viewable windows.
5321 * There are two exceptions though:
5323 * For foreign windows we don't want ever change the mapped state
5324 * except when explicitly done via gdk_window_show/hide, as this may
5325 * cause problems for client owning the foreign window when its window
5326 * is suddenly mapped or unmapped.
5328 * For toplevel windows embedded in a foreign window (e.g. a plug)
5329 * we sometimes synthesize a map of a window, but the native
5330 * window is really shown by the embedder, so we don't want to
5331 * do the show ourselves. We can't really tell this case from the normal
5332 * toplevel show as such toplevels are seen by gdk as parents of the
5333 * root window, so we make an exception for all toplevels.
5335 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
5336 * like this, so we just always show/hide directly.
5339 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
5341 impl_iface->show ((GdkWindow *)w, FALSE);
5343 impl_iface->hide ((GdkWindow *)w);
5351 /* Returns TRUE If the native window was mapped or unmapped */
5353 _gdk_window_update_viewable (GdkWindow *window)
5355 GdkWindowObject *priv = (GdkWindowObject *)window;
5358 if (priv->window_type == GDK_WINDOW_FOREIGN ||
5359 priv->window_type == GDK_WINDOW_ROOT)
5361 else if (gdk_window_is_toplevel (priv) ||
5362 priv->parent->viewable)
5363 viewable = GDK_WINDOW_IS_MAPPED (priv);
5367 return set_viewable (priv, viewable);
5371 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5373 GdkWindowObject *private;
5374 GdkWindowImplIface *impl_iface;
5375 gboolean was_mapped, was_viewable;
5378 g_return_if_fail (GDK_IS_WINDOW (window));
5380 private = (GdkWindowObject *) window;
5381 if (private->destroyed)
5384 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5385 was_viewable = private->viewable;
5388 /* Keep children in (reverse) stacking order */
5389 gdk_window_raise_internal (window);
5391 if (gdk_window_has_impl (private))
5394 gdk_synthesize_window_state (window,
5395 GDK_WINDOW_STATE_WITHDRAWN,
5403 did_show = _gdk_window_update_viewable (window);
5405 /* If it was already viewable the backend show op won't be called, call it
5406 again to ensure things happen right if the mapped tracking was not right
5407 for e.g. a foreign window.
5408 Dunno if this is strictly needed but its what happened pre-csw.
5409 Also show if not done by gdk_window_update_viewable. */
5410 if (gdk_window_has_impl (private) && (was_viewable || !did_show))
5412 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5413 impl_iface->show ((GdkWindow *)private,
5414 !did_show ? was_mapped : TRUE);
5417 if (!was_mapped && !gdk_window_has_impl (private))
5419 if (private->event_mask & GDK_STRUCTURE_MASK)
5420 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5422 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5423 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5426 if (!was_mapped || raise)
5428 recompute_visible_regions (private, TRUE, FALSE);
5430 /* If any decendants became visible we need to send visibility notify */
5431 gdk_window_update_visibility_recursively (private, NULL);
5433 if (gdk_window_is_viewable (window))
5435 _gdk_synthesize_crossing_events_for_geometry_change (window);
5436 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5442 * gdk_window_show_unraised:
5443 * @window: a #GdkWindow
5445 * Shows a #GdkWindow onscreen, but does not modify its stacking
5446 * order. In contrast, gdk_window_show() will raise the window
5447 * to the top of the window stack.
5449 * On the X11 platform, in Xlib terms, this function calls
5450 * XMapWindow() (it also updates some internal GDK state, which means
5451 * that you can't really use XMapWindow() directly on a GDK window).
5454 gdk_window_show_unraised (GdkWindow *window)
5456 gdk_window_show_internal (window, FALSE);
5461 * @window: a #GdkWindow
5463 * Raises @window to the top of the Z-order (stacking order), so that
5464 * other windows with the same parent window appear below @window.
5465 * This is true whether or not the windows are visible.
5467 * If @window is a toplevel, the window manager may choose to deny the
5468 * request to move the window in the Z-order, gdk_window_raise() only
5469 * requests the restack, does not guarantee it.
5472 gdk_window_raise (GdkWindow *window)
5474 GdkWindowObject *private;
5475 cairo_region_t *old_region, *new_region;
5477 g_return_if_fail (GDK_IS_WINDOW (window));
5479 private = (GdkWindowObject *) window;
5480 if (private->destroyed)
5483 gdk_window_flush_if_exposing (window);
5486 if (gdk_window_is_viewable (window) &&
5487 !private->input_only)
5488 old_region = cairo_region_copy (private->clip_region);
5490 /* Keep children in (reverse) stacking order */
5491 gdk_window_raise_internal (window);
5493 recompute_visible_regions (private, TRUE, FALSE);
5497 new_region = cairo_region_copy (private->clip_region);
5499 cairo_region_subtract (new_region, old_region);
5500 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5502 cairo_region_destroy (old_region);
5503 cairo_region_destroy (new_region);
5508 gdk_window_lower_internal (GdkWindow *window)
5510 GdkWindowObject *private = (GdkWindowObject *)window;
5511 GdkWindowObject *parent = private->parent;
5512 GdkWindowImplIface *impl_iface;
5513 GdkWindowObject *above;
5514 GList *native_children;
5519 parent->children = g_list_remove (parent->children, window);
5520 parent->children = g_list_append (parent->children, window);
5523 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5524 /* Just do native lower for toplevels */
5525 if (gdk_window_is_toplevel (private) ||
5526 /* The restack_under codepath should work correctly even if the parent
5527 is native, but it relies on the order of ->children to be correct,
5528 and some apps like SWT reorder the x windows without gdks knowledge,
5529 so we use lower directly in order to make these behave as before
5530 when using native windows */
5531 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5533 impl_iface->lower (window);
5535 else if (gdk_window_has_impl (private))
5537 above = find_native_sibling_above (parent, private);
5540 listhead.data = window;
5541 listhead.next = NULL;
5542 listhead.prev = NULL;
5543 impl_iface->restack_under ((GdkWindow *)above, &listhead);
5546 impl_iface->raise (window);
5550 native_children = NULL;
5551 get_all_native_children (private, &native_children);
5552 if (native_children != NULL)
5554 above = find_native_sibling_above (parent, private);
5557 impl_iface->restack_under ((GdkWindow *)above,
5561 /* Right order, since native_children is bottom-topmost first */
5562 for (l = native_children; l != NULL; l = l->next)
5563 impl_iface->raise (l->data);
5566 g_list_free (native_children);
5573 gdk_window_invalidate_in_parent (GdkWindowObject *private)
5575 GdkRectangle r, child;
5577 if (gdk_window_is_toplevel (private))
5580 /* get the visible rectangle of the parent */
5582 r.width = private->parent->width;
5583 r.height = private->parent->height;
5585 child.x = private->x;
5586 child.y = private->y;
5587 child.width = private->width;
5588 child.height = private->height;
5589 gdk_rectangle_intersect (&r, &child, &r);
5591 gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
5597 * @window: a #GdkWindow
5599 * Lowers @window to the bottom of the Z-order (stacking order), so that
5600 * other windows with the same parent window appear above @window.
5601 * This is true whether or not the other windows are visible.
5603 * If @window is a toplevel, the window manager may choose to deny the
5604 * request to move the window in the Z-order, gdk_window_lower() only
5605 * requests the restack, does not guarantee it.
5607 * Note that gdk_window_show() raises the window again, so don't call this
5608 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5611 gdk_window_lower (GdkWindow *window)
5613 GdkWindowObject *private;
5615 g_return_if_fail (GDK_IS_WINDOW (window));
5617 private = (GdkWindowObject *) window;
5618 if (private->destroyed)
5621 gdk_window_flush_if_exposing (window);
5623 /* Keep children in (reverse) stacking order */
5624 gdk_window_lower_internal (window);
5626 recompute_visible_regions (private, TRUE, FALSE);
5628 _gdk_synthesize_crossing_events_for_geometry_change (window);
5629 gdk_window_invalidate_in_parent (private);
5633 * gdk_window_restack:
5634 * @window: a #GdkWindow
5635 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5638 * Changes the position of @window in the Z-order (stacking order), so that
5639 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5642 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5643 * lowers the window.
5645 * If @window is a toplevel, the window manager may choose to deny the
5646 * request to move the window in the Z-order, gdk_window_restack() only
5647 * requests the restack, does not guarantee it.
5652 gdk_window_restack (GdkWindow *window,
5656 GdkWindowObject *private;
5657 GdkWindowImplIface *impl_iface;
5658 GdkWindowObject *parent;
5659 GdkWindowObject *above_native;
5660 GList *sibling_link;
5661 GList *native_children;
5664 g_return_if_fail (GDK_IS_WINDOW (window));
5665 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5667 private = (GdkWindowObject *) window;
5668 if (private->destroyed)
5671 if (sibling == NULL)
5674 gdk_window_raise (window);
5676 gdk_window_lower (window);
5680 gdk_window_flush_if_exposing (window);
5682 if (gdk_window_is_toplevel (private))
5684 g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
5685 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5686 impl_iface->restack_toplevel (window, sibling, above);
5690 parent = private->parent;
5693 sibling_link = g_list_find (parent->children, sibling);
5694 g_return_if_fail (sibling_link != NULL);
5695 if (sibling_link == NULL)
5698 parent->children = g_list_remove (parent->children, window);
5700 parent->children = g_list_insert_before (parent->children,
5704 parent->children = g_list_insert_before (parent->children,
5708 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5709 if (gdk_window_has_impl (private))
5711 above_native = find_native_sibling_above (parent, private);
5714 listhead.data = window;
5715 listhead.next = NULL;
5716 listhead.prev = NULL;
5717 impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
5720 impl_iface->raise (window);
5724 native_children = NULL;
5725 get_all_native_children (private, &native_children);
5726 if (native_children != NULL)
5728 above_native = find_native_sibling_above (parent, private);
5730 impl_iface->restack_under ((GdkWindow *)above_native,
5734 /* Right order, since native_children is bottom-topmost first */
5735 for (l = native_children; l != NULL; l = l->next)
5736 impl_iface->raise (l->data);
5739 g_list_free (native_children);
5744 recompute_visible_regions (private, TRUE, FALSE);
5746 _gdk_synthesize_crossing_events_for_geometry_change (window);
5747 gdk_window_invalidate_in_parent (private);
5753 * @window: a #GdkWindow
5755 * Like gdk_window_show_unraised(), but also raises the window to the
5756 * top of the window stack (moves the window to the front of the
5759 * This function maps a window so it's visible onscreen. Its opposite
5760 * is gdk_window_hide().
5762 * When implementing a #GtkWidget, you should call this function on the widget's
5763 * #GdkWindow as part of the "map" method.
5766 gdk_window_show (GdkWindow *window)
5768 gdk_window_show_internal (window, TRUE);
5773 * @window: a #GdkWindow
5775 * For toplevel windows, withdraws them, so they will no longer be
5776 * known to the window manager; for all windows, unmaps them, so
5777 * they won't be displayed. Normally done automatically as
5778 * part of gtk_widget_hide().
5781 gdk_window_hide (GdkWindow *window)
5783 GdkWindowObject *private;
5784 GdkWindowImplIface *impl_iface;
5785 gboolean was_mapped, did_hide;
5787 g_return_if_fail (GDK_IS_WINDOW (window));
5789 private = (GdkWindowObject *) window;
5790 if (private->destroyed)
5793 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5795 if (gdk_window_has_impl (private))
5798 if (GDK_WINDOW_IS_MAPPED (window))
5799 gdk_synthesize_window_state (window,
5801 GDK_WINDOW_STATE_WITHDRAWN);
5803 else if (was_mapped)
5805 GdkDisplay *display;
5806 GdkDeviceManager *device_manager;
5809 /* May need to break grabs on children */
5810 display = gdk_drawable_get_display (window);
5811 device_manager = gdk_display_get_device_manager (display);
5813 /* Get all devices */
5814 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5815 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5816 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5818 for (d = devices; d; d = d->next)
5820 GdkDevice *device = d->data;
5822 if (_gdk_display_end_device_grab (display, device,
5823 _gdk_windowing_window_get_next_serial (display),
5826 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5829 private->state = GDK_WINDOW_STATE_WITHDRAWN;
5830 g_list_free (devices);
5833 did_hide = _gdk_window_update_viewable (window);
5835 /* Hide foreign window as those are not handled by update_viewable. */
5836 if (gdk_window_has_impl (private) && (!did_hide))
5838 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5839 impl_iface->hide (window);
5842 recompute_visible_regions (private, TRUE, FALSE);
5844 /* all decendants became non-visible, we need to send visibility notify */
5845 gdk_window_update_visibility_recursively (private, NULL);
5847 if (was_mapped && !gdk_window_has_impl (private))
5849 if (private->event_mask & GDK_STRUCTURE_MASK)
5850 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5852 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5853 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5855 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5858 /* Invalidate the rect */
5860 gdk_window_invalidate_in_parent (private);
5864 * gdk_window_withdraw:
5865 * @window: a toplevel #GdkWindow
5867 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5868 * This function is not really useful as gdk_window_hide() automatically
5869 * withdraws toplevel windows before hiding them.
5872 gdk_window_withdraw (GdkWindow *window)
5874 GdkWindowObject *private;
5875 GdkWindowImplIface *impl_iface;
5876 gboolean was_mapped;
5878 g_return_if_fail (GDK_IS_WINDOW (window));
5880 private = (GdkWindowObject *) window;
5881 if (private->destroyed)
5884 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5886 if (gdk_window_has_impl (private))
5888 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5889 impl_iface->withdraw (window);
5893 if (private->event_mask & GDK_STRUCTURE_MASK)
5894 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5896 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5897 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5899 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5902 recompute_visible_regions (private, TRUE, FALSE);
5907 * gdk_window_set_events:
5908 * @window: a #GdkWindow
5909 * @event_mask: event mask for @window
5911 * The event mask for a window determines which events will be reported
5912 * for that window from all master input devices. For example, an event mask
5913 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5914 * press events. The event mask is the bitwise OR of values from the
5915 * #GdkEventMask enumeration.
5918 gdk_window_set_events (GdkWindow *window,
5919 GdkEventMask event_mask)
5921 GdkWindowObject *private;
5922 GdkWindowImplIface *impl_iface;
5923 GdkDisplay *display;
5925 g_return_if_fail (GDK_IS_WINDOW (window));
5927 private = (GdkWindowObject *) window;
5928 if (private->destroyed)
5931 /* If motion hint is disabled, enable motion events again */
5932 display = gdk_drawable_get_display (window);
5933 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5934 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5936 GList *devices = private->devices_inside;
5940 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5941 devices = devices->next;
5945 private->event_mask = event_mask;
5947 if (gdk_window_has_impl (private))
5949 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5950 impl_iface->set_events (window,
5951 get_native_event_mask (private));
5957 * gdk_window_get_events:
5958 * @window: a #GdkWindow
5960 * Gets the event mask for @window for all master input devices. See
5961 * gdk_window_set_events().
5963 * Return value: event mask for @window
5966 gdk_window_get_events (GdkWindow *window)
5968 GdkWindowObject *private;
5970 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5972 private = (GdkWindowObject *) window;
5973 if (private->destroyed)
5976 return private->event_mask;
5980 * gdk_window_set_device_events:
5981 * @window: a #GdkWindow
5982 * @device: #GdkDevice to enable events for.
5983 * @event_mask: event mask for @window
5985 * Sets the event mask for a given device (Normally a floating device, not
5986 * attached to any visible pointer) to @window. For example, an event mask
5987 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5988 * press events. The event mask is the bitwise OR of values from the
5989 * #GdkEventMask enumeration.
5994 gdk_window_set_device_events (GdkWindow *window,
5996 GdkEventMask event_mask)
5998 GdkEventMask device_mask;
5999 GdkWindowObject *private;
6000 GdkDisplay *display;
6003 g_return_if_fail (GDK_IS_WINDOW (window));
6004 g_return_if_fail (GDK_IS_DEVICE (device));
6006 if (GDK_WINDOW_DESTROYED (window))
6009 private = (GdkWindowObject *) window;
6011 /* If motion hint is disabled, enable motion events again */
6012 display = gdk_drawable_get_display (window);
6013 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
6014 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
6015 _gdk_display_enable_motion_hints (display, device);
6017 if (G_UNLIKELY (!private->device_events))
6018 private->device_events = g_hash_table_new (NULL, NULL);
6020 if (event_mask == 0)
6022 /* FIXME: unsetting events on a master device
6023 * would restore private->event_mask
6025 g_hash_table_remove (private->device_events, device);
6028 g_hash_table_insert (private->device_events, device,
6029 GINT_TO_POINTER (event_mask));
6031 if (_gdk_native_windows)
6034 native = gdk_window_get_toplevel (window);
6036 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
6038 native = gdk_offscreen_window_get_embedder (native);
6040 if (native == NULL ||
6041 (!_gdk_window_has_impl (native) &&
6042 !gdk_window_is_viewable (native)))
6045 native = gdk_window_get_toplevel (native);
6048 device_mask = get_native_device_event_mask (private, device);
6049 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
6053 * gdk_window_get_device_events:
6054 * @window: a #GdkWindow.
6055 * @device: a #GdkDevice.
6057 * Returns the event mask for @window corresponding to an specific device.
6059 * Returns: device event mask for @window
6064 gdk_window_get_device_events (GdkWindow *window,
6067 GdkWindowObject *private;
6070 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6071 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
6073 if (GDK_WINDOW_DESTROYED (window))
6076 private = (GdkWindowObject *) window;
6078 if (!private->device_events)
6081 mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
6083 /* FIXME: device could be controlled by private->event_mask */
6089 gdk_window_move_resize_toplevel (GdkWindow *window,
6096 GdkWindowObject *private;
6097 cairo_region_t *old_region, *new_region;
6098 GdkWindowImplIface *impl_iface;
6100 int old_x, old_y, old_abs_x, old_abs_y;
6104 private = (GdkWindowObject *) window;
6112 is_resize = (width != -1) || (height != -1);
6114 if (gdk_window_is_viewable (window) &&
6115 !private->input_only)
6118 old_region = cairo_region_copy (private->clip_region);
6121 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6122 impl_iface->move_resize (window, with_move, x, y, width, height);
6124 dx = private->x - old_x;
6125 dy = private->y - old_y;
6127 old_abs_x = private->abs_x;
6128 old_abs_y = private->abs_y;
6130 /* Avoid recomputing for pure toplevel moves, for performance reasons */
6132 recompute_visible_regions (private, TRUE, FALSE);
6136 new_region = cairo_region_copy (private->clip_region);
6138 /* This is the newly exposed area (due to any resize),
6139 * X will expose it, but lets do that without the
6142 cairo_region_subtract (new_region, old_region);
6143 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
6145 cairo_region_destroy (old_region);
6146 cairo_region_destroy (new_region);
6149 _gdk_synthesize_crossing_events_for_geometry_change (window);
6154 move_native_children (GdkWindowObject *private)
6157 GdkWindowObject *child;
6158 GdkWindowImplIface *impl_iface;
6160 for (l = private->children; l; l = l->next)
6164 if (child->impl != private->impl)
6166 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
6167 impl_iface->move_resize ((GdkWindow *)child, TRUE,
6169 child->width, child->height);
6172 move_native_children (child);
6177 collect_native_child_region_helper (GdkWindowObject *window,
6179 cairo_region_t **region,
6183 GdkWindowObject *child;
6184 cairo_region_t *tmp;
6187 for (l = window->children; l != NULL; l = l->next)
6191 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
6194 if (child->impl != impl)
6196 tmp = cairo_region_copy (child->clip_region);
6197 cairo_region_translate (tmp,
6198 x_offset + child->x,
6199 y_offset + child->y);
6200 if (*region == NULL)
6204 cairo_region_union (*region, tmp);
6205 cairo_region_destroy (tmp);
6209 collect_native_child_region_helper (child, impl, region,
6210 x_offset + child->x,
6211 y_offset + child->y);
6217 static cairo_region_t *
6218 collect_native_child_region (GdkWindowObject *window,
6219 gboolean include_this)
6221 cairo_region_t *region;
6223 if (include_this && gdk_window_has_impl (window) && window->viewable)
6224 return cairo_region_copy (window->clip_region);
6228 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6235 gdk_window_move_resize_internal (GdkWindow *window,
6242 GdkWindowObject *private;
6243 cairo_region_t *old_region, *new_region, *copy_area;
6244 cairo_region_t *old_native_child_region, *new_native_child_region;
6245 GdkWindowObject *impl_window;
6246 GdkWindowImplIface *impl_iface;
6248 int old_x, old_y, old_abs_x, old_abs_y;
6251 g_return_if_fail (GDK_IS_WINDOW (window));
6253 private = (GdkWindowObject *) window;
6254 if (private->destroyed)
6257 if (gdk_window_is_toplevel (private))
6259 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6263 /* Bail early if no change */
6264 if (private->width == width &&
6265 private->height == height &&
6271 gdk_window_flush_if_exposing (window);
6273 /* Handle child windows */
6278 impl_window = gdk_window_get_impl_window (private);
6283 old_native_child_region = NULL;
6284 if (gdk_window_is_viewable (window) &&
6285 !private->input_only)
6289 old_region = cairo_region_copy (private->clip_region);
6290 /* Adjust region to parent window coords */
6291 cairo_region_translate (old_region, private->x, private->y);
6293 old_native_child_region = collect_native_child_region (private, TRUE);
6294 if (old_native_child_region)
6296 /* Adjust region to parent window coords */
6297 cairo_region_translate (old_native_child_region, private->x, private->y);
6299 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6300 * source or destination for a delayed GdkWindowRegionMove. So, we need
6301 * to flush those here for the parent window and all overlapped subwindows
6302 * of it. And we need to do this before setting the new clips as those will be
6305 gdk_window_flush_recursive (private->parent);
6309 /* Set the new position and size */
6315 if (!(width < 0 && height < 0))
6319 private->width = width;
6322 private->height = height;
6325 dx = private->x - old_x;
6326 dy = private->y - old_y;
6328 old_abs_x = private->abs_x;
6329 old_abs_y = private->abs_y;
6331 recompute_visible_regions (private, TRUE, FALSE);
6333 new_native_child_region = NULL;
6334 if (old_native_child_region)
6336 new_native_child_region = collect_native_child_region (private, TRUE);
6337 /* Adjust region to parent window coords */
6338 cairo_region_translate (new_native_child_region, private->x, private->y);
6341 if (gdk_window_has_impl (private))
6343 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6345 /* Do the actual move after recomputing things, as this will have set the shape to
6346 the now correct one, thus avoiding copying regions that should not be copied. */
6347 impl_iface->move_resize (window, TRUE,
6348 private->x, private->y,
6349 private->width, private->height);
6351 else if (old_abs_x != private->abs_x ||
6352 old_abs_y != private->abs_y)
6353 move_native_children (private);
6357 new_region = cairo_region_copy (private->clip_region);
6358 /* Adjust region to parent window coords */
6359 cairo_region_translate (new_region, private->x, private->y);
6362 * Part of the data at the new location can be copied from the
6363 * old location, this area is the intersection of the old region
6364 * moved as the copy will move it and then intersected with
6368 * Everything in the old and new regions that is not copied must be
6369 * invalidated (including children) as this is newly exposed
6371 copy_area = cairo_region_copy (new_region);
6373 cairo_region_union (new_region, old_region);
6375 if (old_native_child_region)
6377 /* Don't copy from inside native children, as this is copied by
6378 * the native window move.
6380 cairo_region_subtract (old_region, old_native_child_region);
6382 cairo_region_translate (old_region, dx, dy);
6384 cairo_region_intersect (copy_area, old_region);
6386 if (new_native_child_region)
6388 /* Don't copy any bits that would cause a read from the moved
6389 native windows, as we can't read that data */
6390 cairo_region_translate (new_native_child_region, dx, dy);
6391 cairo_region_subtract (copy_area, new_native_child_region);
6392 cairo_region_translate (new_native_child_region, -dx, -dy);
6395 cairo_region_subtract (new_region, copy_area);
6397 /* Convert old region to impl coords */
6398 cairo_region_translate (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
6400 /* convert from parent coords to impl */
6401 cairo_region_translate (copy_area, private->abs_x - private->x, private->abs_y - private->y);
6403 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6405 /* Invalidate affected part in the parent window
6406 * (no higher window should be affected)
6407 * We also invalidate any children in that area, which could include
6408 * this window if it still overlaps that area.
6410 if (old_native_child_region)
6412 /* No need to expose the region that the native window move copies */
6413 cairo_region_translate (old_native_child_region, dx, dy);
6414 cairo_region_intersect (old_native_child_region, new_native_child_region);
6415 cairo_region_subtract (new_region, old_native_child_region);
6417 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
6419 cairo_region_destroy (old_region);
6420 cairo_region_destroy (new_region);
6423 if (old_native_child_region)
6425 cairo_region_destroy (old_native_child_region);
6426 cairo_region_destroy (new_native_child_region);
6429 _gdk_synthesize_crossing_events_for_geometry_change (window);
6436 * @window: a #GdkWindow
6437 * @x: X coordinate relative to window's parent
6438 * @y: Y coordinate relative to window's parent
6440 * Repositions a window relative to its parent window.
6441 * For toplevel windows, window managers may ignore or modify the move;
6442 * you should probably use gtk_window_move() on a #GtkWindow widget
6443 * anyway, instead of using GDK functions. For child windows,
6444 * the move will reliably succeed.
6446 * If you're also planning to resize the window, use gdk_window_move_resize()
6447 * to both move and resize simultaneously, for a nicer visual effect.
6450 gdk_window_move (GdkWindow *window,
6454 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6458 * gdk_window_resize:
6459 * @window: a #GdkWindow
6460 * @width: new width of the window
6461 * @height: new height of the window
6463 * Resizes @window; for toplevel windows, asks the window manager to resize
6464 * the window. The window manager may not allow the resize. When using GTK+,
6465 * use gtk_window_resize() instead of this low-level GDK function.
6467 * Windows may not be resized below 1x1.
6469 * If you're also planning to move the window, use gdk_window_move_resize()
6470 * to both move and resize simultaneously, for a nicer visual effect.
6473 gdk_window_resize (GdkWindow *window,
6477 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6482 * gdk_window_move_resize:
6483 * @window: a #GdkWindow
6484 * @x: new X position relative to window's parent
6485 * @y: new Y position relative to window's parent
6487 * @height: new height
6489 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6490 * except that both operations are performed at once, avoiding strange
6491 * visual effects. (i.e. the user may be able to see the window first
6492 * move, then resize, if you don't use gdk_window_move_resize().)
6495 gdk_window_move_resize (GdkWindow *window,
6501 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6506 * gdk_window_scroll:
6507 * @window: a #GdkWindow
6508 * @dx: Amount to scroll in the X direction
6509 * @dy: Amount to scroll in the Y direction
6511 * Scroll the contents of @window, both pixels and children, by the
6512 * given amount. @window itself does not move. Portions of the window
6513 * that the scroll operation brings in from offscreen areas are
6514 * invalidated. The invalidated region may be bigger than what would
6515 * strictly be necessary.
6517 * For X11, a minimum area will be invalidated if the window has no
6518 * subwindows, or if the edges of the window's parent do not extend
6519 * beyond the edges of the window. In other cases, a multi-step process
6520 * is used to scroll the window which may produce temporary visual
6521 * artifacts and unnecessary invalidations.
6524 gdk_window_scroll (GdkWindow *window,
6528 GdkWindowObject *private = (GdkWindowObject *) window;
6529 GdkWindowObject *impl_window;
6530 cairo_region_t *copy_area, *noncopy_area;
6531 cairo_region_t *old_native_child_region, *new_native_child_region;
6534 g_return_if_fail (GDK_IS_WINDOW (window));
6536 if (dx == 0 && dy == 0)
6539 if (private->destroyed)
6542 gdk_window_flush_if_exposing (window);
6544 old_native_child_region = collect_native_child_region (private, FALSE);
6545 if (old_native_child_region)
6547 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6548 * source or destination for a delayed GdkWindowRegionMove. So, we need
6549 * to flush those here for the window and all overlapped subwindows
6550 * of it. And we need to do this before setting the new clips as those will be
6553 gdk_window_flush_recursive (private);
6557 /* First move all child windows, without causing invalidation */
6559 tmp_list = private->children;
6562 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6563 GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
6565 /* Just update the positions, the bits will move with the copy */
6569 tmp_list = tmp_list->next;
6572 recompute_visible_regions (private, FALSE, TRUE);
6574 new_native_child_region = NULL;
6575 if (old_native_child_region)
6576 new_native_child_region = collect_native_child_region (private, FALSE);
6578 move_native_children (private);
6580 /* Then copy the actual bits of the window w/ child windows */
6582 impl_window = gdk_window_get_impl_window (private);
6584 /* Calculate the area that can be gotten by copying the old area */
6585 copy_area = cairo_region_copy (private->clip_region);
6586 if (old_native_child_region)
6588 /* Don't copy from inside native children, as this is copied by
6589 * the native window move.
6591 cairo_region_subtract (copy_area, old_native_child_region);
6593 /* Don't copy any bits that would cause a read from the moved
6594 native windows, as we can't read that data */
6595 cairo_region_subtract (copy_area, new_native_child_region);
6597 cairo_region_translate (copy_area, dx, dy);
6598 cairo_region_intersect (copy_area, private->clip_region);
6600 /* And the rest need to be invalidated */
6601 noncopy_area = cairo_region_copy (private->clip_region);
6602 cairo_region_subtract (noncopy_area, copy_area);
6604 /* convert from window coords to impl */
6605 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6607 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6609 /* Invalidate not copied regions */
6610 if (old_native_child_region)
6612 /* No need to expose the region that the native window move copies */
6613 cairo_region_translate (old_native_child_region, dx, dy);
6614 cairo_region_intersect (old_native_child_region, new_native_child_region);
6615 cairo_region_subtract (noncopy_area, old_native_child_region);
6617 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6619 cairo_region_destroy (noncopy_area);
6621 if (old_native_child_region)
6623 cairo_region_destroy (old_native_child_region);
6624 cairo_region_destroy (new_native_child_region);
6627 _gdk_synthesize_crossing_events_for_geometry_change (window);
6631 * gdk_window_move_region:
6632 * @window: a #GdkWindow
6633 * @region: The #cairo_region_t to move
6634 * @dx: Amount to move in the X direction
6635 * @dy: Amount to move in the Y direction
6637 * Move the part of @window indicated by @region by @dy pixels in the Y
6638 * direction and @dx pixels in the X direction. The portions of @region
6639 * that not covered by the new position of @region are invalidated.
6641 * Child windows are not moved.
6646 gdk_window_move_region (GdkWindow *window,
6647 const cairo_region_t *region,
6651 GdkWindowObject *private = (GdkWindowObject *) window;
6652 GdkWindowObject *impl_window;
6653 cairo_region_t *nocopy_area;
6654 cairo_region_t *copy_area;
6656 g_return_if_fail (GDK_IS_WINDOW (window));
6657 g_return_if_fail (region != NULL);
6659 if (dx == 0 && dy == 0)
6662 if (private->destroyed)
6665 impl_window = gdk_window_get_impl_window (private);
6667 /* compute source regions */
6668 copy_area = cairo_region_copy (region);
6669 cairo_region_intersect (copy_area, private->clip_region_with_children);
6671 /* compute destination regions */
6672 cairo_region_translate (copy_area, dx, dy);
6673 cairo_region_intersect (copy_area, private->clip_region_with_children);
6675 /* Invalidate parts of the region (source and dest) not covered
6677 nocopy_area = cairo_region_copy (region);
6678 cairo_region_translate (nocopy_area, dx, dy);
6679 cairo_region_union (nocopy_area, region);
6680 cairo_region_subtract (nocopy_area, copy_area);
6682 /* convert from window coords to impl */
6683 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6684 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6686 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6687 cairo_region_destroy (nocopy_area);
6691 * gdk_window_set_background:
6692 * @window: a #GdkWindow
6693 * @color: a #GdkColor
6695 * Sets the background color of @window. (However, when using GTK+,
6696 * set the background of a widget with gtk_widget_modify_bg() - if
6697 * you're an application - or gtk_style_set_background() - if you're
6698 * implementing a custom widget.)
6700 * See also gdk_window_set_background_pattern().
6703 gdk_window_set_background (GdkWindow *window,
6704 const GdkColor *color)
6706 cairo_pattern_t *pattern;
6708 g_return_if_fail (GDK_IS_WINDOW (window));
6710 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6711 color->green / 65535.,
6712 color->blue / 65535.);
6714 gdk_window_set_background_pattern (window, pattern);
6716 cairo_pattern_destroy (pattern);
6719 /* NB: This is more or less a hack now and about to go away. */
6721 gdk_window_set_back_pixmap (GdkWindow *window,
6723 gboolean parent_relative)
6725 cairo_pattern_t *pattern;
6727 g_return_if_fail (GDK_IS_WINDOW (window));
6728 g_return_if_fail (pixmap == NULL || !parent_relative);
6730 if (parent_relative || pixmap == NULL)
6734 static cairo_user_data_key_t key;
6735 cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (pixmap);
6736 pattern = cairo_pattern_create_for_surface (surface);
6737 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
6738 g_object_ref (pixmap);
6739 cairo_pattern_set_user_data (pattern, &key, pixmap, g_object_unref);
6742 gdk_window_set_background_pattern (window, pattern);
6745 cairo_pattern_destroy (pattern);
6749 * gdk_window_set_background_pattern:
6750 * @window: a #GdkWindow
6751 * @pattern: (allow-none): a pattern to use, or %NULL
6753 * Sets the background of @window.
6755 * A background of %NULL means that the window will inherit its
6756 * background form its parent window.
6758 * The windowing system will normally fill a window with its background
6759 * when the window is obscured then exposed, and when you call
6760 * gdk_window_clear().
6763 gdk_window_set_background_pattern (GdkWindow *window,
6764 cairo_pattern_t *pattern)
6766 GdkWindowObject *private;
6768 g_return_if_fail (GDK_IS_WINDOW (window));
6770 private = (GdkWindowObject *) window;
6773 cairo_pattern_reference (pattern);
6774 if (private->background)
6775 cairo_pattern_destroy (private->background);
6776 private->background = pattern;
6778 if (gdk_window_has_impl (private) &&
6779 !private->input_only)
6781 GdkWindowImplIface *impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6782 impl_iface->set_background (window, pattern);
6787 * gdk_window_get_background_pattern:
6790 * Gets the pattern used to clear the background on @window. If @window
6791 * does not have its own background and reuses the parent's, %NULL is
6792 * returned and you'll have to query it yourself.
6794 * Returns: The pattern to use for the background or %NULL to use the
6795 * parent's background.
6800 gdk_window_get_background_pattern (GdkWindow *window)
6802 GdkWindowObject *private = (GdkWindowObject *) window;
6804 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6806 return private->background;
6810 update_cursor_foreach (GdkDisplay *display,
6812 GdkPointerWindowInfo *pointer_info,
6815 GdkWindow *window = user_data;
6816 GdkWindowObject *private = (GdkWindowObject *) window;
6818 if (_gdk_native_windows ||
6819 private->window_type == GDK_WINDOW_ROOT ||
6820 private->window_type == GDK_WINDOW_FOREIGN)
6821 GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_device_cursor (window, device, private->cursor);
6822 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6823 update_cursor (display, device);
6827 * gdk_window_get_cursor:
6828 * @window: a #GdkWindow
6830 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6831 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6832 * there is no custom cursor set on the specified window, and it is
6833 * using the cursor for its parent window.
6835 * Return value: a #GdkCursor, or %NULL. The returned object is owned
6836 * by the #GdkWindow and should not be unreferenced directly. Use
6837 * gdk_window_set_cursor() to unset the cursor of the window
6842 gdk_window_get_cursor (GdkWindow *window)
6844 GdkWindowObject *private;
6846 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6848 private = (GdkWindowObject *) window;
6850 return private->cursor;
6854 * gdk_window_set_cursor:
6855 * @window: a #GdkWindow
6856 * @cursor: (allow-none): a cursor
6858 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6859 * or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor
6860 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6861 * to gdk_window_set_cursor() means that @window will use the cursor of its
6862 * parent window. Most windows should use this default.
6865 gdk_window_set_cursor (GdkWindow *window,
6868 GdkWindowObject *private;
6869 GdkDisplay *display;
6871 g_return_if_fail (GDK_IS_WINDOW (window));
6873 private = (GdkWindowObject *) window;
6874 display = gdk_drawable_get_display (window);
6876 if (private->cursor)
6878 gdk_cursor_unref (private->cursor);
6879 private->cursor = NULL;
6882 if (!GDK_WINDOW_DESTROYED (window))
6885 private->cursor = gdk_cursor_ref (cursor);
6887 _gdk_display_pointer_info_foreach (display,
6888 update_cursor_foreach,
6891 g_object_notify (G_OBJECT (window), "cursor");
6896 * gdk_window_get_device_cursor:
6897 * @window: a #GdkWindow.
6898 * @device: a #GdkDevice.
6900 * Retrieves a #GdkCursor pointer for the @device currently set on the
6901 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6902 * there is no custom cursor set on the specified window, and it is
6903 * using the cursor for its parent window.
6905 * Returns: a #GdkCursor, or %NULL. The returned object is owned
6906 * by the #GdkWindow and should not be unreferenced directly. Use
6907 * gdk_window_set_cursor() to unset the cursor of the window
6912 gdk_window_get_device_cursor (GdkWindow *window,
6915 GdkWindowObject *private;
6917 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6918 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6920 private = (GdkWindowObject *) window;
6922 return g_hash_table_lookup (private->device_cursor, device);
6926 * gdk_window_set_device_cursor:
6927 * @window: a #Gdkwindow
6928 * @device: a #GdkDevice
6929 * @cursor: a #GdkCursor
6931 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6932 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixmap() to create
6933 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6934 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6935 * @window will use the cursor of its parent window. Most windows should
6941 gdk_window_set_device_cursor (GdkWindow *window,
6945 GdkWindowObject *private;
6946 GdkDisplay *display;
6948 g_return_if_fail (GDK_IS_WINDOW (window));
6949 g_return_if_fail (GDK_IS_DEVICE (device));
6951 private = (GdkWindowObject *) window;
6952 display = gdk_drawable_get_display (window);
6955 g_hash_table_remove (private->device_cursor, device);
6957 g_hash_table_replace (private->device_cursor, device, gdk_cursor_ref (cursor));
6959 if (!GDK_WINDOW_DESTROYED (window))
6961 GdkPointerWindowInfo *pointer_info;
6963 pointer_info = _gdk_display_get_pointer_info (display, device);
6965 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6966 update_cursor (display, device);
6971 * gdk_window_get_geometry:
6972 * @window: a #GdkWindow
6973 * @x: return location for X coordinate of window (relative to its parent)
6974 * @y: return location for Y coordinate of window (relative to its parent)
6975 * @width: return location for width of window
6976 * @height: return location for height of window
6977 * @depth: return location for bit depth of window
6979 * Any of the return location arguments to this function may be %NULL,
6980 * if you aren't interested in getting the value of that field.
6982 * The X and Y coordinates returned are relative to the parent window
6983 * of @window, which for toplevels usually means relative to the
6984 * window decorations (titlebar, etc.) rather than relative to the
6985 * root window (screen-size background window).
6987 * On the X11 platform, the geometry is obtained from the X server,
6988 * so reflects the latest position of @window; this may be out-of-sync
6989 * with the position of @window delivered in the most-recently-processed
6990 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6991 * position from the most recent configure event.
6994 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6995 * to call gdk_window_get_position() and gdk_drawable_get_size() instead,
6996 * because it avoids the roundtrip to the X server and because
6997 * gdk_drawable_get_size() supports the full 32-bit coordinate space,
6998 * whereas gdk_window_get_geometry() is restricted to the 16-bit
6999 * coordinates of X11.
7003 gdk_window_get_geometry (GdkWindow *window,
7010 GdkWindowObject *private, *parent;
7011 GdkWindowImplIface *impl_iface;
7015 GDK_NOTE (MULTIHEAD,
7016 g_message ("gdk_window_get_geometry(): Window needs "
7017 "to be non-NULL to be multi head safe"));
7018 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
7021 g_return_if_fail (GDK_IS_WINDOW (window));
7023 private = (GdkWindowObject *) window;
7025 if (!GDK_WINDOW_DESTROYED (window))
7027 if (gdk_window_has_impl (private))
7029 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7030 impl_iface->get_geometry (window, x, y,
7033 /* This reports the position wrt to the native parent, we need to convert
7034 it to be relative to the client side parent */
7035 parent = private->parent;
7036 if (parent && !gdk_window_has_impl (parent))
7039 *x -= parent->abs_x;
7041 *y -= parent->abs_y;
7051 *width = private->width;
7053 *height = private->height;
7055 *depth = private->depth;
7061 * gdk_window_get_origin:
7062 * @window: a #GdkWindow
7063 * @x: return location for X coordinate
7064 * @y: return location for Y coordinate
7066 * Obtains the position of a window in root window coordinates.
7067 * (Compare with gdk_window_get_position() and
7068 * gdk_window_get_geometry() which return the position of a window
7069 * relative to its parent window.)
7071 * Return value: not meaningful, ignore
7074 gdk_window_get_origin (GdkWindow *window,
7078 GdkWindowObject *private;
7079 GdkWindowImplIface *impl_iface;
7081 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7083 if (GDK_WINDOW_DESTROYED (window))
7092 private = (GdkWindowObject *) window;
7094 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7095 impl_iface->get_root_coords (window,
7104 * gdk_window_get_root_coords:
7105 * @window: a #GdkWindow
7106 * @x: X coordinate in window
7107 * @y: Y coordinate in window
7108 * @root_x: return location for X coordinate
7109 * @root_y: return location for Y coordinate
7111 * Obtains the position of a window position in root
7112 * window coordinates. This is similar to
7113 * gdk_window_get_origin() but allows you go pass
7114 * in any position in the window, not just the origin.
7119 gdk_window_get_root_coords (GdkWindow *window,
7125 GdkWindowObject *private;
7126 GdkWindowImplIface *impl_iface;
7128 g_return_if_fail (GDK_IS_WINDOW (window));
7130 private = (GdkWindowObject *) window;
7132 if (GDK_WINDOW_DESTROYED (window))
7141 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7142 impl_iface->get_root_coords (window,
7149 * gdk_window_coords_to_parent:
7150 * @window: a child window
7151 * @x: X coordinate in child's coordinate system
7152 * @y: Y coordinate in child's coordinate system
7153 * @parent_x: (out) (allow-none): return location for X coordinate
7154 * in parent's coordinate system, or %NULL
7155 * @parent_y: (out) (allow-none): return location for Y coordinate
7156 * in parent's coordinate system, or %NULL
7158 * Transforms window coordinates from a child window to its parent
7159 * window, where the parent window is the normal parent as returned by
7160 * gdk_window_get_parent() for normal windows, and the window's
7161 * embedder as returned by gdk_offscreen_window_get_embedder() for
7162 * offscreen windows.
7164 * For normal windows, calling this function is equivalent to adding
7165 * the return values of gdk_window_get_position() to the child coordinates.
7166 * For offscreen windows however (which can be arbitrarily transformed),
7167 * this function calls the GdkWindow::to-embedder: signal to translate
7170 * You should always use this function when writing generic code that
7171 * walks up a window hierarchy.
7173 * See also: gdk_window_coords_from_parent()
7178 gdk_window_coords_to_parent (GdkWindow *window,
7184 GdkWindowObject *obj;
7186 g_return_if_fail (GDK_IS_WINDOW (window));
7188 obj = (GdkWindowObject *) window;
7190 if (gdk_window_is_offscreen (obj))
7194 to_embedder (obj, x, y, &px, &py);
7205 *parent_x = x + obj->x;
7208 *parent_y = y + obj->y;
7213 * gdk_window_coords_from_parent:
7214 * @window: a child window
7215 * @parent_x: X coordinate in parent's coordinate system
7216 * @parent_y: Y coordinate in parent's coordinate system
7217 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7218 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7220 * Transforms window coordinates from a parent window to a child
7221 * window, where the parent window is the normal parent as returned by
7222 * gdk_window_get_parent() for normal windows, and the window's
7223 * embedder as returned by gdk_offscreen_window_get_embedder() for
7224 * offscreen windows.
7226 * For normal windows, calling this function is equivalent to subtracting
7227 * the return values of gdk_window_get_position() from the parent coordinates.
7228 * For offscreen windows however (which can be arbitrarily transformed),
7229 * this function calls the GdkWindow::from-embedder: signal to translate
7232 * You should always use this function when writing generic code that
7233 * walks down a window hierarchy.
7235 * See also: gdk_window_coords_to_parent()
7240 gdk_window_coords_from_parent (GdkWindow *window,
7246 GdkWindowObject *obj;
7248 g_return_if_fail (GDK_IS_WINDOW (window));
7250 obj = (GdkWindowObject *) window;
7252 if (gdk_window_is_offscreen (obj))
7256 from_embedder (obj, parent_x, parent_y, &cx, &cy);
7267 *x = parent_x - obj->x;
7270 *y = parent_y - obj->y;
7275 * gdk_window_shape_combine_region:
7276 * @window: a #GdkWindow
7277 * @shape_region: region of window to be non-transparent
7278 * @offset_x: X position of @shape_region in @window coordinates
7279 * @offset_y: Y position of @shape_region in @window coordinates
7281 * Makes pixels in @window outside @shape_region be transparent,
7282 * so that the window may be nonrectangular.
7284 * If @shape_region is %NULL, the shape will be unset, so the whole
7285 * window will be opaque again. @offset_x and @offset_y are ignored
7286 * if @shape_region is %NULL.
7288 * On the X11 platform, this uses an X server extension which is
7289 * widely available on most common platforms, but not available on
7290 * very old X servers, and occasionally the implementation will be
7291 * buggy. On servers without the shape extension, this function
7294 * This function works on both toplevel and child windows.
7297 gdk_window_shape_combine_region (GdkWindow *window,
7298 const cairo_region_t *shape_region,
7302 GdkWindowObject *private;
7303 cairo_region_t *old_region, *new_region, *diff;
7305 g_return_if_fail (GDK_IS_WINDOW (window));
7307 private = (GdkWindowObject *) window;
7309 if (GDK_WINDOW_DESTROYED (window))
7312 private->shaped = (shape_region != NULL);
7315 cairo_region_destroy (private->shape);
7318 if (GDK_WINDOW_IS_MAPPED (window))
7319 old_region = cairo_region_copy (private->clip_region);
7323 private->shape = cairo_region_copy (shape_region);
7324 cairo_region_translate (private->shape, offset_x, offset_y);
7327 private->shape = NULL;
7329 recompute_visible_regions (private, TRUE, FALSE);
7331 if (gdk_window_has_impl (private) &&
7332 !should_apply_clip_as_shape (private))
7333 apply_shape (private, private->shape);
7337 new_region = cairo_region_copy (private->clip_region);
7339 /* New area in the window, needs invalidation */
7340 diff = cairo_region_copy (new_region);
7341 cairo_region_subtract (diff, old_region);
7343 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7345 cairo_region_destroy (diff);
7347 if (!gdk_window_is_toplevel (private))
7349 /* New area in the non-root parent window, needs invalidation */
7350 diff = cairo_region_copy (old_region);
7351 cairo_region_subtract (diff, new_region);
7353 /* Adjust region to parent window coords */
7354 cairo_region_translate (diff, private->x, private->y);
7356 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
7358 cairo_region_destroy (diff);
7361 cairo_region_destroy (new_region);
7362 cairo_region_destroy (old_region);
7367 do_child_shapes (GdkWindow *window,
7370 GdkWindowObject *private;
7372 cairo_region_t *region;
7374 private = (GdkWindowObject *) window;
7378 r.width = private->width;
7379 r.height = private->height;
7381 region = cairo_region_create_rectangle (&r);
7382 remove_child_area (private, NULL, FALSE, region);
7384 if (merge && private->shape)
7385 cairo_region_subtract (region, private->shape);
7387 gdk_window_shape_combine_region (window, region, 0, 0);
7391 * gdk_window_set_child_shapes:
7392 * @window: a #GdkWindow
7394 * Sets the shape mask of @window to the union of shape masks
7395 * for all children of @window, ignoring the shape mask of @window
7396 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7397 * the shape mask of @window in the masks to be merged.
7400 gdk_window_set_child_shapes (GdkWindow *window)
7402 g_return_if_fail (GDK_IS_WINDOW (window));
7404 do_child_shapes (window, FALSE);
7408 * gdk_window_merge_child_shapes:
7409 * @window: a #GdkWindow
7411 * Merges the shape masks for any child windows into the
7412 * shape mask for @window. i.e. the union of all masks
7413 * for @window and its children will become the new mask
7414 * for @window. See gdk_window_shape_combine_region().
7416 * This function is distinct from gdk_window_set_child_shapes()
7417 * because it includes @window's shape mask in the set of shapes to
7421 gdk_window_merge_child_shapes (GdkWindow *window)
7423 g_return_if_fail (GDK_IS_WINDOW (window));
7425 do_child_shapes (window, TRUE);
7429 * gdk_window_input_shape_combine_region:
7430 * @window: a #GdkWindow
7431 * @shape_region: region of window to be non-transparent
7432 * @offset_x: X position of @shape_region in @window coordinates
7433 * @offset_y: Y position of @shape_region in @window coordinates
7435 * Like gdk_window_shape_combine_region(), but the shape applies
7436 * only to event handling. Mouse events which happen while
7437 * the pointer position corresponds to an unset bit in the
7438 * mask will be passed on the window below @window.
7440 * An input shape is typically used with RGBA windows.
7441 * The alpha channel of the window defines which pixels are
7442 * invisible and allows for nicely antialiased borders,
7443 * and the input shape controls where the window is
7446 * On the X11 platform, this requires version 1.1 of the
7449 * On the Win32 platform, this functionality is not present and the
7450 * function does nothing.
7455 gdk_window_input_shape_combine_region (GdkWindow *window,
7456 const cairo_region_t *shape_region,
7460 GdkWindowObject *private;
7461 GdkWindowImplIface *impl_iface;
7463 g_return_if_fail (GDK_IS_WINDOW (window));
7465 private = (GdkWindowObject *) window;
7467 if (GDK_WINDOW_DESTROYED (window))
7470 if (private->input_shape)
7471 cairo_region_destroy (private->input_shape);
7475 private->input_shape = cairo_region_copy (shape_region);
7476 cairo_region_translate (private->input_shape, offset_x, offset_y);
7479 private->input_shape = NULL;
7481 if (gdk_window_has_impl (private))
7483 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7484 impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
7487 /* Pointer may have e.g. moved outside window due to the input mask change */
7488 _gdk_synthesize_crossing_events_for_geometry_change (window);
7492 do_child_input_shapes (GdkWindow *window,
7495 GdkWindowObject *private;
7497 cairo_region_t *region;
7499 private = (GdkWindowObject *) window;
7503 r.width = private->width;
7504 r.height = private->height;
7506 region = cairo_region_create_rectangle (&r);
7507 remove_child_area (private, NULL, TRUE, region);
7509 if (merge && private->shape)
7510 cairo_region_subtract (region, private->shape);
7511 if (merge && private->input_shape)
7512 cairo_region_subtract (region, private->input_shape);
7514 gdk_window_input_shape_combine_region (window, region, 0, 0);
7519 * gdk_window_set_child_input_shapes:
7520 * @window: a #GdkWindow
7522 * Sets the input shape mask of @window to the union of input shape masks
7523 * for all children of @window, ignoring the input shape mask of @window
7524 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7525 * the input shape mask of @window in the masks to be merged.
7530 gdk_window_set_child_input_shapes (GdkWindow *window)
7532 g_return_if_fail (GDK_IS_WINDOW (window));
7534 do_child_input_shapes (window, FALSE);
7538 * gdk_window_merge_child_input_shapes:
7539 * @window: a #GdkWindow
7541 * Merges the input shape masks for any child windows into the
7542 * input shape mask for @window. i.e. the union of all input masks
7543 * for @window and its children will become the new input mask
7544 * for @window. See gdk_window_input_shape_combine_region().
7546 * This function is distinct from gdk_window_set_child_input_shapes()
7547 * because it includes @window's input shape mask in the set of
7548 * shapes to be merged.
7553 gdk_window_merge_child_input_shapes (GdkWindow *window)
7555 g_return_if_fail (GDK_IS_WINDOW (window));
7557 do_child_input_shapes (window, TRUE);
7562 * gdk_window_set_static_gravities:
7563 * @window: a #GdkWindow
7564 * @use_static: %TRUE to turn on static gravity
7566 * Set the bit gravity of the given window to static, and flag it so
7567 * all children get static subwindow gravity. This is used if you are
7568 * implementing scary features that involve deep knowledge of the
7569 * windowing system. Don't worry about it unless you have to.
7571 * Return value: %TRUE if the server supports static gravity
7574 gdk_window_set_static_gravities (GdkWindow *window,
7575 gboolean use_static)
7577 GdkWindowObject *private;
7578 GdkWindowImplIface *impl_iface;
7580 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7582 private = (GdkWindowObject *) window;
7584 if (gdk_window_has_impl (private))
7586 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7587 return impl_iface->set_static_gravities (window, use_static);
7594 * gdk_window_get_composited:
7595 * @window: a #GdkWindow
7597 * Determines whether @window is composited.
7599 * See gdk_window_set_composited().
7601 * Returns: %TRUE if the window is composited.
7606 gdk_window_get_composited (GdkWindow *window)
7608 GdkWindowObject *private;
7610 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7612 private = (GdkWindowObject *)window;
7614 return private->composited;
7618 * gdk_window_set_composited:
7619 * @window: a #GdkWindow
7620 * @composited: %TRUE to set the window as composited
7622 * Sets a #GdkWindow as composited, or unsets it. Composited
7623 * windows do not automatically have their contents drawn to
7624 * the screen. Drawing is redirected to an offscreen buffer
7625 * and an expose event is emitted on the parent of the composited
7626 * window. It is the responsibility of the parent's expose handler
7627 * to manually merge the off-screen content onto the screen in
7628 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7631 * It only makes sense for child windows to be composited; see
7632 * gdk_window_set_opacity() if you need translucent toplevel
7635 * An additional effect of this call is that the area of this
7636 * window is no longer clipped from regions marked for
7637 * invalidation on its parent. Draws done on the parent
7638 * window are also no longer clipped by the child.
7640 * This call is only supported on some systems (currently,
7641 * only X11 with new enough Xcomposite and Xdamage extensions).
7642 * You must call gdk_display_supports_composite() to check if
7643 * setting a window as composited is supported before
7644 * attempting to do so.
7649 gdk_window_set_composited (GdkWindow *window,
7650 gboolean composited)
7652 GdkWindowObject *private = (GdkWindowObject *)window;
7653 GdkDisplay *display;
7655 g_return_if_fail (GDK_IS_WINDOW (window));
7657 composited = composited != FALSE;
7659 if (private->composited == composited)
7663 gdk_window_ensure_native (window);
7665 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
7667 if (!gdk_display_supports_composite (display) && composited)
7669 g_warning ("gdk_window_set_composited called but "
7670 "compositing is not supported");
7674 _gdk_windowing_window_set_composited (window, composited);
7676 recompute_visible_regions (private, TRUE, FALSE);
7678 if (GDK_WINDOW_IS_MAPPED (window))
7679 gdk_window_invalidate_in_parent (private);
7681 private->composited = composited;
7685 * gdk_window_get_modal_hint:
7686 * @window: A toplevel #GdkWindow.
7688 * Determines whether or not the window manager is hinted that @window
7689 * has modal behaviour.
7691 * Return value: whether or not the window has the modal hint set.
7696 gdk_window_get_modal_hint (GdkWindow *window)
7698 GdkWindowObject *private;
7700 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7702 private = (GdkWindowObject*) window;
7704 return private->modal_hint;
7708 * gdk_window_get_accept_focus:
7709 * @window: a toplevel #GdkWindow.
7711 * Determines whether or not the desktop environment shuld be hinted that
7712 * the window does not want to receive input focus.
7714 * Return value: whether or not the window should receive input focus.
7719 gdk_window_get_accept_focus (GdkWindow *window)
7721 GdkWindowObject *private;
7723 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7725 private = (GdkWindowObject *)window;
7727 return private->accept_focus;
7731 * gdk_window_get_focus_on_map:
7732 * @window: a toplevel #GdkWindow.
7734 * Determines whether or not the desktop environment should be hinted that the
7735 * window does not want to receive input focus when it is mapped.
7737 * Return value: whether or not the window wants to receive input focus when
7743 gdk_window_get_focus_on_map (GdkWindow *window)
7745 GdkWindowObject *private;
7747 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7749 private = (GdkWindowObject *)window;
7751 return private->focus_on_map;
7755 * gdk_window_is_input_only:
7756 * @window: a toplevel #GdkWindow
7758 * Determines whether or not the window is an input only window.
7760 * Return value: %TRUE if @window is input only
7765 gdk_window_is_input_only (GdkWindow *window)
7767 GdkWindowObject *private;
7769 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7771 private = (GdkWindowObject *)window;
7773 return private->input_only;
7777 * gdk_window_is_shaped:
7778 * @window: a toplevel #GdkWindow
7780 * Determines whether or not the window is shaped.
7782 * Return value: %TRUE if @window is shaped
7787 gdk_window_is_shaped (GdkWindow *window)
7789 GdkWindowObject *private;
7791 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7793 private = (GdkWindowObject *)window;
7795 return private->shaped;
7799 window_get_size_rectangle (GdkWindow *window,
7802 GdkWindowObject *private = (GdkWindowObject *) window;
7804 rect->x = rect->y = 0;
7805 rect->width = private->width;
7806 rect->height = private->height;
7809 /* Calculates the real clipping region for a window, in window coordinates,
7810 * taking into account other windows, gc clip region and gc clip mask.
7813 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7814 GdkWindow *base_window,
7815 gboolean do_children,
7816 gint *base_x_offset,
7817 gint *base_y_offset)
7819 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
7820 GdkRectangle visible_rect;
7821 cairo_region_t *real_clip_region;
7822 gint x_offset, y_offset;
7823 GdkWindowObject *parentwin, *lastwin;
7830 if (!private->viewable || private->input_only)
7831 return cairo_region_create ();
7833 window_get_size_rectangle (window, &visible_rect);
7835 /* real_clip_region is in window coordinates */
7836 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7838 x_offset = y_offset = 0;
7842 parentwin = lastwin;
7844 parentwin = lastwin->parent;
7846 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7847 for (; parentwin != NULL &&
7848 (parentwin == private || lastwin != (GdkWindowObject*) base_window);
7849 lastwin = parentwin, parentwin = lastwin->parent)
7852 GdkRectangle real_clip_rect;
7854 if (parentwin != private)
7856 x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
7857 y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
7860 /* children is ordered in reverse stack order */
7861 for (cur = parentwin->children;
7862 cur && cur->data != lastwin;
7865 GdkWindow *child = cur->data;
7866 GdkWindowObject *child_private = (GdkWindowObject *)child;
7868 if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
7871 /* Ignore offscreen children, as they don't draw in their parent and
7872 * don't take part in the clipping */
7873 if (gdk_window_is_offscreen (child_private))
7876 window_get_size_rectangle (child, &visible_rect);
7878 /* Convert rect to "window" coords */
7879 visible_rect.x += child_private->x - x_offset;
7880 visible_rect.y += child_private->y - y_offset;
7882 /* This shortcut is really necessary for performance when there are a lot of windows */
7883 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7884 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7885 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7886 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7887 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7890 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7893 /* Clip to the parent */
7894 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7895 /* Convert rect to "window" coords */
7896 visible_rect.x += - x_offset;
7897 visible_rect.y += - y_offset;
7899 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7903 *base_x_offset = x_offset;
7905 *base_y_offset = y_offset;
7907 return real_clip_region;
7911 _gdk_window_add_damage (GdkWindow *toplevel,
7912 cairo_region_t *damaged_region)
7914 GdkDisplay *display;
7915 GdkEvent event = { 0, };
7916 event.expose.type = GDK_DAMAGE;
7917 event.expose.window = toplevel;
7918 event.expose.send_event = FALSE;
7919 event.expose.region = damaged_region;
7920 cairo_region_get_extents (event.expose.region, &event.expose.area);
7921 display = gdk_drawable_get_display (event.expose.window);
7922 _gdk_event_queue_append (display, gdk_event_copy (&event));
7925 /* Gets the toplevel for a window as used for events,
7926 i.e. including offscreen parents */
7927 static GdkWindowObject *
7928 get_event_parent (GdkWindowObject *window)
7930 if (gdk_window_is_offscreen (window))
7931 return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7933 return window->parent;
7936 /* Gets the toplevel for a window as used for events,
7937 i.e. including offscreen parents going up to the native
7940 get_event_toplevel (GdkWindow *w)
7942 GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
7943 GdkWindowObject *parent;
7945 while ((parent = get_event_parent (private)) != NULL &&
7946 (parent->window_type != GDK_WINDOW_ROOT))
7949 return GDK_WINDOW (private);
7953 _gdk_window_event_parent_of (GdkWindow *parent,
7964 w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
7971 update_cursor (GdkDisplay *display,
7974 GdkWindowObject *cursor_window, *parent, *toplevel;
7975 GdkWindow *pointer_window;
7976 GdkWindowImplIface *impl_iface;
7977 GdkPointerWindowInfo *pointer_info;
7978 GdkDeviceGrabInfo *grab;
7981 pointer_info = _gdk_display_get_pointer_info (display, device);
7982 pointer_window = pointer_info->window_under_pointer;
7984 /* We ignore the serials here and just pick the last grab
7985 we've sent, as that would shortly be used anyway. */
7986 grab = _gdk_display_get_last_device_grab (display, device);
7989 /* the pointer is not in a descendant of the grab window */
7990 !_gdk_window_event_parent_of (grab->window, pointer_window))
7992 /* use the cursor from the grab window */
7993 cursor_window = (GdkWindowObject *) grab->window;
7997 /* otherwise use the cursor from the pointer window */
7998 cursor_window = (GdkWindowObject *) pointer_window;
8001 /* Find the first window with the cursor actually set, as
8002 the cursor is inherited from the parent */
8003 while (cursor_window->cursor == NULL &&
8004 (parent = get_event_parent (cursor_window)) != NULL &&
8005 parent->window_type != GDK_WINDOW_ROOT)
8006 cursor_window = parent;
8008 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
8011 cursor = cursor_window->cursor;
8013 /* Set all cursors on toplevel, otherwise its tricky to keep track of
8014 * which native window has what cursor set. */
8015 toplevel = (GdkWindowObject *) get_event_toplevel (pointer_window);
8016 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
8017 impl_iface->set_device_cursor ((GdkWindow *) toplevel, device, cursor);
8021 point_in_window (GdkWindowObject *window,
8026 x >= 0 && x < window->width &&
8027 y >= 0 && y < window->height &&
8028 (window->shape == NULL ||
8029 cairo_region_contains_point (window->shape,
8031 (window->input_shape == NULL ||
8032 cairo_region_contains_point (window->input_shape,
8037 convert_native_coords_to_toplevel (GdkWindow *window,
8040 gdouble *toplevel_x,
8041 gdouble *toplevel_y)
8043 GdkWindowObject *private = (GdkWindowObject *)window;
8049 while (!gdk_window_is_toplevel (private))
8053 private = private->parent;
8059 return (GdkWindow *)private;
8063 convert_toplevel_coords_to_window (GdkWindow *window,
8069 GdkWindowObject *private;
8070 GdkWindowObject *parent;
8072 GList *children, *l;
8074 private = GDK_WINDOW_OBJECT (window);
8080 while ((parent = get_event_parent (private)) != NULL &&
8081 (parent->window_type != GDK_WINDOW_ROOT))
8083 children = g_list_prepend (children, private);
8087 for (l = children; l != NULL; l = l->next)
8088 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
8090 g_list_free (children);
8096 static GdkWindowObject *
8097 pick_embedded_child (GdkWindowObject *window,
8101 GdkWindowObject *res;
8104 g_signal_emit (window,
8105 signals[PICK_EMBEDDED_CHILD], 0,
8112 _gdk_window_find_child_at (GdkWindow *window,
8116 GdkWindowObject *private, *sub;
8117 double child_x, child_y;
8120 private = (GdkWindowObject *)window;
8122 if (point_in_window (private, x, y))
8124 /* Children is ordered in reverse stack order, i.e. first is topmost */
8125 for (l = private->children; l != NULL; l = l->next)
8129 if (!GDK_WINDOW_IS_MAPPED (sub))
8132 gdk_window_coords_from_parent ((GdkWindow *)sub,
8134 &child_x, &child_y);
8135 if (point_in_window (sub, child_x, child_y))
8136 return (GdkWindow *)sub;
8139 if (private->num_offscreen_children > 0)
8141 sub = pick_embedded_child (private,
8144 return (GdkWindow *)sub;
8152 _gdk_window_find_descendant_at (GdkWindow *toplevel,
8158 GdkWindowObject *private, *sub;
8159 gdouble child_x, child_y;
8163 private = (GdkWindowObject *)toplevel;
8165 if (point_in_window (private, x, y))
8170 /* Children is ordered in reverse stack order, i.e. first is topmost */
8171 for (l = private->children; l != NULL; l = l->next)
8175 if (!GDK_WINDOW_IS_MAPPED (sub))
8178 gdk_window_coords_from_parent ((GdkWindow *)sub,
8180 &child_x, &child_y);
8181 if (point_in_window (sub, child_x, child_y))
8191 private->num_offscreen_children > 0)
8193 sub = pick_embedded_child (private,
8199 from_embedder (sub, x, y, &x, &y);
8207 /* Not in window at all */
8216 return (GdkWindow *)private;
8221 * @window: a toplevel #GdkWindow
8223 * Emits a short beep associated to @window in the appropriate
8224 * display, if supported. Otherwise, emits a short beep on
8225 * the display just as gdk_display_beep().
8230 gdk_window_beep (GdkWindow *window)
8232 GdkDisplay *display;
8233 GdkWindow *toplevel;
8235 g_return_if_fail (GDK_IS_WINDOW (window));
8237 if (GDK_WINDOW_DESTROYED (window))
8240 toplevel = get_event_toplevel (window);
8241 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
8243 if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
8244 _gdk_windowing_window_beep (toplevel);
8246 gdk_display_beep (display);
8250 * gdk_window_set_support_multidevice:
8251 * @window: a #GdkWindow.
8252 * @support_multidevice: %TRUE to enable multidevice support in @window.
8254 * This function will enable multidevice features in @window.
8256 * Multidevice aware windows will need to handle properly multiple,
8257 * per device enter/leave events, device grabs and grab ownerships.
8262 gdk_window_set_support_multidevice (GdkWindow *window,
8263 gboolean support_multidevice)
8265 GdkWindowObject *private = (GdkWindowObject *) window;
8267 g_return_if_fail (GDK_IS_WINDOW (window));
8269 if (GDK_WINDOW_DESTROYED (window))
8272 if (private->support_multidevice == support_multidevice)
8275 private->support_multidevice = support_multidevice;
8277 /* FIXME: What to do if called when some pointers are inside the window ? */
8281 * gdk_window_get_support_multidevice:
8282 * @window: a #GdkWindow.
8284 * Returns %TRUE if the window is aware of the existence of multiple
8287 * Returns: %TRUE if the window handles multidevice features.
8292 gdk_window_get_support_multidevice (GdkWindow *window)
8294 GdkWindowObject *private = (GdkWindowObject *) window;
8296 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8298 if (GDK_WINDOW_DESTROYED (window))
8301 return private->support_multidevice;
8304 static const guint type_masks[] = {
8305 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8306 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8307 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8308 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8309 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8310 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8311 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8312 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8313 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8314 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8315 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8316 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8317 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8318 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8319 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8320 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8321 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8322 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8323 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8324 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8325 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8326 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8327 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8328 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8329 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8330 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8331 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8332 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8333 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8334 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8335 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8336 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8337 0, /* GDK_WINDOW_STATE = 32 */
8338 0, /* GDK_SETTING = 33 */
8339 0, /* GDK_OWNER_CHANGE = 34 */
8340 0, /* GDK_GRAB_BROKEN = 35 */
8341 0, /* GDK_DAMAGE = 36 */
8343 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8345 /* send motion events if the right buttons are down */
8347 update_evmask_for_button_motion (guint evmask,
8348 GdkModifierType mask)
8350 if (evmask & GDK_BUTTON_MOTION_MASK &&
8351 mask & (GDK_BUTTON1_MASK |
8356 evmask |= GDK_POINTER_MOTION_MASK;
8358 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8359 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8360 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8361 evmask |= GDK_POINTER_MOTION_MASK;
8367 is_button_type (GdkEventType type)
8369 return type == GDK_BUTTON_PRESS ||
8370 type == GDK_2BUTTON_PRESS ||
8371 type == GDK_3BUTTON_PRESS ||
8372 type == GDK_BUTTON_RELEASE ||
8377 is_motion_type (GdkEventType type)
8379 return type == GDK_MOTION_NOTIFY ||
8380 type == GDK_ENTER_NOTIFY ||
8381 type == GDK_LEAVE_NOTIFY;
8384 static GdkWindowObject *
8385 find_common_ancestor (GdkWindowObject *win1,
8386 GdkWindowObject *win2)
8388 GdkWindowObject *tmp;
8389 GList *path1 = NULL, *path2 = NULL;
8390 GList *list1, *list2;
8393 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8395 path1 = g_list_prepend (path1, tmp);
8396 tmp = get_event_parent (tmp);
8400 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8402 path2 = g_list_prepend (path2, tmp);
8403 tmp = get_event_parent (tmp);
8409 while (list1 && list2 && (list1->data == list2->data))
8411 tmp = (GdkWindowObject *)list1->data;
8412 list1 = g_list_next (list1);
8413 list2 = g_list_next (list2);
8415 g_list_free (path1);
8416 g_list_free (path2);
8422 _gdk_make_event (GdkWindow *window,
8424 GdkEvent *event_in_queue,
8425 gboolean before_event)
8427 GdkEvent *event = gdk_event_new (type);
8429 GdkModifierType the_state;
8431 the_time = gdk_event_get_time (event_in_queue);
8432 gdk_event_get_state (event_in_queue, &the_state);
8434 event->any.window = g_object_ref (window);
8435 event->any.send_event = FALSE;
8436 if (event_in_queue && event_in_queue->any.send_event)
8437 event->any.send_event = TRUE;
8441 case GDK_MOTION_NOTIFY:
8442 event->motion.time = the_time;
8443 event->motion.axes = NULL;
8444 event->motion.state = the_state;
8447 case GDK_BUTTON_PRESS:
8448 case GDK_2BUTTON_PRESS:
8449 case GDK_3BUTTON_PRESS:
8450 case GDK_BUTTON_RELEASE:
8451 event->button.time = the_time;
8452 event->button.axes = NULL;
8453 event->button.state = the_state;
8457 event->scroll.time = the_time;
8458 event->scroll.state = the_state;
8462 case GDK_KEY_RELEASE:
8463 event->key.time = the_time;
8464 event->key.state = the_state;
8467 case GDK_ENTER_NOTIFY:
8468 case GDK_LEAVE_NOTIFY:
8469 event->crossing.time = the_time;
8470 event->crossing.state = the_state;
8473 case GDK_PROPERTY_NOTIFY:
8474 event->property.time = the_time;
8475 event->property.state = the_state;
8478 case GDK_SELECTION_CLEAR:
8479 case GDK_SELECTION_REQUEST:
8480 case GDK_SELECTION_NOTIFY:
8481 event->selection.time = the_time;
8484 case GDK_PROXIMITY_IN:
8485 case GDK_PROXIMITY_OUT:
8486 event->proximity.time = the_time;
8489 case GDK_DRAG_ENTER:
8490 case GDK_DRAG_LEAVE:
8491 case GDK_DRAG_MOTION:
8492 case GDK_DRAG_STATUS:
8493 case GDK_DROP_START:
8494 case GDK_DROP_FINISHED:
8495 event->dnd.time = the_time;
8498 case GDK_FOCUS_CHANGE:
8502 case GDK_CLIENT_EVENT:
8503 case GDK_VISIBILITY_NOTIFY:
8515 _gdk_event_queue_insert_before (gdk_drawable_get_display (window), event_in_queue, event);
8517 _gdk_event_queue_insert_after (gdk_drawable_get_display (window), event_in_queue, event);
8520 _gdk_event_queue_append (gdk_drawable_get_display (window), event);
8526 send_crossing_event (GdkDisplay *display,
8527 GdkWindowObject *toplevel,
8528 GdkWindowObject *window,
8530 GdkCrossingMode mode,
8531 GdkNotifyType notify_type,
8532 GdkWindow *subwindow,
8536 GdkModifierType mask,
8538 GdkEvent *event_in_queue,
8542 guint32 window_event_mask, type_event_mask;
8543 GdkDeviceGrabInfo *grab;
8544 gboolean block_event = FALSE;
8546 grab = _gdk_display_has_device_grab (display, device, serial);
8549 !grab->owner_events)
8551 /* !owner_event => only report events wrt grab window, ignore rest */
8552 if ((GdkWindow *)window != grab->window)
8554 window_event_mask = grab->event_mask;
8557 window_event_mask = window->event_mask;
8559 if (type == GDK_LEAVE_NOTIFY)
8561 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8562 window->devices_inside = g_list_remove (window->devices_inside, device);
8564 if (!window->support_multidevice && window->devices_inside)
8566 /* Block leave events unless it's the last pointer */
8572 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8574 if (!window->support_multidevice && window->devices_inside)
8576 /* Only emit enter events for the first device */
8580 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8581 device->mode != GDK_MODE_DISABLED &&
8582 !g_list_find (window->devices_inside, device))
8583 window->devices_inside = g_list_prepend (window->devices_inside, device);
8589 if (window_event_mask & type_event_mask)
8591 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8592 gdk_event_set_device (event, device);
8593 event->crossing.time = time_;
8594 event->crossing.subwindow = subwindow;
8596 g_object_ref (subwindow);
8597 convert_toplevel_coords_to_window ((GdkWindow *)window,
8598 toplevel_x, toplevel_y,
8599 &event->crossing.x, &event->crossing.y);
8600 event->crossing.x_root = toplevel_x + toplevel->x;
8601 event->crossing.y_root = toplevel_y + toplevel->y;
8602 event->crossing.mode = mode;
8603 event->crossing.detail = notify_type;
8604 event->crossing.focus = FALSE;
8605 event->crossing.state = mask;
8610 /* The coordinates are in the toplevel window that src/dest are in.
8611 * src and dest are always (if != NULL) in the same toplevel, as
8612 * we get a leave-notify and set the window_under_pointer to null
8613 * before crossing to another toplevel.
8616 _gdk_synthesize_crossing_events (GdkDisplay *display,
8620 GdkCrossingMode mode,
8623 GdkModifierType mask,
8625 GdkEvent *event_in_queue,
8627 gboolean non_linear)
8630 GdkWindowObject *win, *last, *next;
8634 GdkWindowObject *toplevel;
8635 GdkNotifyType notify_type;
8637 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8639 a = (GdkWindowObject *)src;
8640 b = (GdkWindowObject *)dest;
8642 return; /* No crossings generated between src and dest */
8644 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8646 if (a && gdk_window_get_device_events (src, device) == 0)
8649 if (b && gdk_window_get_device_events (dest, device) == 0)
8656 c = find_common_ancestor (a, b);
8658 non_linear |= (c != a) && (c != b);
8660 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8662 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
8664 /* Traverse up from a to (excluding) c sending leave events */
8666 notify_type = GDK_NOTIFY_NONLINEAR;
8668 notify_type = GDK_NOTIFY_INFERIOR;
8670 notify_type = GDK_NOTIFY_ANCESTOR;
8671 send_crossing_event (display, toplevel,
8672 a, GDK_LEAVE_NOTIFY,
8676 toplevel_x, toplevel_y,
8684 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8686 notify_type = GDK_NOTIFY_VIRTUAL;
8689 win = get_event_parent (a);
8690 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8692 send_crossing_event (display, toplevel,
8693 win, GDK_LEAVE_NOTIFY,
8698 toplevel_x, toplevel_y,
8704 win = get_event_parent (win);
8709 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8711 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
8713 /* Traverse down from c to b */
8717 win = get_event_parent (b);
8718 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8720 path = g_list_prepend (path, win);
8721 win = get_event_parent (win);
8725 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8727 notify_type = GDK_NOTIFY_VIRTUAL;
8732 win = (GdkWindowObject *)list->data;
8733 list = g_list_next (list);
8735 next = (GdkWindowObject *)list->data;
8739 send_crossing_event (display, toplevel,
8740 win, GDK_ENTER_NOTIFY,
8745 toplevel_x, toplevel_y,
8755 notify_type = GDK_NOTIFY_NONLINEAR;
8757 notify_type = GDK_NOTIFY_ANCESTOR;
8759 notify_type = GDK_NOTIFY_INFERIOR;
8761 send_crossing_event (display, toplevel,
8762 b, GDK_ENTER_NOTIFY,
8767 toplevel_x, toplevel_y,
8774 /* Returns the window inside the event window with the pointer in it
8775 * at the specified coordinates, or NULL if its not in any child of
8776 * the toplevel. It also takes into account !owner_events grabs.
8779 get_pointer_window (GdkDisplay *display,
8780 GdkWindow *event_window,
8786 GdkWindow *pointer_window;
8787 GdkDeviceGrabInfo *grab;
8788 GdkPointerWindowInfo *pointer_info;
8790 pointer_info = _gdk_display_get_pointer_info (display, device);
8792 if (event_window == pointer_info->toplevel_under_pointer)
8794 _gdk_window_find_descendant_at (event_window,
8795 toplevel_x, toplevel_y,
8798 pointer_window = NULL;
8800 grab = _gdk_display_has_device_grab (display, device, serial);
8802 !grab->owner_events &&
8803 pointer_window != grab->window)
8804 pointer_window = NULL;
8806 return pointer_window;
8810 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8814 GdkPointerWindowInfo *device_info;
8816 /* We don't track this if all native, and it can cause issues
8817 with the update_cursor call below */
8818 if (_gdk_native_windows)
8821 device_info = _gdk_display_get_pointer_info (display, device);
8823 if (device_info->window_under_pointer)
8824 g_object_unref (device_info->window_under_pointer);
8825 device_info->window_under_pointer = window;
8829 g_object_ref (window);
8830 update_cursor (display, device);
8833 _gdk_display_enable_motion_hints (display, device);
8838 * @window: the #GdkWindow which will own the grab (the grab window).
8839 * @owner_events: if %FALSE then all pointer events are reported with respect to
8840 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8841 * events for this application are reported as normal, but pointer events outside
8842 * this application are reported with respect to @window and only if selected by
8843 * @event_mask. In either mode, unreported events are discarded.
8844 * @event_mask: specifies the event mask, which is used in accordance with
8845 * @owner_events. Note that only pointer events (i.e. button and motion events)
8847 * @confine_to: If non-%NULL, the pointer will be confined to this
8848 * window during the grab. If the pointer is outside @confine_to, it will
8849 * automatically be moved to the closest edge of @confine_to and enter
8850 * and leave events will be generated as necessary.
8851 * @cursor: the cursor to display while the grab is active. If this is %NULL then
8852 * the normal cursors are used for @window and its descendants, and the cursor
8853 * for @window is used for all other windows.
8854 * @time_: the timestamp of the event which led to this pointer grab. This usually
8855 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8856 * the time isn't known.
8858 * Grabs the pointer (usually a mouse) so that all events are passed to this
8859 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8860 * the grab window becomes unviewable.
8861 * This overrides any previous pointer grab by this client.
8863 * Pointer grabs are used for operations which need complete control over mouse
8864 * events, even if the mouse leaves the application.
8865 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8866 * the #GtkHPaned and #GtkVPaned widgets, and for resizing columns in #GtkCList
8869 * Note that if the event mask of an X window has selected both button press and
8870 * button release events, then a button press event will cause an automatic
8871 * pointer grab until the button is released.
8872 * X does this automatically since most applications expect to receive button
8873 * press and release events in pairs.
8874 * It is equivalent to a pointer grab on the window with @owner_events set to
8877 * If you set up anything at the time you take the grab that needs to be cleaned
8878 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8879 * are emitted when the grab ends unvoluntarily.
8881 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8883 * Deprecated: 3.0: Use gdk_device_grab() instead.
8886 gdk_pointer_grab (GdkWindow * window,
8887 gboolean owner_events,
8888 GdkEventMask event_mask,
8889 GdkWindow * confine_to,
8894 GdkDisplay *display;
8895 GdkDeviceManager *device_manager;
8897 GdkGrabStatus res = 0;
8899 GList *devices, *dev;
8901 g_return_val_if_fail (window != NULL, 0);
8902 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8903 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8905 /* We need a native window for confine to to work, ensure we have one */
8908 if (!gdk_window_ensure_native (confine_to))
8910 g_warning ("Can't confine to grabbed window, not native");
8915 /* Non-viewable client side window => fail */
8916 if (!_gdk_window_has_impl (window) &&
8917 !gdk_window_is_viewable (window))
8918 return GDK_GRAB_NOT_VIEWABLE;
8920 if (_gdk_native_windows)
8923 native = gdk_window_get_toplevel (window);
8924 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
8926 native = gdk_offscreen_window_get_embedder (native);
8928 if (native == NULL ||
8929 (!_gdk_window_has_impl (native) &&
8930 !gdk_window_is_viewable (native)))
8931 return GDK_GRAB_NOT_VIEWABLE;
8933 native = gdk_window_get_toplevel (native);
8936 display = gdk_drawable_get_display (window);
8938 serial = _gdk_windowing_window_get_next_serial (display);
8939 device_manager = gdk_display_get_device_manager (display);
8940 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8942 /* FIXME: Should this be generic to all backends? */
8943 /* FIXME: What happens with extended devices? */
8944 for (dev = devices; dev; dev = dev->next)
8948 if (device->source != GDK_SOURCE_MOUSE)
8951 res = _gdk_windowing_device_grab (device,
8955 get_native_grab_event_mask (event_mask),
8960 if (res == GDK_GRAB_SUCCESS)
8961 _gdk_display_add_device_grab (display,
8973 /* FIXME: handle errors when grabbing */
8975 g_list_free (devices);
8981 * gdk_keyboard_grab:
8982 * @window: the #GdkWindow which will own the grab (the grab window).
8983 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8984 * @window. If %TRUE then keyboard events for this application are
8985 * reported as normal, but keyboard events outside this application
8986 * are reported with respect to @window. Both key press and key
8987 * release events are always reported, independant of the event mask
8988 * set by the application.
8989 * @time: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8992 * Grabs the keyboard so that all events are passed to this
8993 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8994 * This overrides any previous keyboard grab by this client.
8996 * If you set up anything at the time you take the grab that needs to be cleaned
8997 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8998 * are emitted when the grab ends unvoluntarily.
9000 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
9002 * Deprecated: 3.0: Use gdk_device_grab() instead.
9005 gdk_keyboard_grab (GdkWindow *window,
9006 gboolean owner_events,
9010 GdkDisplay *display;
9011 GdkDeviceManager *device_manager;
9013 GdkGrabStatus res = 0;
9015 GList *devices, *dev;
9017 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
9019 /* Non-viewable client side window => fail */
9020 if (!_gdk_window_has_impl (window) &&
9021 !gdk_window_is_viewable (window))
9022 return GDK_GRAB_NOT_VIEWABLE;
9024 if (_gdk_native_windows)
9027 native = gdk_window_get_toplevel (window);
9029 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
9031 native = gdk_offscreen_window_get_embedder (native);
9033 if (native == NULL ||
9034 (!_gdk_window_has_impl (native) &&
9035 !gdk_window_is_viewable (native)))
9036 return GDK_GRAB_NOT_VIEWABLE;
9038 native = gdk_window_get_toplevel (native);
9041 display = gdk_drawable_get_display (window);
9043 serial = _gdk_windowing_window_get_next_serial (display);
9044 device_manager = gdk_display_get_device_manager (display);
9045 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
9047 /* FIXME: Should this be generic to all backends? */
9048 /* FIXME: What happens with extended devices? */
9049 for (dev = devices; dev; dev = dev->next)
9053 if (device->source != GDK_SOURCE_KEYBOARD)
9056 res = _gdk_windowing_device_grab (device,
9060 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
9065 if (res == GDK_GRAB_SUCCESS)
9066 _gdk_display_add_device_grab (display,
9077 /* FIXME: handle errors when grabbing */
9079 g_list_free (devices);
9085 * gdk_window_geometry_changed:
9086 * @window: an embedded offscreen #GdkWindow
9088 * This function informs GDK that the geometry of an embedded
9089 * offscreen window has changed. This is necessary for GDK to keep
9090 * track of which offscreen window the pointer is in.
9095 gdk_window_geometry_changed (GdkWindow *window)
9097 _gdk_synthesize_crossing_events_for_geometry_change (window);
9101 do_synthesize_crossing_event (gpointer data)
9103 GdkDisplay *display;
9104 GdkWindow *changed_toplevel;
9105 GdkWindowObject *changed_toplevel_priv;
9106 GHashTableIter iter;
9107 gpointer key, value;
9110 changed_toplevel = data;
9111 changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
9113 changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
9115 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9118 display = gdk_drawable_get_display (changed_toplevel);
9119 serial = _gdk_windowing_window_get_next_serial (display);
9120 g_hash_table_iter_init (&iter, display->pointers_info);
9122 while (g_hash_table_iter_next (&iter, &key, &value))
9124 GdkWindow *new_window_under_pointer;
9125 GdkPointerWindowInfo *pointer_info = value;
9126 GdkDevice *device = key;
9128 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9130 new_window_under_pointer =
9131 get_pointer_window (display, changed_toplevel,
9133 pointer_info->toplevel_x,
9134 pointer_info->toplevel_y,
9136 if (new_window_under_pointer != pointer_info->window_under_pointer)
9138 _gdk_synthesize_crossing_events (display,
9139 pointer_info->window_under_pointer,
9140 new_window_under_pointer,
9142 GDK_CROSSING_NORMAL,
9143 pointer_info->toplevel_x,
9144 pointer_info->toplevel_y,
9145 pointer_info->state,
9150 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9159 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9161 GdkDisplay *display;
9162 GdkWindow *toplevel;
9163 GdkWindowObject *toplevel_priv;
9165 if (_gdk_native_windows)
9166 return; /* We use the native crossing events if all native */
9168 display = gdk_drawable_get_display (changed_window);
9170 toplevel = get_event_toplevel (changed_window);
9171 toplevel_priv = (GdkWindowObject *) toplevel;
9173 if (!toplevel_priv->synthesize_crossing_event_queued)
9175 toplevel_priv->synthesize_crossing_event_queued = TRUE;
9177 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9178 do_synthesize_crossing_event,
9179 g_object_ref (toplevel),
9184 /* Don't use for crossing events */
9186 get_event_window (GdkDisplay *display,
9188 GdkWindow *pointer_window,
9190 GdkModifierType mask,
9195 GdkWindow *grab_window;
9197 GdkDeviceGrabInfo *grab;
9199 grab = _gdk_display_has_device_grab (display, device, serial);
9201 if (grab != NULL && !grab->owner_events)
9203 evmask = grab->event_mask;
9204 evmask = update_evmask_for_button_motion (evmask, mask);
9206 grab_window = grab->window;
9208 if (evmask & type_masks[type])
9211 *evmask_out = evmask;
9218 w = (GdkWindowObject *)pointer_window;
9221 evmask = w->event_mask;
9222 evmask = update_evmask_for_button_motion (evmask, mask);
9224 if (evmask & type_masks[type])
9227 *evmask_out = evmask;
9228 return (GdkWindow *)w;
9231 w = get_event_parent (w);
9237 evmask = grab->event_mask;
9238 evmask = update_evmask_for_button_motion (evmask, mask);
9240 if (evmask & type_masks[type])
9243 *evmask_out = evmask;
9244 return grab->window;
9254 proxy_pointer_event (GdkDisplay *display,
9255 GdkEvent *source_event,
9258 GdkWindow *toplevel_window, *event_window;
9259 GdkWindow *pointer_window;
9260 GdkPointerWindowInfo *pointer_info;
9264 gdouble toplevel_x, toplevel_y;
9266 gboolean non_linear;
9268 event_window = source_event->any.window;
9269 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9270 gdk_event_get_state (source_event, &state);
9271 time_ = gdk_event_get_time (source_event);
9272 device = gdk_event_get_device (source_event);
9273 pointer_info = _gdk_display_get_pointer_info (display, device);
9274 toplevel_window = convert_native_coords_to_toplevel (event_window,
9275 toplevel_x, toplevel_y,
9276 &toplevel_x, &toplevel_y);
9279 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9280 source_event->type == GDK_ENTER_NOTIFY) &&
9281 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9282 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9285 /* If we get crossing events with subwindow unexpectedly being NULL
9286 that means there is a native subwindow that gdk doesn't know about.
9287 We track these and forward them, with the correct virtual window
9289 This is important to get right, as metacity uses gdk for the frame
9290 windows, but gdk doesn't know about the client windows reparented
9292 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9293 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9294 (source_event->type == GDK_ENTER_NOTIFY &&
9295 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9296 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9297 source_event->crossing.subwindow == NULL)
9299 /* Left for an unknown (to gdk) subwindow */
9301 /* Send leave events from window under pointer to event window
9302 that will get the subwindow == NULL window */
9303 _gdk_synthesize_crossing_events (display,
9304 pointer_info->window_under_pointer,
9307 source_event->crossing.mode,
9308 toplevel_x, toplevel_y,
9314 /* Send subwindow == NULL event */
9315 send_crossing_event (display,
9316 (GdkWindowObject *)toplevel_window,
9317 (GdkWindowObject *)event_window,
9319 source_event->crossing.mode,
9320 source_event->crossing.detail,
9323 toplevel_x, toplevel_y,
9328 _gdk_display_set_window_under_pointer (display, device, NULL);
9332 pointer_window = get_pointer_window (display, toplevel_window, device,
9333 toplevel_x, toplevel_y, serial);
9335 if (((source_event->type == GDK_ENTER_NOTIFY &&
9336 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9337 (source_event->type == GDK_LEAVE_NOTIFY &&
9338 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9339 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9340 source_event->crossing.subwindow == NULL)
9342 /* Entered from an unknown (to gdk) subwindow */
9344 /* Send subwindow == NULL event */
9345 send_crossing_event (display,
9346 (GdkWindowObject *)toplevel_window,
9347 (GdkWindowObject *)event_window,
9349 source_event->crossing.mode,
9350 source_event->crossing.detail,
9353 toplevel_x, toplevel_y,
9358 /* Send enter events from event window to pointer_window */
9359 _gdk_synthesize_crossing_events (display,
9363 source_event->crossing.mode,
9364 toplevel_x, toplevel_y,
9367 serial, non_linear);
9368 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9372 if (pointer_info->window_under_pointer != pointer_window)
9374 /* Either a toplevel crossing notify that ended up inside a child window,
9375 or a motion notify that got into another child window */
9377 /* Different than last time, send crossing events */
9378 _gdk_synthesize_crossing_events (display,
9379 pointer_info->window_under_pointer,
9382 GDK_CROSSING_NORMAL,
9383 toplevel_x, toplevel_y,
9386 serial, non_linear);
9387 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9389 else if (source_event->type == GDK_MOTION_NOTIFY)
9391 GdkWindow *event_win;
9395 event_win = get_event_window (display,
9404 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9405 gdk_window_get_device_events (event_win, device) == 0)
9411 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9413 gulong *device_serial;
9415 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9417 if (!device_serial ||
9418 (*device_serial != 0 &&
9419 serial < *device_serial))
9420 event_win = NULL; /* Ignore event */
9424 *device_serial = G_MAXULONG;
9428 if (event_win && !display->ignore_core_events)
9430 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9431 event->motion.time = time_;
9432 convert_toplevel_coords_to_window (event_win,
9433 toplevel_x, toplevel_y,
9434 &event->motion.x, &event->motion.y);
9435 event->motion.x_root = source_event->motion.x_root;
9436 event->motion.y_root = source_event->motion.y_root;
9437 event->motion.state = state;
9438 event->motion.is_hint = is_hint;
9439 event->motion.device = source_event->motion.device;
9440 event->motion.axes = g_memdup (source_event->motion.axes,
9441 sizeof (gdouble) * source_event->motion.device->num_axes);
9445 /* unlink all move events from queue.
9446 We handle our own, including our emulated masks. */
9450 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9451 GDK_BUTTON2_MASK | \
9452 GDK_BUTTON3_MASK | \
9453 GDK_BUTTON4_MASK | \
9457 proxy_button_event (GdkEvent *source_event,
9460 GdkWindow *toplevel_window, *event_window;
9461 GdkWindow *event_win;
9462 GdkWindow *pointer_window;
9463 GdkWindowObject *parent;
9468 gdouble toplevel_x, toplevel_y;
9469 GdkDisplay *display;
9473 type = source_event->any.type;
9474 event_window = source_event->any.window;
9475 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9476 gdk_event_get_state (source_event, &state);
9477 time_ = gdk_event_get_time (source_event);
9478 device = gdk_event_get_device (source_event);
9479 display = gdk_drawable_get_display (source_event->any.window);
9480 toplevel_window = convert_native_coords_to_toplevel (event_window,
9481 toplevel_x, toplevel_y,
9482 &toplevel_x, &toplevel_y);
9484 if (type == GDK_BUTTON_PRESS &&
9485 !source_event->any.send_event &&
9486 _gdk_display_has_device_grab (display, device, serial) == NULL)
9489 _gdk_window_find_descendant_at (toplevel_window,
9490 toplevel_x, toplevel_y,
9493 /* Find the event window, that gets the grab */
9494 w = (GdkWindowObject *)pointer_window;
9496 (parent = get_event_parent (w)) != NULL &&
9497 parent->window_type != GDK_WINDOW_ROOT)
9499 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9503 pointer_window = (GdkWindow *)w;
9505 _gdk_display_add_device_grab (display,
9511 gdk_window_get_events (pointer_window),
9515 _gdk_display_device_grab_update (display, device, serial);
9518 pointer_window = get_pointer_window (display, toplevel_window, device,
9519 toplevel_x, toplevel_y,
9522 event_win = get_event_window (display,
9528 if (event_win == NULL || display->ignore_core_events)
9531 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9532 gdk_window_get_device_events (event_win, device) == 0)
9535 event = _gdk_make_event (event_win, type, source_event, FALSE);
9539 case GDK_BUTTON_PRESS:
9540 case GDK_BUTTON_RELEASE:
9541 event->button.button = source_event->button.button;
9542 convert_toplevel_coords_to_window (event_win,
9543 toplevel_x, toplevel_y,
9544 &event->button.x, &event->button.y);
9545 event->button.x_root = source_event->button.x_root;
9546 event->button.y_root = source_event->button.y_root;
9547 event->button.state = state;
9548 event->button.device = source_event->button.device;
9549 event->button.axes = g_memdup (source_event->button.axes,
9550 sizeof (gdouble) * source_event->button.device->num_axes);
9552 if (type == GDK_BUTTON_PRESS)
9553 _gdk_event_button_generate (display, event);
9557 event->scroll.direction = source_event->scroll.direction;
9558 convert_toplevel_coords_to_window (event_win,
9559 toplevel_x, toplevel_y,
9560 &event->scroll.x, &event->scroll.y);
9561 event->scroll.x_root = source_event->scroll.x_root;
9562 event->scroll.y_root = source_event->scroll.y_root;
9563 event->scroll.state = state;
9564 event->scroll.device = source_event->scroll.device;
9571 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9574 #ifdef DEBUG_WINDOW_PRINTING
9576 gdk_window_print (GdkWindowObject *window,
9580 const char *window_types[] = {
9590 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9591 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9592 window->x, window->y,
9593 window->width, window->height
9596 if (gdk_window_has_impl (window))
9598 #ifdef GDK_WINDOWING_X11
9599 g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
9603 if (window->window_type != GDK_WINDOW_CHILD)
9604 g_print (" %s", window_types[window->window_type]);
9606 if (window->input_only)
9607 g_print (" input-only");
9610 g_print (" shaped");
9612 if (!gdk_window_is_visible ((GdkWindow *)window))
9613 g_print (" hidden");
9615 g_print (" abs[%d,%d]",
9616 window->abs_x, window->abs_y);
9618 cairo_region_get_extents (window->clip_region, &r);
9619 if (cairo_region_is_empty (window->clip_region))
9620 g_print (" clipbox[empty]");
9622 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9629 gdk_window_print_tree (GdkWindow *window,
9631 gboolean include_input_only)
9633 GdkWindowObject *private;
9636 private = (GdkWindowObject *)window;
9638 if (private->input_only && !include_input_only)
9641 gdk_window_print (private, indent);
9643 for (l = private->children; l != NULL; l = l->next)
9644 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9647 #endif /* DEBUG_WINDOW_PRINTING */
9650 _gdk_windowing_got_event (GdkDisplay *display,
9655 GdkWindow *event_window;
9656 GdkWindowObject *event_private;
9658 gboolean unlink_event;
9659 guint old_state, old_button;
9660 GdkDeviceGrabInfo *button_release_grab;
9661 GdkPointerWindowInfo *pointer_info;
9663 gboolean is_toplevel;
9665 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9666 display->last_event_time = gdk_event_get_time (event);
9668 device = gdk_event_get_device (event);
9674 g_object_get (device, "input-mode", &mode, NULL);
9675 _gdk_display_device_grab_update (display, device, serial);
9677 if (mode == GDK_MODE_DISABLED ||
9678 !_gdk_display_check_grab_ownership (display, device, serial))
9680 /* Device events are blocked by another
9681 * device grab, or the device is disabled
9683 unlink_event = TRUE;
9688 event_window = event->any.window;
9692 pointer_info = _gdk_display_get_pointer_info (display, device);
9693 event_private = GDK_WINDOW_OBJECT (event_window);
9695 #ifdef DEBUG_WINDOW_PRINTING
9696 if (event->type == GDK_KEY_PRESS &&
9697 (event->key.keyval == 0xa7 ||
9698 event->key.keyval == 0xbd))
9700 gdk_window_print_tree (event_window, 0,
9701 event->key.keyval == 0xbd);
9705 if (_gdk_native_windows)
9707 if (event->type == GDK_BUTTON_PRESS &&
9708 !event->any.send_event &&
9709 _gdk_display_has_device_grab (display, device, serial) == NULL)
9711 _gdk_display_add_device_grab (display,
9717 gdk_window_get_events (event_window),
9719 gdk_event_get_time (event),
9721 _gdk_display_device_grab_update (display, device, serial);
9723 if (event->type == GDK_BUTTON_RELEASE &&
9724 !event->any.send_event)
9726 button_release_grab =
9727 _gdk_display_has_device_grab (display, device, serial);
9728 if (button_release_grab &&
9729 button_release_grab->implicit &&
9730 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9732 button_release_grab->serial_end = serial;
9733 button_release_grab->implicit_ungrab = FALSE;
9734 _gdk_display_device_grab_update (display, device, serial);
9738 if (event->type == GDK_BUTTON_PRESS)
9739 _gdk_event_button_generate (display, event);
9744 if (event->type == GDK_VISIBILITY_NOTIFY)
9746 event_private->native_visibility = event->visibility.state;
9747 gdk_window_update_visibility_recursively (event_private,
9752 if (!(is_button_type (event->type) ||
9753 is_motion_type (event->type)) ||
9754 event_private->window_type == GDK_WINDOW_ROOT)
9757 is_toplevel = gdk_window_is_toplevel (event_private);
9759 if ((event->type == GDK_ENTER_NOTIFY ||
9760 event->type == GDK_LEAVE_NOTIFY) &&
9761 (event->crossing.mode == GDK_CROSSING_GRAB ||
9762 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9763 (_gdk_display_has_device_grab (display, device, serial) ||
9764 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9766 /* We synthesize all crossing events due to grabs ourselves,
9767 * so we ignore the native ones caused by our native pointer_grab
9768 * calls. Otherwise we would proxy these crossing event and cause
9769 * multiple copies of crossing events for grabs.
9771 * We do want to handle grabs from other clients though, as for
9772 * instance alt-tab in metacity causes grabs like these and
9773 * we want to handle those. Thus the has_pointer_grab check.
9775 * Implicit grabs on child windows create some grabbing events
9776 * that are sent before the button press. This means we can't
9777 * detect these with the has_pointer_grab check (as the implicit
9778 * grab is only noticed when we get button press event), so we
9779 * detect these events by checking for INFERIOR enter or leave
9780 * events. These should never be a problem to filter out.
9783 /* We ended up in this window after some (perhaps other clients)
9784 grab, so update the toplevel_under_window state */
9786 event->type == GDK_ENTER_NOTIFY &&
9787 event->crossing.mode == GDK_CROSSING_UNGRAB)
9789 if (pointer_info->toplevel_under_pointer)
9790 g_object_unref (pointer_info->toplevel_under_pointer);
9791 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9794 unlink_event = TRUE;
9798 /* Track toplevel_under_pointer */
9801 if (event->type == GDK_ENTER_NOTIFY &&
9802 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9804 if (pointer_info->toplevel_under_pointer)
9805 g_object_unref (pointer_info->toplevel_under_pointer);
9806 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9808 else if (event->type == GDK_LEAVE_NOTIFY &&
9809 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9810 pointer_info->toplevel_under_pointer == event_window)
9812 if (pointer_info->toplevel_under_pointer)
9813 g_object_unref (pointer_info->toplevel_under_pointer);
9814 pointer_info->toplevel_under_pointer = NULL;
9818 /* Store last pointer window and position/state */
9819 old_state = pointer_info->state;
9820 old_button = pointer_info->button;
9822 gdk_event_get_coords (event, &x, &y);
9823 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9824 pointer_info->toplevel_x = x;
9825 pointer_info->toplevel_y = y;
9826 gdk_event_get_state (event, &pointer_info->state);
9827 if (event->type == GDK_BUTTON_PRESS ||
9828 event->type == GDK_BUTTON_RELEASE)
9829 pointer_info->button = event->button.button;
9832 (pointer_info->state != old_state ||
9833 pointer_info->button != old_button))
9834 _gdk_display_enable_motion_hints (display, device);
9836 unlink_event = FALSE;
9837 if (is_motion_type (event->type))
9838 unlink_event = proxy_pointer_event (display,
9841 else if (is_button_type (event->type))
9842 unlink_event = proxy_button_event (event,
9845 if (event->type == GDK_BUTTON_RELEASE &&
9846 !event->any.send_event)
9848 button_release_grab =
9849 _gdk_display_has_device_grab (display, device, serial);
9850 if (button_release_grab &&
9851 button_release_grab->implicit &&
9852 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9854 button_release_grab->serial_end = serial;
9855 button_release_grab->implicit_ungrab = FALSE;
9856 _gdk_display_device_grab_update (display, device, serial);
9863 _gdk_event_queue_remove_link (display, event_link);
9864 g_list_free_1 (event_link);
9865 gdk_event_free (event);
9871 get_extension_event_window (GdkDisplay *display,
9872 GdkWindow *pointer_window,
9877 GdkWindow *grab_window;
9879 GdkDeviceGrabInfo *grab;
9881 /* FIXME: which device? */
9882 grab = _gdk_display_has_device_grab (display, display->core_pointer, serial);
9884 if (grab != NULL && !grab->owner_events)
9886 evmask = grab->event_mask;
9888 grab_window = grab->window;
9890 if (evmask & type_masks[type])
9896 w = (GdkWindowObject *)pointer_window;
9899 evmask = w->extension_events;
9901 if (evmask & type_masks[type])
9902 return (GdkWindow *)w;
9904 w = get_event_parent (w);
9910 evmask = grab->event_mask;
9912 if (evmask & type_masks[type])
9913 return grab->window;
9923 _gdk_window_get_input_window_for_event (GdkWindow *native_window,
9924 GdkEventType event_type,
9928 GdkDisplay *display;
9929 GdkWindow *toplevel_window;
9930 GdkWindow *pointer_window;
9931 GdkWindow *event_win;
9932 gdouble toplevel_x, toplevel_y;
9937 display = gdk_drawable_get_display (native_window);
9938 toplevel_window = convert_native_coords_to_toplevel (native_window,
9939 toplevel_x, toplevel_y,
9940 &toplevel_x, &toplevel_y);
9941 /* FIXME: which device? */
9942 pointer_window = get_pointer_window (display, toplevel_window, NULL,
9943 toplevel_x, toplevel_y, serial);
9944 event_win = get_extension_event_window (display,
9953 * gdk_window_create_similar_surface:
9954 * @window: window to make new surface similar to
9955 * @content: the content for the new surface
9956 * @width: width of the new surface
9957 * @height: height of the new surface
9959 * Create a new surface that is as compatible as possible with the
9960 * given @window. For example the new surface will have the same
9961 * fallback resolution and font options as @window. Generally, the new
9962 * surface will also use the same backend as @window, unless that is
9963 * not possible for some reason. The type of the returned surface may
9964 * be examined with cairo_surface_get_type().
9966 * Initially the surface contents are all 0 (transparent if contents
9967 * have transparency, black otherwise.)
9969 * Returns: a pointer to the newly allocated surface. The caller
9970 * owns the surface and should call cairo_surface_destroy() when done
9973 * This function always returns a valid pointer, but it will return a
9974 * pointer to a "nil" surface if @other is already in an error state
9975 * or any other error occurs.
9980 gdk_window_create_similar_surface (GdkWindow * window,
9981 cairo_content_t content,
9985 cairo_surface_t *window_surface, *surface;
9987 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9989 window_surface = _gdk_drawable_ref_cairo_surface (window);
9991 surface = cairo_surface_create_similar (window_surface,
9995 cairo_surface_destroy (window_surface);