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;
209 cairo_surface_t *surface;
210 guint uses_implicit : 1;
216 cairo_region_t *dest_region; /* The destination region */
217 int dx, dy; /* The amount that the source was moved to reach dest_region */
218 } GdkWindowRegionMove;
222 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
223 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
226 static void gdk_window_drop_cairo_surface (GdkWindowObject *private);
227 static void gdk_window_set_cairo_clip (GdkDrawable *drawable,
230 static void gdk_window_real_get_size (GdkDrawable *drawable,
234 static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable);
235 static gint gdk_window_real_get_depth (GdkDrawable *drawable);
236 static GdkScreen* gdk_window_real_get_screen (GdkDrawable *drawable);
237 static void gdk_window_real_set_colormap (GdkDrawable *drawable,
239 static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
241 static GdkDrawable* gdk_window_get_source_drawable (GdkDrawable *drawable);
243 static cairo_region_t* gdk_window_get_clip_region (GdkDrawable *drawable);
244 static cairo_region_t* gdk_window_get_visible_region (GdkDrawable *drawable);
246 static void gdk_window_free_paint_stack (GdkWindow *window);
248 static void gdk_window_init (GdkWindowObject *window);
249 static void gdk_window_class_init (GdkWindowObjectClass *klass);
250 static void gdk_window_finalize (GObject *object);
252 static void gdk_window_set_property (GObject *object,
256 static void gdk_window_get_property (GObject *object,
261 static void gdk_window_clear_backing_region (GdkWindow *window,
262 cairo_region_t *region);
264 static void recompute_visible_regions (GdkWindowObject *private,
265 gboolean recalculate_siblings,
266 gboolean recalculate_children);
267 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
268 static void gdk_window_flush_recursive (GdkWindowObject *window);
269 static void do_move_region_bits_on_impl (GdkWindowObject *private,
270 cairo_region_t *region, /* In impl window coords */
272 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
273 static void move_native_children (GdkWindowObject *private);
274 static void update_cursor (GdkDisplay *display,
276 static void impl_window_add_update_area (GdkWindowObject *impl_window,
277 cairo_region_t *region);
278 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
279 static void gdk_window_invalidate_region_full (GdkWindow *window,
280 const cairo_region_t *region,
281 gboolean invalidate_children,
283 static void gdk_window_invalidate_rect_full (GdkWindow *window,
284 const GdkRectangle *rect,
285 gboolean invalidate_children,
288 static guint signals[LAST_SIGNAL] = { 0 };
290 static gpointer parent_class = NULL;
292 static const cairo_user_data_key_t gdk_window_cairo_key;
295 new_region_tag (void)
297 static guint32 tag = 0;
303 gdk_window_object_get_type (void)
305 static GType object_type = 0;
308 object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
310 sizeof (GdkWindowObjectClass),
311 (GClassInitFunc) gdk_window_class_init,
312 sizeof (GdkWindowObject),
313 (GInstanceInitFunc) gdk_window_init,
320 _gdk_paintable_get_type (void)
322 static GType paintable_type = 0;
326 const GTypeInfo paintable_info =
328 sizeof (GdkPaintableIface), /* class_size */
329 NULL, /* base_init */
330 NULL, /* base_finalize */
333 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
334 g_intern_static_string ("GdkPaintable"),
337 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
340 return paintable_type;
344 gdk_window_init (GdkWindowObject *window)
346 /* 0-initialization is good for all other fields. */
348 window->window_type = GDK_WINDOW_CHILD;
350 window->state = GDK_WINDOW_STATE_WITHDRAWN;
353 window->toplevel_window_type = -1;
355 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
356 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
357 /* Default to unobscured since some backends don't send visibility events */
358 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
361 /* Stop and return on the first non-NULL parent */
363 accumulate_get_window (GSignalInvocationHint *ihint,
365 const GValue *handler_return,
368 g_value_copy (handler_return, return_accu);
369 /* Continue while returning NULL */
370 return g_value_get_object (handler_return) == NULL;
373 static GQuark quark_pointer_window = 0;
376 gdk_window_class_init (GdkWindowObjectClass *klass)
378 GObjectClass *object_class = G_OBJECT_CLASS (klass);
379 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
381 parent_class = g_type_class_peek_parent (klass);
383 object_class->finalize = gdk_window_finalize;
384 object_class->set_property = gdk_window_set_property;
385 object_class->get_property = gdk_window_get_property;
387 drawable_class->get_depth = gdk_window_real_get_depth;
388 drawable_class->get_screen = gdk_window_real_get_screen;
389 drawable_class->get_size = gdk_window_real_get_size;
390 drawable_class->set_colormap = gdk_window_real_set_colormap;
391 drawable_class->get_colormap = gdk_window_real_get_colormap;
392 drawable_class->get_visual = gdk_window_real_get_visual;
393 drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
394 drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
395 drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
396 drawable_class->get_clip_region = gdk_window_get_clip_region;
397 drawable_class->get_visible_region = gdk_window_get_visible_region;
398 drawable_class->get_source_drawable = gdk_window_get_source_drawable;
400 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
408 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
409 * gdk_window_get_cursor() for details.
413 g_object_class_install_property (object_class,
415 g_param_spec_boxed ("cursor",
422 * GdkWindow::pick-embedded-child:
423 * @window: the window on which the signal is emitted
424 * @x: x coordinate in the window
425 * @y: y coordinate in the window
427 * The ::pick-embedded-child signal is emitted to find an embedded
428 * child at the given position.
430 * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
434 signals[PICK_EMBEDDED_CHILD] =
435 g_signal_new (g_intern_static_string ("pick-embedded-child"),
436 G_OBJECT_CLASS_TYPE (object_class),
439 accumulate_get_window, NULL,
440 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
447 * GdkWindow::to-embedder:
448 * @window: the offscreen window on which the signal is emitted
449 * @offscreen-x: x coordinate in the offscreen window
450 * @offscreen-y: y coordinate in the offscreen window
451 * @embedder-x: return location for the x coordinate in the embedder window
452 * @embedder-y: return location for the y coordinate in the embedder window
454 * The ::to-embedder signal is emitted to translate coordinates
455 * in an offscreen window to its embedder.
457 * See also #GtkWindow::from-embedder.
461 signals[TO_EMBEDDER] =
462 g_signal_new (g_intern_static_string ("to-embedder"),
463 G_OBJECT_CLASS_TYPE (object_class),
467 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
476 * GdkWindow::from-embedder:
477 * @window: the offscreen window on which the signal is emitted
478 * @embedder-x: x coordinate in the embedder window
479 * @embedder-y: y coordinate in the embedder window
480 * @offscreen-x: return location for the x coordinate in the offscreen window
481 * @offscreen-y: return location for the y coordinate in the offscreen window
483 * The ::from-embedder signal is emitted to translate coordinates
484 * in the embedder of an offscreen window to the offscreen window.
486 * See also #GtkWindow::to-embedder.
490 signals[FROM_EMBEDDER] =
491 g_signal_new (g_intern_static_string ("from-embedder"),
492 G_OBJECT_CLASS_TYPE (object_class),
496 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
506 device_removed_cb (GdkDeviceManager *device_manager,
510 GdkWindowObject *private;
512 private = (GdkWindowObject *) window;
514 private->devices_inside = g_list_remove (private->devices_inside, device);
515 g_hash_table_remove (private->device_cursor, device);
517 if (private->device_events)
518 g_hash_table_remove (private->device_events, device);
522 gdk_window_finalize (GObject *object)
524 GdkWindow *window = GDK_WINDOW (object);
525 GdkWindowObject *obj = (GdkWindowObject *) object;
526 GdkDeviceManager *device_manager;
528 device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (window)));
529 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
531 if (!GDK_WINDOW_DESTROYED (window))
533 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
535 g_warning ("losing last reference to undestroyed window\n");
536 _gdk_window_destroy (window, FALSE);
539 /* We use TRUE here, to keep us from actually calling
540 * XDestroyWindow() on the window
542 _gdk_window_destroy (window, TRUE);
547 g_object_unref (obj->impl);
551 if (obj->impl_window != obj)
553 g_object_unref (obj->impl_window);
554 obj->impl_window = NULL;
558 cairo_region_destroy (obj->shape);
560 if (obj->input_shape)
561 cairo_region_destroy (obj->input_shape);
564 gdk_cursor_unref (obj->cursor);
566 if (obj->device_cursor)
567 g_hash_table_destroy (obj->device_cursor);
569 if (obj->device_events)
570 g_hash_table_destroy (obj->device_events);
572 if (obj->devices_inside)
573 g_list_free (obj->devices_inside);
575 G_OBJECT_CLASS (parent_class)->finalize (object);
579 gdk_window_set_property (GObject *object,
584 GdkWindow *window = (GdkWindow *)object;
589 gdk_window_set_cursor (window, g_value_get_boxed (value));
593 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
599 gdk_window_get_property (GObject *object,
604 GdkWindow *window = (GdkWindow *) object;
609 g_value_set_boxed (value, gdk_window_get_cursor (window));
613 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
619 gdk_window_is_offscreen (GdkWindowObject *window)
621 return window->window_type == GDK_WINDOW_OFFSCREEN;
624 static GdkWindowObject *
625 gdk_window_get_impl_window (GdkWindowObject *window)
627 return window->impl_window;
631 _gdk_window_get_impl_window (GdkWindow *window)
633 return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
637 gdk_window_has_impl (GdkWindowObject *window)
639 return window->impl_window == window;
643 gdk_window_is_toplevel (GdkWindowObject *window)
646 window->parent == NULL ||
647 window->parent->window_type == GDK_WINDOW_ROOT;
651 _gdk_window_has_impl (GdkWindow *window)
653 return gdk_window_has_impl ((GdkWindowObject *)window);
657 gdk_window_has_no_impl (GdkWindowObject *window)
659 return window->impl_window != window;
663 remove_child_area (GdkWindowObject *private,
664 GdkWindowObject *until,
666 cairo_region_t *region)
668 GdkWindowObject *child;
669 cairo_region_t *child_region;
672 cairo_region_t *shape;
674 for (l = private->children; l; l = l->next)
681 /* If region is empty already, no need to do
682 anything potentially costly */
683 if (cairo_region_is_empty (region))
686 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
689 /* Ignore offscreen children, as they don't draw in their parent and
690 * don't take part in the clipping */
691 if (gdk_window_is_offscreen (child))
696 r.width = child->width;
697 r.height = child->height;
699 /* Bail early if child totally outside region */
700 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
703 child_region = cairo_region_create_rectangle (&r);
707 /* Adjust shape region to parent window coords */
708 cairo_region_translate (child->shape, child->x, child->y);
709 cairo_region_intersect (child_region, child->shape);
710 cairo_region_translate (child->shape, -child->x, -child->y);
712 else if (private->window_type == GDK_WINDOW_FOREIGN)
714 shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
717 cairo_region_intersect (child_region, shape);
718 cairo_region_destroy (shape);
724 if (child->input_shape)
725 cairo_region_intersect (child_region, child->input_shape);
726 else if (private->window_type == GDK_WINDOW_FOREIGN)
728 shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
731 cairo_region_intersect (child_region, shape);
732 cairo_region_destroy (shape);
737 cairo_region_subtract (region, child_region);
738 cairo_region_destroy (child_region);
743 static GdkVisibilityState
744 effective_visibility (GdkWindowObject *private)
746 GdkVisibilityState native;
748 if (!gdk_window_is_viewable ((GdkWindow *)private))
749 return GDK_VISIBILITY_NOT_VIEWABLE;
751 native = private->impl_window->native_visibility;
753 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
754 private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
755 return GDK_VISIBILITY_FULLY_OBSCURED;
756 else if (native == GDK_VISIBILITY_UNOBSCURED)
757 return private->visibility;
758 else /* native PARTIAL, private partial or unobscured */
759 return GDK_VISIBILITY_PARTIAL;
763 gdk_window_update_visibility (GdkWindowObject *private)
765 GdkVisibilityState new_visibility;
768 new_visibility = effective_visibility (private);
770 if (new_visibility != private->effective_visibility)
772 private->effective_visibility = new_visibility;
774 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
775 private->event_mask & GDK_VISIBILITY_NOTIFY)
777 event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
779 event->visibility.state = new_visibility;
785 gdk_window_update_visibility_recursively (GdkWindowObject *private,
786 GdkWindowObject *only_for_impl)
788 GdkWindowObject *child;
791 gdk_window_update_visibility (private);
792 for (l = private->children; l != NULL; l = l->next)
795 if ((only_for_impl == NULL) ||
796 (only_for_impl == child->impl_window))
797 gdk_window_update_visibility_recursively (child, only_for_impl);
802 should_apply_clip_as_shape (GdkWindowObject *private)
805 gdk_window_has_impl (private) &&
806 /* Not for offscreens */
807 !gdk_window_is_offscreen (private) &&
808 /* or for toplevels */
809 !gdk_window_is_toplevel (private) &&
810 /* or for foreign windows */
811 private->window_type != GDK_WINDOW_FOREIGN &&
812 /* or for the root window */
813 private->window_type != GDK_WINDOW_ROOT;
817 apply_shape (GdkWindowObject *private,
818 cairo_region_t *region)
820 GdkWindowImplIface *impl_iface;
822 /* We trash whether we applied a shape so that
823 we can avoid unsetting it many times, which
824 could happen in e.g. apply_clip_as_shape as
825 windows get resized */
826 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
828 impl_iface->shape_combine_region ((GdkWindow *)private,
830 else if (private->applied_shape)
831 impl_iface->shape_combine_region ((GdkWindow *)private,
834 private->applied_shape = region != NULL;
838 region_rect_equal (const cairo_region_t *region,
839 const GdkRectangle *rect)
841 GdkRectangle extents;
843 if (cairo_region_num_rectangles (region) != 1)
846 cairo_region_get_extents (region, &extents);
848 return extents.x == rect->x &&
849 extents.y == rect->y &&
850 extents.width == rect->width &&
851 extents.height == rect->height;
855 apply_clip_as_shape (GdkWindowObject *private)
860 r.width = private->width;
861 r.height = private->height;
863 /* We only apply the clip region if would differ
864 from the actual clip region implied by the size
865 of the window. This is to avoid unneccessarily
866 adding meaningless shapes to all native subwindows */
867 if (!region_rect_equal (private->clip_region, &r))
868 apply_shape (private, private->clip_region);
870 apply_shape (private, NULL);
874 recompute_visible_regions_internal (GdkWindowObject *private,
875 gboolean recalculate_clip,
876 gboolean recalculate_siblings,
877 gboolean recalculate_children)
881 GdkWindowObject *child;
882 cairo_region_t *new_clip, *old_clip_region_with_children;
883 gboolean clip_region_changed;
884 gboolean abs_pos_changed;
885 int old_abs_x, old_abs_y;
887 old_abs_x = private->abs_x;
888 old_abs_y = private->abs_y;
890 /* Update absolute position */
891 if (gdk_window_has_impl (private))
893 /* Native window starts here */
899 private->abs_x = private->parent->abs_x + private->x;
900 private->abs_y = private->parent->abs_y + private->y;
904 private->abs_x != old_abs_x ||
905 private->abs_y != old_abs_y;
907 /* Update clip region based on:
910 * siblings in parents above window
912 clip_region_changed = FALSE;
913 if (recalculate_clip)
915 if (private->viewable)
917 /* Calculate visible region (sans children) in parent window coords */
920 r.width = private->width;
921 r.height = private->height;
922 new_clip = cairo_region_create_rectangle (&r);
924 if (!gdk_window_is_toplevel (private))
926 cairo_region_intersect (new_clip, private->parent->clip_region);
928 /* Remove all overlapping children from parent.
929 * Unless we're all native, because then we don't need to take
930 * siblings into account since X does that clipping for us.
931 * This makes things like SWT that modify the raw X stacking
932 * order without GDKs knowledge work.
934 if (!_gdk_native_windows)
935 remove_child_area (private->parent, private, FALSE, new_clip);
938 /* Convert from parent coords to window coords */
939 cairo_region_translate (new_clip, -private->x, -private->y);
942 cairo_region_intersect (new_clip, private->shape);
945 new_clip = cairo_region_create ();
947 if (private->clip_region == NULL ||
948 !cairo_region_equal (private->clip_region, new_clip))
949 clip_region_changed = TRUE;
951 if (private->clip_region)
952 cairo_region_destroy (private->clip_region);
953 private->clip_region = new_clip;
955 old_clip_region_with_children = private->clip_region_with_children;
956 private->clip_region_with_children = cairo_region_copy (private->clip_region);
957 if (private->window_type != GDK_WINDOW_ROOT)
958 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
960 if (clip_region_changed ||
961 !cairo_region_equal (private->clip_region_with_children, old_clip_region_with_children))
962 private->clip_tag = new_region_tag ();
964 if (old_clip_region_with_children)
965 cairo_region_destroy (old_clip_region_with_children);
968 if (clip_region_changed)
970 GdkVisibilityState visibility;
971 gboolean fully_visible;
973 if (cairo_region_is_empty (private->clip_region))
974 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
979 fully_visible = cairo_region_equal (private->clip_region,
986 r.width = private->width;
987 r.height = private->height;
988 fully_visible = region_rect_equal (private->clip_region, &r);
992 visibility = GDK_VISIBILITY_UNOBSCURED;
994 visibility = GDK_VISIBILITY_PARTIAL;
997 if (private->visibility != visibility)
999 private->visibility = visibility;
1000 gdk_window_update_visibility (private);
1004 /* Update all children, recursively (except for root, where children are not exact). */
1005 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1006 private->window_type != GDK_WINDOW_ROOT)
1008 for (l = private->children; l; l = l->next)
1011 /* Only recalculate clip if the the clip region changed, otherwise
1012 * there is no way the child clip region could change (its has not e.g. moved)
1013 * Except if recalculate_children is set to force child updates
1015 recompute_visible_regions_internal (child,
1016 recalculate_clip && (clip_region_changed || recalculate_children),
1021 if (clip_region_changed &&
1022 should_apply_clip_as_shape (private))
1023 apply_clip_as_shape (private);
1025 if (recalculate_siblings &&
1026 !gdk_window_is_toplevel (private))
1028 /* If we moved a child window in parent or changed the stacking order, then we
1029 * need to recompute the visible area of all the other children in the parent
1031 for (l = private->parent->children; l; l = l->next)
1035 if (child != private)
1036 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1039 /* We also need to recompute the _with_children clip for the parent */
1040 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1043 if (private->cairo_surface)
1047 /* It would be nice if we had some cairo support here so we
1048 could set the clip rect on the cairo surface */
1049 width = private->abs_x + private->width;
1050 height = private->abs_y + private->height;
1052 if (_gdk_windowing_set_cairo_surface_size (private->cairo_surface,
1055 cairo_surface_set_device_offset (private->cairo_surface,
1061 cairo_surface_destroy (private->cairo_surface);
1062 private->cairo_surface = NULL;
1067 /* Call this when private has changed in one or more of these ways:
1071 * stacking order of window changed
1074 * It will recalculate abs_x/y and the clip regions
1076 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1077 * for recalculate_siblings. (Mostly used internally for the recursion)
1079 * If a child window was removed (and you can't use that child for
1080 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1083 recompute_visible_regions (GdkWindowObject *private,
1084 gboolean recalculate_siblings,
1085 gboolean recalculate_children)
1087 recompute_visible_regions_internal (private,
1089 recalculate_siblings,
1090 recalculate_children);
1094 _gdk_window_update_size (GdkWindow *window)
1096 recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1099 /* Find the native window that would be just above "child"
1100 * in the native stacking order if "child" was a native window
1101 * (it doesn't have to be native). If there is no such native
1102 * window inside this native parent then NULL is returned.
1103 * If child is NULL, find lowest native window in parent.
1105 static GdkWindowObject *
1106 find_native_sibling_above_helper (GdkWindowObject *parent,
1107 GdkWindowObject *child)
1114 l = g_list_find (parent->children, child);
1115 g_assert (l != NULL); /* Better be a child of its parent... */
1116 l = l->prev; /* Start looking at the one above the child */
1119 l = g_list_last (parent->children);
1121 for (; l != NULL; l = l->prev)
1125 if (gdk_window_has_impl (w))
1128 g_assert (parent != w);
1129 w = find_native_sibling_above_helper (w, NULL);
1138 static GdkWindowObject *
1139 find_native_sibling_above (GdkWindowObject *parent,
1140 GdkWindowObject *child)
1144 w = find_native_sibling_above_helper (parent, child);
1148 if (gdk_window_has_impl (parent))
1151 return find_native_sibling_above (parent->parent, parent);
1155 get_native_device_event_mask (GdkWindowObject *private,
1158 GdkEventMask event_mask;
1161 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1163 event_mask = private->event_mask;
1165 if (_gdk_native_windows ||
1166 private->window_type == GDK_WINDOW_ROOT ||
1167 private->window_type == GDK_WINDOW_FOREIGN)
1173 /* Do whatever the app asks to, since the app
1174 * may be asking for weird things for native windows,
1175 * but don't use motion hints as that may affect non-native
1176 * child windows that don't want it. Also, we need to
1177 * set all the app-specified masks since they will be picked
1178 * up by any implicit grabs (i.e. if they were not set as
1179 * native we would not get the events we need). */
1180 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1182 /* We need thse for all native windows so we can
1183 emulate events on children: */
1186 GDK_VISIBILITY_NOTIFY_MASK |
1187 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1189 /* Additionally we select for pointer and button events
1190 * for toplevels as we need to get these to emulate
1191 * them for non-native subwindows. Even though we don't
1192 * select on them for all native windows we will get them
1193 * as the events are propagated out to the first window
1194 * that select for them.
1195 * Not selecting for button press on all windows is an
1196 * important thing, because in X only one client can do
1197 * so, and we don't want to unexpectedly prevent another
1198 * client from doing it.
1200 * We also need to do the same if the app selects for button presses
1201 * because then we will get implicit grabs for this window, and the
1202 * event mask used for that grab is based on the rest of the mask
1203 * for the window, but we might need more events than this window
1204 * lists due to some non-native child window.
1206 if (gdk_window_is_toplevel (private) ||
1207 mask & GDK_BUTTON_PRESS_MASK)
1209 GDK_POINTER_MOTION_MASK |
1210 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1218 get_native_grab_event_mask (GdkEventMask grab_mask)
1220 /* Similar to the above but for pointer events only */
1222 GDK_POINTER_MOTION_MASK |
1223 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1224 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1227 ~GDK_POINTER_MOTION_HINT_MASK);
1231 get_native_event_mask (GdkWindowObject *private)
1233 return get_native_device_event_mask (private, NULL);
1236 /* Puts the native window in the right order wrt the other native windows
1237 * in the hierarchy, given the position it has in the client side data.
1238 * This is useful if some operation changed the stacking order.
1239 * This calls assumes the native window is now topmost in its native parent.
1242 sync_native_window_stack_position (GdkWindow *window)
1244 GdkWindowObject *above;
1245 GdkWindowObject *private;
1246 GdkWindowImplIface *impl_iface;
1247 GList listhead = {0};
1249 private = (GdkWindowObject *) window;
1250 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1252 above = find_native_sibling_above (private->parent, private);
1255 listhead.data = window;
1256 impl_iface->restack_under ((GdkWindow *)above,
1263 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1264 * the default root window for the default display.
1265 * @attributes: attributes of the new window
1266 * @attributes_mask: mask indicating which fields in @attributes are valid
1268 * Creates a new #GdkWindow using the attributes from
1269 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1270 * more details. Note: to use this on displays other than the default
1271 * display, @parent must be specified.
1273 * Return value: (transfer none): the new #GdkWindow
1276 gdk_window_new (GdkWindow *parent,
1277 GdkWindowAttr *attributes,
1278 gint attributes_mask)
1281 GdkWindowObject *private;
1286 GdkEventMask event_mask;
1287 GdkWindow *real_parent;
1288 GdkDeviceManager *device_manager;
1290 g_return_val_if_fail (attributes != NULL, NULL);
1294 GDK_NOTE (MULTIHEAD,
1295 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1297 screen = gdk_screen_get_default ();
1298 parent = gdk_screen_get_root_window (screen);
1301 screen = gdk_drawable_get_screen (parent);
1303 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1305 if (GDK_WINDOW_DESTROYED (parent))
1307 g_warning ("gdk_window_new(): parent is destroyed\n");
1311 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1312 _gdk_native_windows)
1314 g_warning ("Offscreen windows not supported with native-windows gdk");
1318 window = g_object_new (GDK_TYPE_WINDOW, NULL);
1319 private = (GdkWindowObject *) window;
1321 /* Windows with a foreign parent are treated as if they are children
1322 * of the root window, except for actual creation.
1324 real_parent = parent;
1325 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1326 parent = gdk_screen_get_root_window (screen);
1328 private->parent = (GdkWindowObject *)parent;
1330 private->accept_focus = TRUE;
1331 private->focus_on_map = TRUE;
1333 if (attributes_mask & GDK_WA_X)
1338 if (attributes_mask & GDK_WA_Y)
1345 private->width = (attributes->width > 1) ? (attributes->width) : (1);
1346 private->height = (attributes->height > 1) ? (attributes->height) : (1);
1348 #ifdef GDK_WINDOWING_X11
1349 /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1350 * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1352 if (attributes->wclass == GDK_INPUT_ONLY &&
1353 private->parent->window_type == GDK_WINDOW_ROOT &&
1354 !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1356 g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1357 attributes->wclass = GDK_INPUT_OUTPUT;
1361 if (attributes->wclass == GDK_INPUT_ONLY)
1363 /* Backwards compatiblity - we've always ignored
1364 * attributes->window_type for input-only windows
1367 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1368 private->window_type = GDK_WINDOW_TEMP;
1370 private->window_type = GDK_WINDOW_CHILD;
1373 private->window_type = attributes->window_type;
1376 switch (private->window_type)
1378 case GDK_WINDOW_TOPLEVEL:
1379 case GDK_WINDOW_TEMP:
1380 case GDK_WINDOW_OFFSCREEN:
1381 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1382 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1383 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1384 case GDK_WINDOW_CHILD:
1388 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1392 if (attributes_mask & GDK_WA_VISUAL)
1393 visual = attributes->visual;
1395 visual = gdk_screen_get_system_visual (screen);
1397 private->event_mask = attributes->event_mask;
1399 if (attributes->wclass == GDK_INPUT_OUTPUT)
1401 private->input_only = FALSE;
1402 private->depth = visual->depth;
1404 /* XXX: Cache this somehow? */
1405 private->background = cairo_pattern_create_rgb (0, 0, 0);
1410 private->input_only = TRUE;
1413 if (private->parent)
1414 private->parent->children = g_list_prepend (private->parent->children, window);
1416 native = _gdk_native_windows; /* Default */
1417 if (private->parent->window_type == GDK_WINDOW_ROOT)
1418 native = TRUE; /* Always use native windows for toplevels */
1419 else if (!private->input_only &&
1420 ((attributes_mask & GDK_WA_COLORMAP &&
1421 attributes->colormap != gdk_drawable_get_colormap ((GdkDrawable *)private->parent)) ||
1422 (attributes_mask & GDK_WA_VISUAL &&
1423 attributes->visual != gdk_drawable_get_visual ((GdkDrawable *)private->parent))))
1424 native = TRUE; /* InputOutput window with different colormap or visual than parent, needs native window */
1426 if (gdk_window_is_offscreen (private))
1428 _gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask);
1429 private->impl_window = private;
1433 event_mask = get_native_event_mask (private);
1435 /* Create the impl */
1436 _gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask);
1437 private->impl_window = private;
1439 /* This will put the native window topmost in the native parent, which may
1440 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1441 if (!_gdk_window_has_impl (real_parent))
1442 sync_native_window_stack_position (window);
1446 private->impl_window = g_object_ref (private->parent->impl_window);
1447 private->impl = g_object_ref (private->impl_window->impl);
1450 recompute_visible_regions (private, TRUE, FALSE);
1452 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1453 (attributes->cursor) :
1456 private->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1457 (GDestroyNotify) gdk_cursor_unref);
1459 device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (parent)));
1460 g_signal_connect (device_manager, "device-removed",
1461 G_CALLBACK (device_removed_cb), window);
1467 is_parent_of (GdkWindow *parent,
1478 w = gdk_window_get_parent (w);
1485 change_impl (GdkWindowObject *private,
1486 GdkWindowObject *impl_window,
1490 GdkWindowObject *child;
1491 GdkDrawable *old_impl;
1492 GdkWindowObject *old_impl_window;
1494 old_impl = private->impl;
1495 old_impl_window = private->impl_window;
1496 if (private != impl_window)
1497 private->impl_window = g_object_ref (impl_window);
1499 private->impl_window = private;
1500 private->impl = g_object_ref (new);
1501 if (old_impl_window != private)
1502 g_object_unref (old_impl_window);
1503 g_object_unref (old_impl);
1505 for (l = private->children; l != NULL; l = l->next)
1509 if (child->impl == old_impl)
1510 change_impl (child, impl_window, new);
1515 reparent_to_impl (GdkWindowObject *private)
1518 GdkWindowObject *child;
1520 GdkWindowImplIface *impl_iface;
1522 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1524 /* Enumerate in reverse order so we get the right order for the native
1525 windows (first in childrens list is topmost, and reparent places on top) */
1526 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1530 if (child->impl == private->impl)
1531 reparent_to_impl (child);
1534 show = impl_iface->reparent ((GdkWindow *)child,
1535 (GdkWindow *)private,
1536 child->x, child->y);
1538 gdk_window_show_unraised ((GdkWindow *)child);
1545 * gdk_window_reparent:
1546 * @window: a #GdkWindow
1547 * @new_parent: new parent to move @window into
1548 * @x: X location inside the new parent
1549 * @y: Y location inside the new parent
1551 * Reparents @window into the given @new_parent. The window being
1552 * reparented will be unmapped as a side effect.
1556 gdk_window_reparent (GdkWindow *window,
1557 GdkWindow *new_parent,
1561 GdkWindowObject *private;
1562 GdkWindowObject *new_parent_private;
1563 GdkWindowObject *old_parent;
1565 gboolean show, was_mapped, applied_clip_as_shape;
1566 gboolean do_reparent_to_impl;
1567 GdkEventMask old_native_event_mask;
1568 GdkWindowImplIface *impl_iface;
1570 g_return_if_fail (GDK_IS_WINDOW (window));
1571 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1572 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1574 if (GDK_WINDOW_DESTROYED (window) ||
1575 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1578 screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
1580 new_parent = gdk_screen_get_root_window (screen);
1582 private = (GdkWindowObject *) window;
1583 new_parent_private = (GdkWindowObject *)new_parent;
1585 /* No input-output children of input-only windows */
1586 if (new_parent_private->input_only && !private->input_only)
1589 /* Don't create loops in hierarchy */
1590 if (is_parent_of (window, new_parent))
1593 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1594 To make sure we're ok, just wipe it. */
1595 gdk_window_drop_cairo_surface (private);
1597 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1598 old_parent = private->parent;
1600 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1603 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1604 if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1605 new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1606 gdk_window_ensure_native (window);
1608 applied_clip_as_shape = should_apply_clip_as_shape (private);
1610 old_native_event_mask = 0;
1611 do_reparent_to_impl = FALSE;
1612 if (gdk_window_has_impl (private))
1614 old_native_event_mask = get_native_event_mask (private);
1616 show = impl_iface->reparent (window, new_parent, x, y);
1620 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1621 g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1622 new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1625 gdk_window_hide (window);
1627 do_reparent_to_impl = TRUE;
1628 change_impl (private,
1629 new_parent_private->impl_window,
1630 new_parent_private->impl);
1633 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1636 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1638 new_parent = gdk_screen_get_root_window (screen);
1639 new_parent_private = (GdkWindowObject *)new_parent;
1643 old_parent->children = g_list_remove (old_parent->children, window);
1645 private->parent = new_parent_private;
1649 new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1651 /* Switch the window type as appropriate */
1653 switch (GDK_WINDOW_TYPE (new_parent))
1655 case GDK_WINDOW_ROOT:
1656 case GDK_WINDOW_FOREIGN:
1657 if (private->toplevel_window_type != -1)
1658 GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1659 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1660 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1662 case GDK_WINDOW_OFFSCREEN:
1663 case GDK_WINDOW_TOPLEVEL:
1664 case GDK_WINDOW_CHILD:
1665 case GDK_WINDOW_TEMP:
1666 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1667 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1669 /* Save the original window type so we can restore it if the
1670 * window is reparented back to be a toplevel
1672 private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1673 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1677 /* We might have changed window type for a native windows, so we
1678 need to change the event mask too. */
1679 if (gdk_window_has_impl (private))
1681 GdkEventMask native_event_mask = get_native_event_mask (private);
1683 if (native_event_mask != old_native_event_mask)
1684 impl_iface->set_events (window, native_event_mask);
1687 _gdk_window_update_viewable (window);
1689 recompute_visible_regions (private, TRUE, FALSE);
1690 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1691 recompute_visible_regions (old_parent, FALSE, TRUE);
1693 /* We used to apply the clip as the shape, but no more.
1694 Reset this to the real shape */
1695 if (gdk_window_has_impl (private) &&
1696 applied_clip_as_shape &&
1697 !should_apply_clip_as_shape (private))
1698 apply_shape (private, private->shape);
1700 if (do_reparent_to_impl)
1701 reparent_to_impl (private);
1704 /* The reparent will have put the native window topmost in the native parent,
1705 * which may be wrong wrt other native windows in the non-native hierarchy,
1707 if (!gdk_window_has_impl (new_parent_private))
1708 sync_native_window_stack_position (window);
1712 gdk_window_show_unraised (window);
1714 _gdk_synthesize_crossing_events_for_geometry_change (window);
1718 temporary_disable_extension_events (GdkWindowObject *window)
1720 GdkWindowObject *child;
1724 if (window->extension_events != 0)
1726 g_object_set_data (G_OBJECT (window),
1727 "gdk-window-extension-events",
1728 GINT_TO_POINTER (window->extension_events));
1729 gdk_input_set_extension_events ((GdkWindow *)window, 0,
1730 GDK_EXTENSION_EVENTS_NONE);
1735 for (l = window->children; l != NULL; l = l->next)
1739 if (window->impl_window == child->impl_window)
1740 res |= temporary_disable_extension_events (child);
1747 reenable_extension_events (GdkWindowObject *window)
1749 GdkWindowObject *child;
1753 mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1754 "gdk-window-extension-events"));
1758 /* We don't have the mode here, so we pass in cursor.
1759 This works with the current code since mode is not
1760 stored except as part of the mask, and cursor doesn't
1762 gdk_input_set_extension_events ((GdkWindow *)window, mask,
1763 GDK_EXTENSION_EVENTS_CURSOR);
1764 g_object_set_data (G_OBJECT (window),
1765 "gdk-window-extension-events",
1769 for (l = window->children; l != NULL; l = l->next)
1773 if (window->impl_window == child->impl_window)
1774 reenable_extension_events (window);
1779 * gdk_window_ensure_native:
1780 * @window: a #GdkWindow
1782 * Tries to ensure that there is a window-system native window for this
1783 * GdkWindow. This may fail in some situations, returning %FALSE.
1785 * Offscreen window and children of them can never have native windows.
1787 * Some backends may not support native child windows.
1789 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1794 gdk_window_ensure_native (GdkWindow *window)
1796 GdkWindowObject *private;
1797 GdkWindowObject *impl_window;
1798 GdkDrawable *new_impl, *old_impl;
1801 GdkWindowAttr attributes;
1802 GdkWindowObject *above;
1804 GdkWindowImplIface *impl_iface;
1805 gboolean disabled_extension_events;
1807 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1809 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1810 GDK_WINDOW_DESTROYED (window))
1813 private = (GdkWindowObject *) window;
1815 impl_window = gdk_window_get_impl_window (private);
1817 if (gdk_window_is_offscreen (impl_window))
1818 return FALSE; /* native in offscreens not supported */
1820 if (impl_window == private)
1821 /* Already has an impl, and its not offscreen . */
1824 /* Need to create a native window */
1826 /* First we disable any extension events on the window or its
1827 descendants to handle the native input window moving */
1828 disabled_extension_events = FALSE;
1829 if (impl_window->input_window)
1830 disabled_extension_events = temporary_disable_extension_events (private);
1832 gdk_window_drop_cairo_surface (private);
1834 screen = gdk_drawable_get_screen (window);
1835 visual = gdk_drawable_get_visual (window);
1837 attributes.colormap = gdk_drawable_get_colormap (window);
1839 old_impl = private->impl;
1840 _gdk_window_impl_new (window, (GdkWindow *)private->parent,
1842 get_native_event_mask (private),
1843 &attributes, GDK_WA_COLORMAP);
1844 new_impl = private->impl;
1846 private->impl = old_impl;
1847 change_impl (private, private, new_impl);
1849 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1851 /* Native window creation will put the native window topmost in the
1852 * native parent, which may be wrong wrt the position of the previous
1853 * non-native window wrt to the other non-native children, so correct this.
1855 above = find_native_sibling_above (private->parent, private);
1858 listhead.data = window;
1859 listhead.prev = NULL;
1860 listhead.next = NULL;
1861 impl_iface->restack_under ((GdkWindow *)above, &listhead);
1864 recompute_visible_regions (private, FALSE, FALSE);
1866 /* The shape may not have been set, as the clip region doesn't actually
1867 change, so do it here manually */
1868 if (should_apply_clip_as_shape (private))
1869 apply_clip_as_shape (private);
1871 reparent_to_impl (private);
1873 if (!private->input_only)
1875 impl_iface->set_background (window, private->background);
1878 impl_iface->input_shape_combine_region (window,
1879 private->input_shape,
1882 if (gdk_window_is_viewable (window))
1883 impl_iface->show (window, FALSE);
1885 if (disabled_extension_events)
1886 reenable_extension_events (private);
1892 window_remove_filters (GdkWindow *window)
1894 GdkWindowObject *obj = (GdkWindowObject*) window;
1900 for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
1901 g_free (tmp_list->data);
1903 g_list_free (obj->filters);
1904 obj->filters = NULL;
1909 update_pointer_info_foreach (GdkDisplay *display,
1911 GdkPointerWindowInfo *pointer_info,
1914 GdkWindow *window = user_data;
1916 if (pointer_info->toplevel_under_pointer == window)
1918 g_object_unref (pointer_info->toplevel_under_pointer);
1919 pointer_info->toplevel_under_pointer = NULL;
1924 window_remove_from_pointer_info (GdkWindow *window,
1925 GdkDisplay *display)
1927 _gdk_display_pointer_info_foreach (display,
1928 update_pointer_info_foreach,
1933 * _gdk_window_destroy_hierarchy:
1934 * @window: a #GdkWindow
1935 * @recursing: If TRUE, then this is being called because a parent
1937 * @recursing_native: If TRUE, then this is being called because a native parent
1938 * was destroyed. This generally means that the call to the
1939 * windowing system to destroy the window can be omitted, since
1940 * it will be destroyed as a result of the parent being destroyed.
1941 * Unless @foreign_destroy.
1942 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1943 * external agency. The window has already been destroyed and no
1944 * windowing system calls should be made. (This may never happen
1945 * for some windowing systems.)
1947 * Internal function to destroy a window. Like gdk_window_destroy(),
1948 * but does not drop the reference count created by gdk_window_new().
1951 _gdk_window_destroy_hierarchy (GdkWindow *window,
1953 gboolean recursing_native,
1954 gboolean foreign_destroy)
1956 GdkWindowObject *private;
1957 GdkWindowObject *temp_private;
1958 GdkWindowImplIface *impl_iface;
1959 GdkWindow *temp_window;
1961 GdkDisplay *display;
1965 g_return_if_fail (GDK_IS_WINDOW (window));
1967 private = (GdkWindowObject*) window;
1969 if (GDK_WINDOW_DESTROYED (window))
1972 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
1973 screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
1974 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1975 if (temp_window == window)
1976 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1979 switch (private->window_type)
1981 case GDK_WINDOW_ROOT:
1982 if (!screen->closed)
1984 g_error ("attempted to destroy root window");
1987 /* else fall thru */
1988 case GDK_WINDOW_TOPLEVEL:
1989 case GDK_WINDOW_CHILD:
1990 case GDK_WINDOW_TEMP:
1991 case GDK_WINDOW_FOREIGN:
1992 case GDK_WINDOW_OFFSCREEN:
1993 if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
1995 /* Logically, it probably makes more sense to send
1996 * a "destroy yourself" message to the foreign window
1997 * whether or not it's in our hierarchy; but for historical
1998 * reasons, we only send "destroy yourself" messages to
1999 * foreign windows in our hierarchy.
2001 if (private->parent)
2002 _gdk_windowing_window_destroy_foreign (window);
2004 /* Also for historical reasons, we remove any filters
2005 * on a foreign window when it or a parent is destroyed;
2006 * this likely causes problems if two separate portions
2007 * of code are maintaining filter lists on a foreign window.
2009 window_remove_filters (window);
2013 if (private->parent)
2015 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
2017 if (parent_private->children)
2018 parent_private->children = g_list_remove (parent_private->children, window);
2021 GDK_WINDOW_IS_MAPPED (window))
2023 recompute_visible_regions (private, TRUE, FALSE);
2024 gdk_window_invalidate_in_parent (private);
2028 gdk_window_free_paint_stack (window);
2030 gdk_window_set_background_pattern (window, NULL);
2032 if (private->background)
2034 cairo_pattern_destroy (private->background);
2035 private->background = NULL;
2038 if (private->window_type == GDK_WINDOW_FOREIGN)
2039 g_assert (private->children == NULL);
2042 children = tmp = private->children;
2043 private->children = NULL;
2047 temp_window = tmp->data;
2050 temp_private = (GdkWindowObject*) temp_window;
2052 _gdk_window_destroy_hierarchy (temp_window,
2054 recursing_native || gdk_window_has_impl (private),
2058 g_list_free (children);
2061 _gdk_window_clear_update_area (window);
2063 gdk_window_drop_cairo_surface (private);
2065 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2067 if (gdk_window_has_impl (private))
2068 impl_iface->destroy (window, recursing_native,
2072 /* hide to make sure we repaint and break grabs */
2073 gdk_window_hide (window);
2076 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2077 private->parent = NULL;
2078 private->destroyed = TRUE;
2080 window_remove_filters (window);
2082 gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
2084 window_remove_from_pointer_info (window, display);
2086 if (private->clip_region)
2088 cairo_region_destroy (private->clip_region);
2089 private->clip_region = NULL;
2092 if (private->clip_region_with_children)
2094 cairo_region_destroy (private->clip_region_with_children);
2095 private->clip_region_with_children = NULL;
2098 if (private->outstanding_moves)
2100 g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2101 g_list_free (private->outstanding_moves);
2102 private->outstanding_moves = NULL;
2110 * _gdk_window_destroy:
2111 * @window: a #GdkWindow
2112 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2113 * external agency. The window has already been destroyed and no
2114 * windowing system calls should be made. (This may never happen
2115 * for some windowing systems.)
2117 * Internal function to destroy a window. Like gdk_window_destroy(),
2118 * but does not drop the reference count created by gdk_window_new().
2121 _gdk_window_destroy (GdkWindow *window,
2122 gboolean foreign_destroy)
2124 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2128 * gdk_window_destroy:
2129 * @window: a #GdkWindow
2131 * Destroys the window system resources associated with @window and decrements @window's
2132 * reference count. The window system resources for all children of @window are also
2133 * destroyed, but the children's reference counts are not decremented.
2135 * Note that a window will not be destroyed automatically when its reference count
2136 * reaches zero. You must call this function yourself before that happens.
2140 gdk_window_destroy (GdkWindow *window)
2142 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2143 g_object_unref (window);
2147 * gdk_window_set_user_data:
2148 * @window: a #GdkWindow
2149 * @user_data: user data
2151 * For most purposes this function is deprecated in favor of
2152 * g_object_set_data(). However, for historical reasons GTK+ stores
2153 * the #GtkWidget that owns a #GdkWindow as user data on the
2154 * #GdkWindow. So, custom widget implementations should use
2155 * this function for that. If GTK+ receives an event for a #GdkWindow,
2156 * and the user data for the window is non-%NULL, GTK+ will assume the
2157 * user data is a #GtkWidget, and forward the event to that widget.
2161 gdk_window_set_user_data (GdkWindow *window,
2164 g_return_if_fail (GDK_IS_WINDOW (window));
2166 ((GdkWindowObject*)window)->user_data = user_data;
2170 * gdk_window_get_user_data:
2171 * @window: a #GdkWindow
2172 * @data: return location for user data
2174 * Retrieves the user data for @window, which is normally the widget
2175 * that @window belongs to. See gdk_window_set_user_data().
2179 gdk_window_get_user_data (GdkWindow *window,
2182 g_return_if_fail (GDK_IS_WINDOW (window));
2184 *data = ((GdkWindowObject*)window)->user_data;
2188 * gdk_window_get_window_type:
2189 * @window: a #GdkWindow
2191 * Gets the type of the window. See #GdkWindowType.
2193 * Return value: type of window
2196 gdk_window_get_window_type (GdkWindow *window)
2198 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2200 return GDK_WINDOW_TYPE (window);
2204 * gdk_window_is_destroyed:
2205 * @window: a #GdkWindow
2207 * Check to see if a window is destroyed..
2209 * Return value: %TRUE if the window is destroyed
2214 gdk_window_is_destroyed (GdkWindow *window)
2216 return GDK_WINDOW_DESTROYED (window);
2220 to_embedder (GdkWindowObject *window,
2221 gdouble offscreen_x,
2222 gdouble offscreen_y,
2223 gdouble *embedder_x,
2224 gdouble *embedder_y)
2226 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2227 offscreen_x, offscreen_y,
2228 embedder_x, embedder_y);
2232 from_embedder (GdkWindowObject *window,
2235 gdouble *offscreen_x,
2236 gdouble *offscreen_y)
2238 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2239 embedder_x, embedder_y,
2240 offscreen_x, offscreen_y);
2244 * gdk_window_has_native:
2245 * @window: a #GdkWindow
2247 * Checks whether the window has a native window or not. Note that
2248 * you can use gdk_window_ensure_native() if a native window is needed.
2250 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2255 gdk_window_has_native (GdkWindow *window)
2259 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2261 w = GDK_WINDOW_OBJECT (window);
2263 return w->parent == NULL || w->parent->impl != w->impl;
2267 * gdk_window_get_position:
2268 * @window: a #GdkWindow
2269 * @x: X coordinate of window
2270 * @y: Y coordinate of window
2272 * Obtains the position of the window as reported in the
2273 * most-recently-processed #GdkEventConfigure. Contrast with
2274 * gdk_window_get_geometry() which queries the X server for the
2275 * current window position, regardless of which events have been
2276 * received or processed.
2278 * The position coordinates are relative to the window's parent window.
2282 gdk_window_get_position (GdkWindow *window,
2286 GdkWindowObject *obj;
2288 g_return_if_fail (GDK_IS_WINDOW (window));
2290 obj = (GdkWindowObject*) window;
2299 * gdk_window_get_parent:
2300 * @window: a #GdkWindow
2302 * Obtains the parent of @window, as known to GDK. Does not query the
2303 * X server; thus this returns the parent as passed to gdk_window_new(),
2304 * not the actual parent. This should never matter unless you're using
2305 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2306 * matter for toplevel windows, because the window manager may choose
2309 * Note that you should use gdk_window_get_effective_parent() when
2310 * writing generic code that walks up a window hierarchy, because
2311 * gdk_window_get_parent() will most likely not do what you expect if
2312 * there are offscreen windows in the hierarchy.
2314 * Return value: (transfer none): parent of @window
2317 gdk_window_get_parent (GdkWindow *window)
2319 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2321 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2325 * gdk_window_get_effective_parent:
2326 * @window: a #GdkWindow
2328 * Obtains the parent of @window, as known to GDK. Works like
2329 * gdk_window_get_parent() for normal windows, but returns the
2330 * window's embedder for offscreen windows.
2332 * See also: gdk_offscreen_window_get_embedder()
2334 * Return value: (transfer none): effective parent of @window
2339 gdk_window_get_effective_parent (GdkWindow *window)
2341 GdkWindowObject *obj;
2343 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2345 obj = (GdkWindowObject *)window;
2347 if (gdk_window_is_offscreen (obj))
2348 return gdk_offscreen_window_get_embedder (window);
2350 return (GdkWindow *) obj->parent;
2354 * gdk_window_get_toplevel:
2355 * @window: a #GdkWindow
2357 * Gets the toplevel window that's an ancestor of @window.
2359 * Any window type but %GDK_WINDOW_CHILD is considered a
2360 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2361 * has a root window as parent.
2363 * Note that you should use gdk_window_get_effective_toplevel() when
2364 * you want to get to a window's toplevel as seen on screen, because
2365 * gdk_window_get_toplevel() will most likely not do what you expect
2366 * if there are offscreen windows in the hierarchy.
2368 * Return value: (transfer none): the toplevel window containing @window
2371 gdk_window_get_toplevel (GdkWindow *window)
2373 GdkWindowObject *obj;
2375 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2377 obj = (GdkWindowObject *)window;
2379 while (obj->window_type == GDK_WINDOW_CHILD)
2381 if (gdk_window_is_toplevel (obj))
2386 return GDK_WINDOW (obj);
2390 * gdk_window_get_effective_toplevel:
2391 * @window: a #GdkWindow
2393 * Gets the toplevel window that's an ancestor of @window.
2395 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2396 * embedder as its parent, using gdk_window_get_effective_parent().
2398 * See also: gdk_offscreen_window_get_embedder()
2400 * Return value: (transfer none): the effective toplevel window containing @window
2405 gdk_window_get_effective_toplevel (GdkWindow *window)
2409 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2411 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2412 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2419 * gdk_window_get_children:
2420 * @window: a #GdkWindow
2422 * Gets the list of children of @window known to GDK.
2423 * This function only returns children created via GDK,
2424 * so for example it's useless when used with the root window;
2425 * it only returns windows an application created itself.
2427 * The returned list must be freed, but the elements in the
2430 * Return value: (transfer container) (element-type GdkWindow):
2431 * list of child windows inside @window
2434 gdk_window_get_children (GdkWindow *window)
2436 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2438 if (GDK_WINDOW_DESTROYED (window))
2441 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2445 * gdk_window_peek_children:
2446 * @window: a #GdkWindow
2448 * Like gdk_window_get_children(), but does not copy the list of
2449 * children, so the list does not need to be freed.
2451 * Return value: (transfer none) (element-type GdkWindow):
2452 * a reference to the list of child windows in @window
2455 gdk_window_peek_children (GdkWindow *window)
2457 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2459 if (GDK_WINDOW_DESTROYED (window))
2462 return GDK_WINDOW_OBJECT (window)->children;
2466 * gdk_window_add_filter:
2467 * @window: a #GdkWindow
2468 * @function: filter callback
2469 * @data: data to pass to filter callback
2471 * Adds an event filter to @window, allowing you to intercept events
2472 * before they reach GDK. This is a low-level operation and makes it
2473 * easy to break GDK and/or GTK+, so you have to know what you're
2474 * doing. Pass %NULL for @window to get all events for all windows,
2475 * instead of events for a specific window.
2477 * See gdk_display_add_client_message_filter() if you are interested
2478 * in X ClientMessage events.
2481 gdk_window_add_filter (GdkWindow *window,
2482 GdkFilterFunc function,
2485 GdkWindowObject *private;
2487 GdkEventFilter *filter;
2489 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2491 private = (GdkWindowObject*) window;
2492 if (private && GDK_WINDOW_DESTROYED (window))
2495 /* Filters are for the native events on the native window, so
2496 ensure there is a native window. */
2498 gdk_window_ensure_native (window);
2501 tmp_list = private->filters;
2503 tmp_list = _gdk_default_filters;
2507 filter = (GdkEventFilter *)tmp_list->data;
2508 if ((filter->function == function) && (filter->data == data))
2510 tmp_list = tmp_list->next;
2513 filter = g_new (GdkEventFilter, 1);
2514 filter->function = function;
2515 filter->data = data;
2518 private->filters = g_list_append (private->filters, filter);
2520 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2524 * gdk_window_remove_filter:
2525 * @window: a #GdkWindow
2526 * @function: previously-added filter function
2527 * @data: user data for previously-added filter function
2529 * Remove a filter previously added with gdk_window_add_filter().
2533 gdk_window_remove_filter (GdkWindow *window,
2534 GdkFilterFunc function,
2537 GdkWindowObject *private;
2538 GList *tmp_list, *node;
2539 GdkEventFilter *filter;
2541 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2543 private = (GdkWindowObject*) window;
2546 tmp_list = private->filters;
2548 tmp_list = _gdk_default_filters;
2552 filter = (GdkEventFilter *)tmp_list->data;
2554 tmp_list = tmp_list->next;
2556 if ((filter->function == function) && (filter->data == data))
2559 private->filters = g_list_remove_link (private->filters, node);
2561 _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
2562 g_list_free_1 (node);
2571 * gdk_screen_get_toplevel_windows:
2572 * @screen: The #GdkScreen where the toplevels are located.
2574 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2575 * A toplevel window is a child of the root window (see
2576 * gdk_get_default_root_window()).
2578 * The returned list should be freed with g_list_free(), but
2579 * its elements need not be freed.
2581 * Return value: (transfer container) (element-type GdkWindow):
2582 * list of toplevel windows, free with g_list_free()
2587 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2589 GdkWindow * root_window;
2590 GList *new_list = NULL;
2593 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2595 root_window = gdk_screen_get_root_window (screen);
2597 tmp_list = ((GdkWindowObject *)root_window)->children;
2600 GdkWindowObject *w = tmp_list->data;
2602 if (w->window_type != GDK_WINDOW_FOREIGN)
2603 new_list = g_list_prepend (new_list, w);
2604 tmp_list = tmp_list->next;
2611 * gdk_window_is_visible:
2612 * @window: a #GdkWindow
2614 * Checks whether the window has been mapped (with gdk_window_show() or
2615 * gdk_window_show_unraised()).
2617 * Return value: %TRUE if the window is mapped
2620 gdk_window_is_visible (GdkWindow *window)
2622 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2624 return GDK_WINDOW_IS_MAPPED (window);
2628 * gdk_window_is_viewable:
2629 * @window: a #GdkWindow
2631 * Check if the window and all ancestors of the window are
2632 * mapped. (This is not necessarily "viewable" in the X sense, since
2633 * we only check as far as we have GDK window parents, not to the root
2636 * Return value: %TRUE if the window is viewable
2639 gdk_window_is_viewable (GdkWindow *window)
2641 GdkWindowObject *private = (GdkWindowObject *)window;
2643 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2645 if (private->destroyed)
2648 return private->viewable;
2652 * gdk_window_get_state:
2653 * @window: a #GdkWindow
2655 * Gets the bitwise OR of the currently active window state flags,
2656 * from the #GdkWindowState enumeration.
2658 * Return value: window state bitfield
2661 gdk_window_get_state (GdkWindow *window)
2663 GdkWindowObject *private = (GdkWindowObject *)window;
2665 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2667 return private->state;
2671 /* This creates an empty "implicit" paint region for the impl window.
2672 * By itself this does nothing, but real paints to this window
2673 * or children of it can use this pixmap as backing to avoid allocating
2674 * multiple pixmaps for subwindow rendering. When doing so they
2675 * add to the region of the implicit paint region, which will be
2676 * pushed to the window when the implicit paint region is ended.
2677 * Such paints should not copy anything to the window on paint end, but
2678 * should rely on the implicit paint end.
2679 * The implicit paint will be automatically ended if someone draws
2680 * directly to the window or a child window.
2683 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2685 GdkWindowObject *private = (GdkWindowObject *)window;
2686 GdkWindowPaint *paint;
2688 g_assert (gdk_window_has_impl (private));
2690 if (_gdk_native_windows)
2691 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2693 if (GDK_IS_PAINTABLE (private->impl))
2694 return FALSE; /* Implementation does double buffering */
2696 if (private->paint_stack != NULL ||
2697 private->implicit_paint != NULL)
2698 return FALSE; /* Don't stack implicit paints */
2700 if (private->outstanding_surfaces != 0)
2701 return FALSE; /* May conflict with direct drawing to cairo surface */
2703 /* Never do implicit paints for foreign windows, they don't need
2704 * double buffer combination since they have no client side children,
2705 * and creating pixmaps for them is risky since they could disappear
2708 if (private->window_type == GDK_WINDOW_FOREIGN)
2711 paint = g_new (GdkWindowPaint, 1);
2712 paint->region = cairo_region_create (); /* Empty */
2713 paint->x_offset = rect->x;
2714 paint->y_offset = rect->y;
2715 paint->uses_implicit = FALSE;
2716 paint->flushed = FALSE;
2717 paint->surface = NULL;
2719 gdk_pixmap_new (window,
2720 MAX (rect->width, 1), MAX (rect->height, 1), -1);
2722 private->implicit_paint = paint;
2727 /* Ensure that all content related to this (sub)window is pushed to the
2728 native region. If there is an active paint then that area is not
2729 pushed, in order to not show partially finished double buffers. */
2731 gdk_window_flush_implicit_paint (GdkWindow *window)
2733 GdkWindowObject *private = (GdkWindowObject *)window;
2734 GdkWindowObject *impl_window;
2735 GdkWindowPaint *paint;
2736 cairo_region_t *region;
2739 impl_window = gdk_window_get_impl_window (private);
2740 if (impl_window->implicit_paint == NULL)
2743 paint = impl_window->implicit_paint;
2744 paint->flushed = TRUE;
2745 region = cairo_region_copy (private->clip_region_with_children);
2747 /* Don't flush active double buffers, as that may show partially done
2749 for (list = private->paint_stack; list != NULL; list = list->next)
2751 GdkWindowPaint *tmp_paint = list->data;
2753 cairo_region_subtract (region, tmp_paint->region);
2756 cairo_region_translate (region, private->abs_x, private->abs_y);
2757 cairo_region_intersect (region, paint->region);
2759 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2763 /* Remove flushed region from the implicit paint */
2764 cairo_region_subtract (paint->region, region);
2766 /* Some regions are valid, push these to window now */
2767 cr = gdk_cairo_create (private->impl);
2768 gdk_cairo_set_source_pixmap (cr, paint->pixmap,
2769 paint->x_offset, paint->y_offset);
2770 gdk_cairo_region (cr, region);
2775 cairo_region_destroy (region);
2778 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2780 gdk_window_end_implicit_paint (GdkWindow *window)
2782 GdkWindowObject *private = (GdkWindowObject *)window;
2783 GdkWindowPaint *paint;
2785 g_assert (gdk_window_has_impl (private));
2787 g_assert (private->implicit_paint != NULL);
2789 paint = private->implicit_paint;
2791 private->implicit_paint = NULL;
2793 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2797 /* Some regions are valid, push these to window now */
2798 cr = gdk_cairo_create (private->impl);
2799 gdk_cairo_region (cr, paint->region);
2801 gdk_cairo_set_source_pixmap (cr, paint->pixmap,
2802 paint->x_offset, paint->y_offset);
2803 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2808 cairo_region_destroy (paint->region);
2810 g_object_unref (paint->pixmap);
2815 * gdk_window_begin_paint_rect:
2816 * @window: a #GdkWindow
2817 * @rectangle: rectangle you intend to draw to
2819 * A convenience wrapper around gdk_window_begin_paint_region() which
2820 * creates a rectangular region for you. See
2821 * gdk_window_begin_paint_region() for details.
2825 gdk_window_begin_paint_rect (GdkWindow *window,
2826 const GdkRectangle *rectangle)
2828 cairo_region_t *region;
2830 g_return_if_fail (GDK_IS_WINDOW (window));
2832 region = cairo_region_create_rectangle (rectangle);
2833 gdk_window_begin_paint_region (window, region);
2834 cairo_region_destroy (region);
2838 * gdk_window_begin_paint_region:
2839 * @window: a #GdkWindow
2840 * @region: region you intend to draw to
2842 * Indicates that you are beginning the process of redrawing @region.
2843 * A backing store (offscreen buffer) large enough to contain @region
2844 * will be created. The backing store will be initialized with the
2845 * background color or background pixmap for @window. Then, all
2846 * drawing operations performed on @window will be diverted to the
2847 * backing store. When you call gdk_window_end_paint(), the backing
2848 * store will be copied to @window, making it visible onscreen. Only
2849 * the part of @window contained in @region will be modified; that is,
2850 * drawing operations are clipped to @region.
2852 * The net result of all this is to remove flicker, because the user
2853 * sees the finished product appear all at once when you call
2854 * gdk_window_end_paint(). If you draw to @window directly without
2855 * calling gdk_window_begin_paint_region(), the user may see flicker
2856 * as individual drawing operations are performed in sequence. The
2857 * clipping and background-initializing features of
2858 * gdk_window_begin_paint_region() are conveniences for the
2859 * programmer, so you can avoid doing that work yourself.
2861 * When using GTK+, the widget system automatically places calls to
2862 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2863 * emissions of the expose_event signal. That is, if you're writing an
2864 * expose event handler, you can assume that the exposed area in
2865 * #GdkEventExpose has already been cleared to the window background,
2866 * is already set as the clip region, and already has a backing store.
2867 * Therefore in most cases, application code need not call
2868 * gdk_window_begin_paint_region(). (You can disable the automatic
2869 * calls around expose events on a widget-by-widget basis by calling
2870 * gtk_widget_set_double_buffered().)
2872 * If you call this function multiple times before calling the
2873 * matching gdk_window_end_paint(), the backing stores are pushed onto
2874 * a stack. gdk_window_end_paint() copies the topmost backing store
2875 * onscreen, subtracts the topmost region from all other regions in
2876 * the stack, and pops the stack. All drawing operations affect only
2877 * the topmost backing store in the stack. One matching call to
2878 * gdk_window_end_paint() is required for each call to
2879 * gdk_window_begin_paint_region().
2883 gdk_window_begin_paint_region (GdkWindow *window,
2884 const cairo_region_t *region)
2886 #ifdef USE_BACKING_STORE
2887 GdkWindowObject *private = (GdkWindowObject *)window;
2888 GdkRectangle clip_box;
2889 GdkWindowPaint *paint, *implicit_paint;
2890 GdkWindowObject *impl_window;
2893 g_return_if_fail (GDK_IS_WINDOW (window));
2895 if (GDK_WINDOW_DESTROYED (window))
2898 if (GDK_IS_PAINTABLE (private->impl))
2900 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
2902 if (iface->begin_paint_region)
2903 iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
2908 impl_window = gdk_window_get_impl_window (private);
2909 implicit_paint = impl_window->implicit_paint;
2911 paint = g_new (GdkWindowPaint, 1);
2912 paint->region = cairo_region_copy (region);
2913 paint->region_tag = new_region_tag ();
2915 cairo_region_intersect (paint->region, private->clip_region_with_children);
2916 cairo_region_get_extents (paint->region, &clip_box);
2918 /* Convert to impl coords */
2919 cairo_region_translate (paint->region, private->abs_x, private->abs_y);
2921 /* Mark the region as valid on the implicit paint */
2924 cairo_region_union (implicit_paint->region, paint->region);
2926 /* Convert back to normal coords */
2927 cairo_region_translate (paint->region, -private->abs_x, -private->abs_y);
2933 paint->uses_implicit = TRUE;
2934 paint->pixmap = g_object_ref (implicit_paint->pixmap);
2935 paint->x_offset = -private->abs_x + implicit_paint->x_offset;
2936 paint->y_offset = -private->abs_y + implicit_paint->y_offset;
2938 gdk_drawable_get_size (paint->pixmap, &width, &height);
2939 paint->surface = _gdk_drawable_create_cairo_surface (paint->pixmap, width, height);
2943 paint->uses_implicit = FALSE;
2944 paint->x_offset = clip_box.x;
2945 paint->y_offset = clip_box.y;
2947 gdk_pixmap_new (window,
2948 MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1);
2949 paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap);
2953 cairo_surface_set_device_offset (paint->surface,
2954 -paint->x_offset, -paint->y_offset);
2956 for (list = private->paint_stack; list != NULL; list = list->next)
2958 GdkWindowPaint *tmp_paint = list->data;
2960 cairo_region_subtract (tmp_paint->region, paint->region);
2963 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
2965 if (!cairo_region_is_empty (paint->region))
2967 gdk_window_clear_backing_region (window,
2971 #endif /* USE_BACKING_STORE */
2975 * gdk_window_end_paint:
2976 * @window: a #GdkWindow
2978 * Indicates that the backing store created by the most recent call to
2979 * gdk_window_begin_paint_region() should be copied onscreen and
2980 * deleted, leaving the next-most-recent backing store or no backing
2981 * store at all as the active paint region. See
2982 * gdk_window_begin_paint_region() for full details. It is an error to
2983 * call this function without a matching
2984 * gdk_window_begin_paint_region() first.
2988 gdk_window_end_paint (GdkWindow *window)
2990 #ifdef USE_BACKING_STORE
2991 GdkWindowObject *private = (GdkWindowObject *)window;
2992 GdkWindowObject *composited;
2993 GdkWindowPaint *paint;
2994 GdkRectangle clip_box;
2995 cairo_region_t *full_clip;
2997 g_return_if_fail (GDK_IS_WINDOW (window));
2999 if (GDK_WINDOW_DESTROYED (window))
3002 if (GDK_IS_PAINTABLE (private->impl))
3004 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3006 if (iface->end_paint)
3007 iface->end_paint ((GdkPaintable*)private->impl);
3011 if (private->paint_stack == NULL)
3013 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3017 paint = private->paint_stack->data;
3019 private->paint_stack = g_slist_delete_link (private->paint_stack,
3020 private->paint_stack);
3022 cairo_region_get_extents (paint->region, &clip_box);
3024 if (!paint->uses_implicit)
3028 gdk_window_flush_outstanding_moves (window);
3030 full_clip = cairo_region_copy (private->clip_region_with_children);
3031 cairo_region_intersect (full_clip, paint->region);
3033 cr = gdk_cairo_create (private->impl);
3034 gdk_cairo_set_source_pixmap (cr, paint->pixmap, 0, 0);
3035 cairo_translate (cr, private->abs_x, private->abs_y);
3036 gdk_cairo_region (cr, full_clip);
3040 cairo_region_destroy (full_clip);
3043 cairo_surface_destroy (paint->surface);
3044 g_object_unref (paint->pixmap);
3045 cairo_region_destroy (paint->region);
3048 /* find a composited window in our hierarchy to signal its
3049 * parent to redraw, calculating the clip box as we go...
3051 * stop if parent becomes NULL since then we'd have nowhere
3052 * to draw (ie: 'composited' will always be non-NULL here).
3054 for (composited = private;
3056 composited = composited->parent)
3060 gdk_drawable_get_size (GDK_DRAWABLE (composited->parent),
3063 clip_box.x += composited->x;
3064 clip_box.y += composited->y;
3065 clip_box.width = MIN (clip_box.width, width - clip_box.x);
3066 clip_box.height = MIN (clip_box.height, height - clip_box.y);
3068 if (composited->composited)
3070 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3075 #endif /* USE_BACKING_STORE */
3079 gdk_window_free_paint_stack (GdkWindow *window)
3081 GdkWindowObject *private = (GdkWindowObject *)window;
3083 if (private->paint_stack)
3085 GSList *tmp_list = private->paint_stack;
3089 GdkWindowPaint *paint = tmp_list->data;
3091 if (tmp_list == private->paint_stack)
3092 g_object_unref (paint->pixmap);
3094 cairo_region_destroy (paint->region);
3097 tmp_list = tmp_list->next;
3100 g_slist_free (private->paint_stack);
3101 private->paint_stack = NULL;
3106 do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3107 cairo_region_t *dest_region, /* In impl window coords */
3110 GdkWindowImplIface *impl_iface;
3112 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (impl_window->impl);
3114 impl_iface->translate ((GdkWindow *) impl_window, dest_region, dx, dy);
3117 static GdkWindowRegionMove *
3118 gdk_window_region_move_new (cairo_region_t *region,
3121 GdkWindowRegionMove *move;
3123 move = g_slice_new (GdkWindowRegionMove);
3124 move->dest_region = cairo_region_copy (region);
3132 gdk_window_region_move_free (GdkWindowRegionMove *move)
3134 cairo_region_destroy (move->dest_region);
3135 g_slice_free (GdkWindowRegionMove, move);
3139 append_move_region (GdkWindowObject *impl_window,
3140 cairo_region_t *new_dest_region,
3143 GdkWindowRegionMove *move, *old_move;
3144 cairo_region_t *new_total_region, *old_total_region;
3145 cairo_region_t *source_overlaps_destination;
3146 cairo_region_t *non_overwritten;
3147 gboolean added_move;
3150 if (cairo_region_is_empty (new_dest_region))
3153 /* In principle this could just append the move to the list of outstanding
3154 moves that will be replayed before drawing anything when we're handling
3155 exposes. However, we'd like to do a bit better since its commonly the case
3156 that we get multiple copies where A is copied to B and then B is copied
3157 to C, and we'd like to express this as a simple copy A to C operation. */
3159 /* We approach this by taking the new move and pushing it ahead of moves
3160 starting at the end of the list and stopping when its not safe to do so.
3161 It's not safe to push past a move if either the source of the new move
3162 is in the destination of the old move, or if the destination of the new
3163 move is in the source of the new move, or if the destination of the new
3164 move overlaps the destination of the old move. We simplify this by
3165 just comparing the total regions (src + dest) */
3166 new_total_region = cairo_region_copy (new_dest_region);
3167 cairo_region_translate (new_total_region, -dx, -dy);
3168 cairo_region_union (new_total_region, new_dest_region);
3171 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3176 old_total_region = cairo_region_copy (old_move->dest_region);
3177 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3178 cairo_region_union (old_total_region, old_move->dest_region);
3180 cairo_region_intersect (old_total_region, new_total_region);
3181 /* If these regions intersect then its not safe to push the
3182 new region before the old one */
3183 if (!cairo_region_is_empty (old_total_region))
3185 /* The area where the new moves source overlaps the old ones
3187 source_overlaps_destination = cairo_region_copy (new_dest_region);
3188 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3189 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3190 cairo_region_translate (source_overlaps_destination, dx, dy);
3192 /* We can do all sort of optimizations here, but to do things safely it becomes
3193 quite complicated. However, a very common case is that you copy something first,
3194 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3195 in the same direction). We'd like to detect this case and optimize it to one
3197 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3199 /* This means we might be able to replace the old move and the new one
3200 with the new one read from the old ones source, and a second copy of
3201 the non-overwritten parts of the old move. However, such a split
3202 is only valid if the source in the old move isn't overwritten
3203 by the destination of the new one */
3205 /* the new destination of old move if split is ok: */
3206 non_overwritten = cairo_region_copy (old_move->dest_region);
3207 cairo_region_subtract (non_overwritten, new_dest_region);
3208 /* move to source region */
3209 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3211 cairo_region_intersect (non_overwritten, new_dest_region);
3212 if (cairo_region_is_empty (non_overwritten))
3215 move = gdk_window_region_move_new (new_dest_region,
3219 impl_window->outstanding_moves =
3220 g_list_insert_before (impl_window->outstanding_moves,
3222 cairo_region_subtract (old_move->dest_region, new_dest_region);
3224 cairo_region_destroy (non_overwritten);
3227 cairo_region_destroy (source_overlaps_destination);
3228 cairo_region_destroy (old_total_region);
3231 cairo_region_destroy (old_total_region);
3234 cairo_region_destroy (new_total_region);
3238 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3241 impl_window->outstanding_moves =
3242 g_list_prepend (impl_window->outstanding_moves,
3245 impl_window->outstanding_moves =
3246 g_list_insert_before (impl_window->outstanding_moves,
3251 /* Moves bits and update area by dx/dy in impl window.
3252 Takes ownership of region to avoid copy (because we may change it) */
3254 move_region_on_impl (GdkWindowObject *impl_window,
3255 cairo_region_t *region, /* In impl window coords */
3258 if ((dx == 0 && dy == 0) ||
3259 cairo_region_is_empty (region))
3261 cairo_region_destroy (region);
3265 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3267 /* Move any old invalid regions in the copy source area by dx/dy */
3268 if (impl_window->update_area)
3270 cairo_region_t *update_area;
3272 update_area = cairo_region_copy (region);
3274 /* Convert from target to source */
3275 cairo_region_translate (update_area, -dx, -dy);
3276 cairo_region_intersect (update_area, impl_window->update_area);
3277 /* We only copy the area, so keep the old update area invalid.
3278 It would be safe to remove it too, as code that uses
3279 move_region_on_impl generally also invalidate the source
3280 area. However, it would just use waste cycles. */
3283 cairo_region_translate (update_area, dx, dy);
3284 cairo_region_union (impl_window->update_area, update_area);
3286 /* This area of the destination is now invalid,
3287 so no need to copy to it. */
3288 cairo_region_subtract (region, update_area);
3290 cairo_region_destroy (update_area);
3293 /* If we're currently exposing this window, don't copy to this
3294 destination, as it will be overdrawn when the expose is done,
3295 instead invalidate it and repaint later. */
3296 if (impl_window->implicit_paint)
3298 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3299 cairo_region_t *exposing;
3301 exposing = cairo_region_copy (implicit_paint->region);
3302 cairo_region_intersect (exposing, region);
3303 cairo_region_subtract (region, exposing);
3305 impl_window_add_update_area (impl_window, exposing);
3306 cairo_region_destroy (exposing);
3309 if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3310 append_move_region (impl_window, region, dx, dy);
3312 do_move_region_bits_on_impl (impl_window,
3315 cairo_region_destroy (region);
3318 /* Flushes all outstanding changes to the window, call this
3319 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3322 gdk_window_flush_outstanding_moves (GdkWindow *window)
3324 GdkWindowObject *private;
3325 GdkWindowObject *impl_window;
3326 GList *l, *outstanding;
3327 GdkWindowRegionMove *move;
3329 private = (GdkWindowObject *) window;
3331 impl_window = gdk_window_get_impl_window (private);
3332 outstanding = impl_window->outstanding_moves;
3333 impl_window->outstanding_moves = NULL;
3335 for (l = outstanding; l != NULL; l = l->next)
3339 do_move_region_bits_on_impl (impl_window,
3340 move->dest_region, move->dx, move->dy);
3342 gdk_window_region_move_free (move);
3345 g_list_free (outstanding);
3350 * @window: a #GdkWindow
3352 * Flush all outstanding cached operations on a window, leaving the
3353 * window in a state which reflects all that has been drawn before.
3355 * Gdk uses multiple kinds of caching to get better performance and
3356 * nicer drawing. For instance, during exposes all paints to a window
3357 * using double buffered rendering are keep on a pixmap until the last
3358 * window has been exposed. It also delays window moves/scrolls until
3359 * as long as possible until next update to avoid tearing when moving
3362 * Normally this should be completely invisible to applications, as
3363 * we automatically flush the windows when required, but this might
3364 * be needed if you for instance mix direct native drawing with
3365 * gdk drawing. For Gtk widgets that don't use double buffering this
3366 * will be called automatically before sending the expose event.
3371 gdk_window_flush (GdkWindow *window)
3373 gdk_window_flush_outstanding_moves (window);
3374 gdk_window_flush_implicit_paint (window);
3377 /* If we're about to move/resize or otherwise change the
3378 * hierarchy of a client side window in an impl and we're
3379 * called from an expose event handler then we need to
3380 * flush any already painted parts of the implicit paint
3381 * that are not part of the current paint, as these may
3382 * be used when scrolling or may overdraw the changes
3383 * caused by the hierarchy change.
3386 gdk_window_flush_if_exposing (GdkWindow *window)
3388 GdkWindowObject *private;
3389 GdkWindowObject *impl_window;
3391 private = (GdkWindowObject *) window;
3392 impl_window = gdk_window_get_impl_window (private);
3394 /* If we're in an implicit paint (i.e. in an expose handler, flush
3395 all the already finished exposes to get things to an uptodate state. */
3396 if (impl_window->implicit_paint)
3397 gdk_window_flush (window);
3402 gdk_window_flush_recursive_helper (GdkWindowObject *window,
3405 GdkWindowObject *child;
3408 for (l = window->children; l != NULL; l = l->next)
3412 if (child->impl == impl)
3413 /* Same impl, ignore */
3414 gdk_window_flush_recursive_helper (child, impl);
3416 gdk_window_flush_recursive (child);
3421 gdk_window_flush_recursive (GdkWindowObject *window)
3423 gdk_window_flush ((GdkWindow *)window);
3424 gdk_window_flush_recursive_helper (window, window->impl);
3428 gdk_window_get_offsets (GdkWindow *window,
3432 GdkWindowObject *private = (GdkWindowObject *)window;
3434 if (private->paint_stack)
3436 GdkWindowPaint *paint = private->paint_stack->data;
3437 *x_offset = paint->x_offset;
3438 *y_offset = paint->y_offset;
3442 *x_offset = -private->abs_x;
3443 *y_offset = -private->abs_y;
3448 * gdk_window_get_internal_paint_info:
3449 * @window: a #GdkWindow
3450 * @real_drawable: (out): location to store the drawable to which drawing should be
3452 * @x_offset: (out): location to store the X offset between coordinates in @window,
3453 * and the underlying window system primitive coordinates for
3455 * @y_offset: (out): location to store the Y offset between coordinates in @window,
3456 * and the underlying window system primitive coordinates for
3459 * If you bypass the GDK layer and use windowing system primitives to
3460 * draw directly onto a #GdkWindow, then you need to deal with two
3461 * details: there may be an offset between GDK coordinates and windowing
3462 * system coordinates, and GDK may have redirected drawing to a offscreen
3463 * pixmap as the result of a gdk_window_begin_paint_region() calls.
3464 * This function allows retrieving the information you need to compensate
3465 * for these effects.
3467 * This function exposes details of the GDK implementation, and is thus
3468 * likely to change in future releases of GDK.
3471 gdk_window_get_internal_paint_info (GdkWindow *window,
3472 GdkDrawable **real_drawable,
3478 GdkWindowObject *private;
3480 g_return_if_fail (GDK_IS_WINDOW (window));
3482 private = (GdkWindowObject *)window;
3486 if (private->paint_stack)
3488 GdkWindowPaint *paint = private->paint_stack->data;
3489 *real_drawable = paint->pixmap;
3493 /* This means you're probably gonna be doing some weird shit
3494 directly to the window, so we flush all outstanding stuff */
3495 gdk_window_flush (window);
3496 *real_drawable = window;
3500 gdk_window_get_offsets (window, &x_off, &y_off);
3508 static GdkDrawable *
3509 gdk_window_get_source_drawable (GdkDrawable *drawable)
3511 GdkWindow *window = GDK_WINDOW (drawable);
3512 GdkWindowObject *private;
3514 private = (GdkWindowObject *) window;
3515 if (GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable)
3516 return GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable (private->impl);
3521 static cairo_region_t*
3522 gdk_window_get_clip_region (GdkDrawable *drawable)
3524 GdkWindowObject *private = (GdkWindowObject *)drawable;
3525 cairo_region_t *result;
3527 result = cairo_region_copy (private->clip_region);
3529 if (private->paint_stack)
3531 cairo_region_t *paint_region = cairo_region_create ();
3532 GSList *tmp_list = private->paint_stack;
3536 GdkWindowPaint *paint = tmp_list->data;
3538 cairo_region_union (paint_region, paint->region);
3540 tmp_list = tmp_list->next;
3543 cairo_region_intersect (result, paint_region);
3544 cairo_region_destroy (paint_region);
3550 static cairo_region_t*
3551 gdk_window_get_visible_region (GdkDrawable *drawable)
3553 GdkWindowObject *private = (GdkWindowObject*) drawable;
3555 return cairo_region_copy (private->clip_region);
3559 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3561 GdkWindowObject *private = (GdkWindowObject *) window;
3562 GdkWindowObject *bg_private;
3563 cairo_pattern_t *pattern = NULL;
3564 int x_offset = 0, y_offset = 0;
3567 cr = cairo_create (paint->surface);
3569 for (bg_private = private; bg_private; bg_private = bg_private->parent)
3571 pattern = gdk_window_get_background_pattern ((GdkWindow *) bg_private);
3575 x_offset += bg_private->x;
3576 y_offset += bg_private->y;
3581 cairo_translate (cr, -x_offset, -y_offset);
3582 cairo_set_source (cr, pattern);
3583 cairo_translate (cr, x_offset, y_offset);
3586 cairo_set_source_rgb (cr, 0, 0, 0);
3592 gdk_window_clear_backing_region (GdkWindow *window,
3593 cairo_region_t *region)
3595 GdkWindowObject *private = (GdkWindowObject *)window;
3596 GdkWindowPaint *paint = private->paint_stack->data;
3597 cairo_region_t *clip;
3598 GdkRectangle clipbox;
3601 if (GDK_WINDOW_DESTROYED (window))
3604 cr = setup_backing_rect (window, paint, 0, 0);
3606 clip = cairo_region_copy (paint->region);
3607 cairo_region_intersect (clip, region);
3608 cairo_region_get_extents (clip, &clipbox);
3610 gdk_cairo_region (cr, clip);
3615 cairo_region_destroy (clip);
3619 gdk_window_clear_backing_region_direct (GdkWindow *window,
3620 cairo_region_t *region)
3622 GdkWindowObject *private = (GdkWindowObject *)window;
3623 GdkWindowPaint paint;
3624 cairo_region_t *clip;
3625 GdkRectangle clipbox;
3628 if (GDK_WINDOW_DESTROYED (window))
3633 paint.pixmap = window;
3634 paint.surface = _gdk_drawable_ref_cairo_surface (window);
3636 cr = setup_backing_rect (window, &paint, 0, 0);
3638 clip = cairo_region_copy (private->clip_region_with_children);
3639 cairo_region_intersect (clip, region);
3640 cairo_region_get_extents (clip, &clipbox);
3642 gdk_cairo_region (cr, clip);
3647 cairo_region_destroy (clip);
3648 cairo_surface_destroy (paint.surface);
3654 * @window: a #GdkWindow
3656 * Clears an entire @window to the background color or background pixmap.
3659 gdk_window_clear (GdkWindow *window)
3663 g_return_if_fail (GDK_IS_WINDOW (window));
3665 gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
3667 gdk_window_clear_area (window, 0, 0,
3672 gdk_window_clear_region_internal (GdkWindow *window,
3673 cairo_region_t *region)
3675 GdkWindowObject *private = (GdkWindowObject *)window;
3677 if (private->paint_stack)
3678 gdk_window_clear_backing_region (window, region);
3680 gdk_window_clear_backing_region_direct (window, region);
3684 * gdk_window_clear_area:
3685 * @window: a #GdkWindow
3686 * @x: x coordinate of rectangle to clear
3687 * @y: y coordinate of rectangle to clear
3688 * @width: width of rectangle to clear
3689 * @height: height of rectangle to clear
3691 * Clears an area of @window to the background color or background pixmap.
3695 gdk_window_clear_area (GdkWindow *window,
3702 cairo_region_t *region;
3704 g_return_if_fail (GDK_IS_WINDOW (window));
3706 if (GDK_WINDOW_DESTROYED (window))
3709 /* Terminate early to avoid weird interpretation of
3710 zero width/height by XClearArea */
3711 if (width == 0 || height == 0)
3717 rect.height = height;
3719 region = cairo_region_create_rectangle (&rect);
3720 gdk_window_clear_region_internal (window,
3722 cairo_region_destroy (region);
3726 gdk_window_real_get_size (GdkDrawable *drawable,
3730 GdkWindowObject *private = (GdkWindowObject *)drawable;
3733 *width = private->width;
3735 *height = private->height;
3739 gdk_window_real_get_visual (GdkDrawable *drawable)
3741 GdkColormap *colormap;
3743 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
3745 colormap = gdk_drawable_get_colormap (drawable);
3746 return colormap ? gdk_colormap_get_visual (colormap) : NULL;
3750 gdk_window_real_get_depth (GdkDrawable *drawable)
3752 g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
3754 return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
3758 gdk_window_real_get_screen (GdkDrawable *drawable)
3760 return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
3764 gdk_window_real_set_colormap (GdkDrawable *drawable,
3767 GdkWindowObject *private;
3769 g_return_if_fail (GDK_IS_WINDOW (drawable));
3771 if (GDK_WINDOW_DESTROYED (drawable))
3774 private = (GdkWindowObject *)drawable;
3776 /* different colormap than parent, requires native window */
3777 if (!private->input_only &&
3778 cmap != gdk_drawable_get_colormap ((GdkDrawable *)(private->parent)))
3779 gdk_window_ensure_native ((GdkWindow *)drawable);
3781 gdk_drawable_set_colormap (private->impl, cmap);
3785 gdk_window_real_get_colormap (GdkDrawable *drawable)
3787 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
3789 if (GDK_WINDOW_DESTROYED (drawable))
3792 return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
3796 gdk_window_drop_cairo_surface (GdkWindowObject *private)
3798 if (private->cairo_surface)
3800 cairo_surface_finish (private->cairo_surface);
3801 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3807 gdk_window_cairo_surface_destroy (void *data)
3809 GdkWindowObject *private = (GdkWindowObject*) data;
3811 private->cairo_surface = NULL;
3812 private->impl_window->outstanding_surfaces--;
3815 static cairo_surface_t *
3816 gdk_window_create_cairo_surface (GdkDrawable *drawable,
3820 return _gdk_windowing_create_cairo_surface (GDK_WINDOW_OBJECT(drawable)->impl,
3825 static cairo_surface_t *
3826 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
3828 GdkWindowObject *private = (GdkWindowObject*) drawable;
3829 cairo_surface_t *surface;
3831 if (private->paint_stack)
3833 GdkWindowPaint *paint = private->paint_stack->data;
3835 surface = paint->surface;
3836 cairo_surface_reference (surface);
3841 /* This will be drawing directly to the window, so flush implicit paint */
3842 gdk_window_flush ((GdkWindow *)drawable);
3844 if (!private->cairo_surface)
3847 GdkDrawable *source;
3849 /* It would be nice if we had some cairo support here so we
3850 could set the clip rect on the cairo surface */
3851 width = private->abs_x + private->width;
3852 height = private->abs_y + private->height;
3854 source = _gdk_drawable_get_source_drawable (drawable);
3856 private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height);
3858 if (private->cairo_surface)
3860 private->impl_window->outstanding_surfaces++;
3862 cairo_surface_set_device_offset (private->cairo_surface,
3866 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3867 drawable, gdk_window_cairo_surface_destroy);
3871 cairo_surface_reference (private->cairo_surface);
3873 surface = private->cairo_surface;
3880 gdk_window_set_cairo_clip (GdkDrawable *drawable,
3883 GdkWindowObject *private = (GdkWindowObject*) drawable;
3885 if (!private->paint_stack)
3887 cairo_reset_clip (cr);
3890 cairo_identity_matrix (cr);
3892 cairo_new_path (cr);
3893 gdk_cairo_region (cr, private->clip_region_with_children);
3900 GdkWindowPaint *paint = private->paint_stack->data;
3902 /* Only needs to clip to region if piggybacking
3903 on an implicit paint pixmap */
3904 cairo_reset_clip (cr);
3905 if (paint->uses_implicit)
3908 cairo_identity_matrix (cr);
3910 cairo_new_path (cr);
3911 gdk_cairo_region (cr, paint->region);
3919 /* Code for dirty-region queueing
3921 static GSList *update_windows = NULL;
3922 static guint update_idle = 0;
3923 static gboolean debug_updates = FALSE;
3925 static inline gboolean
3926 gdk_window_is_ancestor (GdkWindow *window,
3927 GdkWindow *ancestor)
3931 GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
3933 if (parent == ancestor)
3943 gdk_window_add_update_window (GdkWindow *window)
3946 GSList *prev = NULL;
3947 gboolean has_ancestor_in_list = FALSE;
3949 for (tmp = update_windows; tmp; tmp = tmp->next)
3951 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
3953 /* check if tmp is an ancestor of "window"; if it is, set a
3954 * flag indicating that all following windows are either
3955 * children of "window" or from a differen hierarchy
3957 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3958 has_ancestor_in_list = TRUE;
3960 /* insert in reverse stacking order when adding around siblings,
3961 * so processing updates properly paints over lower stacked windows
3963 if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
3965 gint index = g_list_index (parent->children, window);
3966 for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
3968 gint sibling_index = g_list_index (parent->children, tmp->data);
3969 if (index > sibling_index)
3973 /* here, tmp got advanced past all lower stacked siblings */
3974 tmp = g_slist_prepend (tmp, window);
3978 update_windows = tmp;
3982 /* if "window" has an ancestor in the list and tmp is one of
3983 * "window's" children, insert "window" before tmp
3985 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3987 tmp = g_slist_prepend (tmp, window);
3992 update_windows = tmp;
3996 /* if we're at the end of the list and had an ancestor it it,
3997 * append to the list
3999 if (! tmp->next && has_ancestor_in_list)
4001 tmp = g_slist_append (tmp, window);
4008 /* if all above checks failed ("window" is from a different
4009 * hierarchy than what is already in the list) or the list is
4012 update_windows = g_slist_prepend (update_windows, window);
4016 gdk_window_remove_update_window (GdkWindow *window)
4018 update_windows = g_slist_remove (update_windows, window);
4022 gdk_window_update_idle (gpointer data)
4024 gdk_window_process_all_updates ();
4030 gdk_window_is_toplevel_frozen (GdkWindow *window)
4032 GdkWindowObject *toplevel;
4034 toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
4036 return toplevel->update_and_descendants_freeze_count > 0;
4040 gdk_window_schedule_update (GdkWindow *window)
4043 (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
4044 gdk_window_is_toplevel_frozen (window)))
4049 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4050 gdk_window_update_idle,
4055 _gdk_window_process_updates_recurse (GdkWindow *window,
4056 cairo_region_t *expose_region)
4058 GdkWindowObject *private = (GdkWindowObject *)window;
4059 GdkWindowObject *child;
4060 cairo_region_t *child_region;
4062 GList *l, *children;
4064 if (cairo_region_is_empty (expose_region))
4067 if (gdk_window_is_offscreen (private->impl_window) &&
4068 private == private->impl_window)
4069 _gdk_window_add_damage ((GdkWindow *) private->impl_window, expose_region);
4071 /* Make this reentrancy safe for expose handlers freeing windows */
4072 children = g_list_copy (private->children);
4073 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4075 /* Iterate over children, starting at topmost */
4076 for (l = children; l != NULL; l = l->next)
4080 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
4083 /* Ignore offscreen children, as they don't draw in their parent and
4084 * don't take part in the clipping */
4085 if (gdk_window_is_offscreen (child))
4090 r.width = child->width;
4091 r.height = child->height;
4093 child_region = cairo_region_create_rectangle (&r);
4096 /* Adjust shape region to parent window coords */
4097 cairo_region_translate (child->shape, child->x, child->y);
4098 cairo_region_intersect (child_region, child->shape);
4099 cairo_region_translate (child->shape, -child->x, -child->y);
4102 if (child->impl == private->impl)
4104 /* Client side child, expose */
4105 cairo_region_intersect (child_region, expose_region);
4106 cairo_region_subtract (expose_region, child_region);
4107 cairo_region_translate (child_region, -child->x, -child->y);
4108 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
4112 /* Native child, just remove area from expose region */
4113 cairo_region_subtract (expose_region, child_region);
4115 cairo_region_destroy (child_region);
4118 g_list_foreach (children, (GFunc)g_object_unref, NULL);
4119 g_list_free (children);
4121 if (!cairo_region_is_empty (expose_region) &&
4122 !private->destroyed)
4124 if (private->event_mask & GDK_EXPOSURE_MASK)
4128 event.expose.type = GDK_EXPOSE;
4129 event.expose.window = g_object_ref (window);
4130 event.expose.send_event = FALSE;
4131 event.expose.count = 0;
4132 event.expose.region = expose_region;
4133 cairo_region_get_extents (expose_region, &event.expose.area);
4135 (*_gdk_event_func) (&event, _gdk_event_data);
4137 g_object_unref (window);
4139 else if (private->window_type != GDK_WINDOW_FOREIGN)
4141 /* No exposure mask set, so nothing will be drawn, the
4142 * app relies on the background being what it specified
4143 * for the window. So, we need to clear this manually.
4145 * For foreign windows if expose is not set that generally
4146 * means some other client paints them, so don't clear
4149 * We use begin/end_paint around the clear so that we can
4150 * piggyback on the implicit paint */
4152 gdk_window_begin_paint_region (window, expose_region);
4153 gdk_window_clear_region_internal (window, expose_region);
4154 gdk_window_end_paint (window);
4159 /* Process and remove any invalid area on the native window by creating
4160 * expose events for the window and all non-native descendants.
4161 * Also processes any outstanding moves on the window before doing
4162 * any drawing. Note that its possible to have outstanding moves without
4163 * any invalid area as we use the update idle mechanism to coalesce
4164 * multiple moves as well as multiple invalidations.
4167 gdk_window_process_updates_internal (GdkWindow *window)
4169 GdkWindowObject *private = (GdkWindowObject *)window;
4170 GdkWindowImplIface *impl_iface;
4171 gboolean save_region = FALSE;
4172 GdkRectangle clip_box;
4174 /* Ensure the window lives while updating it */
4175 g_object_ref (window);
4177 /* If an update got queued during update processing, we can get a
4178 * window in the update queue that has an empty update_area.
4181 if (private->update_area)
4183 cairo_region_t *update_area = private->update_area;
4184 private->update_area = NULL;
4186 if (_gdk_event_func && gdk_window_is_viewable (window))
4188 cairo_region_t *expose_region;
4189 gboolean end_implicit;
4191 /* Clip to part visible in toplevel */
4192 cairo_region_intersect (update_area, private->clip_region);
4196 /* Make sure we see the red invalid area before redrawing. */
4197 gdk_display_sync (gdk_drawable_get_display (window));
4201 /* At this point we will be completely redrawing all of update_area.
4202 * If we have any outstanding moves that end up moving stuff inside
4203 * this area we don't actually need to move that as that part would
4204 * be overdrawn by the expose anyway. So, in order to copy less data
4205 * we remove these areas from the outstanding moves.
4207 if (private->outstanding_moves)
4209 GdkWindowRegionMove *move;
4210 cairo_region_t *remove;
4213 remove = cairo_region_copy (update_area);
4214 /* We iterate backwards, starting from the state that would be
4215 if we had applied all the moves. */
4216 for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
4221 /* Don't need this area */
4222 cairo_region_subtract (move->dest_region, remove);
4224 /* However if any of the destination we do need has a source
4225 in the updated region we do need that as a destination for
4226 the earlier moves */
4227 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
4228 cairo_region_subtract (remove, move->dest_region);
4230 if (cairo_region_is_empty (move->dest_region))
4232 gdk_window_region_move_free (move);
4233 private->outstanding_moves =
4234 g_list_delete_link (private->outstanding_moves, l);
4236 else /* move back */
4237 cairo_region_translate (move->dest_region, move->dx, move->dy);
4239 cairo_region_destroy (remove);
4242 /* By now we a set of window moves that should be applied, and then
4243 * an update region that should be repainted. A trivial implementation
4244 * would just do that in order, however in order to get nicer drawing
4245 * we do some tricks:
4247 * First of all, each subwindow expose may be double buffered by
4248 * itself (depending on widget setting) via
4249 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
4250 * creating a single pixmap the size of the invalid area on the
4251 * native window which all the individual normal paints will draw
4252 * into. This way in the normal case there will be only one pixmap
4253 * allocated and only once pixmap draw done for all the windows
4254 * in this native window.
4255 * There are a couple of reasons this may fail, for instance, some
4256 * backends (like quartz) do its own double buffering, so we disable
4257 * gdk double buffering there. Secondly, some subwindow could be
4258 * non-double buffered and draw directly to the window outside a
4259 * begin/end_paint pair. That will be lead to a gdk_window_flush
4260 * which immediately executes all outstanding moves and paints+removes
4261 * the implicit paint (further paints will allocate their own pixmap).
4263 * Secondly, in the case of implicit double buffering we expose all
4264 * the child windows into the implicit pixmap before we execute
4265 * the outstanding moves. This way we minimize the time between
4266 * doing the moves and rendering the new update area, thus minimizing
4267 * flashing. Of course, if any subwindow is non-double buffered we
4268 * well flush earlier than that.
4270 * Thirdly, after having done the outstanding moves we queue an
4271 * "antiexpose" on the area that will be drawn by the expose, which
4272 * means that any invalid region on the native window side before
4273 * the first expose drawing operation will be discarded, as it
4274 * has by then been overdrawn with valid data. This means we can
4275 * avoid doing the unnecessary repaint any outstanding expose events.
4278 cairo_region_get_extents (update_area, &clip_box);
4279 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
4280 expose_region = cairo_region_copy (update_area);
4283 /* Rendering is not double buffered by gdk, do outstanding
4284 * moves and queue antiexposure immediately. No need to do
4286 gdk_window_flush_outstanding_moves (window);
4287 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4288 save_region = impl_iface->queue_antiexpose (window, update_area);
4291 /* Render the invalid areas to the implicit paint, by sending exposes.
4292 * May flush if non-double buffered widget draw. */
4293 _gdk_windowing_window_process_updates_recurse (window, expose_region);
4297 /* Do moves right before exposes are rendered to the window */
4298 gdk_window_flush_outstanding_moves (window);
4300 /* By this time we know that any outstanding expose for this
4301 * area is invalid and we can avoid it, so queue an antiexpose.
4302 * However, it may be that due to an non-double buffered expose
4303 * we have already started drawing to the window, so it would
4304 * be to late to anti-expose now. Since this is merely an
4305 * optimization we just avoid doing it at all in that case.
4307 if (private->implicit_paint != NULL &&
4308 !private->implicit_paint->flushed)
4310 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4311 save_region = impl_iface->queue_antiexpose (window, update_area);
4314 gdk_window_end_implicit_paint (window);
4316 cairo_region_destroy (expose_region);
4319 cairo_region_destroy (update_area);
4322 if (private->outstanding_moves)
4324 /* Flush any outstanding moves, may happen if we moved a window but got
4325 no actual invalid area */
4326 gdk_window_flush_outstanding_moves (window);
4329 g_object_unref (window);
4333 flush_all_displays (void)
4335 GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4338 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
4339 gdk_display_flush (tmp_list->data);
4341 g_slist_free (displays);
4344 /* Currently it is not possible to override
4345 * gdk_window_process_all_updates in the same manner as
4346 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4347 * by implementing the GdkPaintable interface. If in the future a
4348 * backend would need this, the right solution would be to add a
4349 * method to GdkDisplay that can be optionally
4350 * NULL. gdk_window_process_all_updates can then walk the list of open
4351 * displays and call the mehod.
4355 * gdk_window_process_all_updates:
4357 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4358 * in the application.
4362 gdk_window_process_all_updates (void)
4364 GSList *old_update_windows = update_windows;
4365 GSList *tmp_list = update_windows;
4366 static gboolean in_process_all_updates = FALSE;
4367 static gboolean got_recursive_update = FALSE;
4369 if (in_process_all_updates)
4371 /* We can't do this now since that would recurse, so
4372 delay it until after the recursion is done. */
4373 got_recursive_update = TRUE;
4378 in_process_all_updates = TRUE;
4379 got_recursive_update = FALSE;
4382 g_source_remove (update_idle);
4384 update_windows = NULL;
4387 _gdk_windowing_before_process_all_updates ();
4389 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4393 GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
4395 if (!GDK_WINDOW_DESTROYED (tmp_list->data))
4397 if (private->update_freeze_count ||
4398 gdk_window_is_toplevel_frozen (tmp_list->data))
4399 gdk_window_add_update_window ((GdkWindow *) private);
4401 gdk_window_process_updates_internal (tmp_list->data);
4404 g_object_unref (tmp_list->data);
4405 tmp_list = tmp_list->next;
4408 g_slist_free (old_update_windows);
4410 flush_all_displays ();
4412 _gdk_windowing_after_process_all_updates ();
4414 in_process_all_updates = FALSE;
4416 /* If we ignored a recursive call, schedule a
4417 redraw now so that it eventually happens,
4418 otherwise we could miss an update if nothing
4419 else schedules an update. */
4420 if (got_recursive_update && !update_idle)
4422 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4423 gdk_window_update_idle,
4428 * gdk_window_process_updates:
4429 * @window: a #GdkWindow
4430 * @update_children: whether to also process updates for child windows
4432 * Sends one or more expose events to @window. The areas in each
4433 * expose event will cover the entire update area for the window (see
4434 * gdk_window_invalidate_region() for details). Normally GDK calls
4435 * gdk_window_process_all_updates() on your behalf, so there's no
4436 * need to call this function unless you want to force expose events
4437 * to be delivered immediately and synchronously (vs. the usual
4438 * case, where GDK delivers them in an idle handler). Occasionally
4439 * this is useful to produce nicer scrolling behavior, for example.
4443 gdk_window_process_updates (GdkWindow *window,
4444 gboolean update_children)
4446 GdkWindowObject *private = (GdkWindowObject *)window;
4447 GdkWindowObject *impl_window;
4449 g_return_if_fail (GDK_IS_WINDOW (window));
4451 if (GDK_WINDOW_DESTROYED (window))
4454 /* Make sure the window lives during the expose callouts */
4455 g_object_ref (window);
4457 impl_window = gdk_window_get_impl_window (private);
4458 if ((impl_window->update_area ||
4459 impl_window->outstanding_moves) &&
4460 !impl_window->update_freeze_count &&
4461 !gdk_window_is_toplevel_frozen (window) &&
4463 /* Don't recurse into process_updates_internal, we'll
4464 * do the update later when idle instead. */
4465 impl_window->implicit_paint == NULL)
4467 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4468 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4471 if (update_children)
4473 /* process updates in reverse stacking order so composition or
4474 * painting over achieves the desired effect for offscreen windows
4476 GList *node, *children;
4478 children = g_list_copy (private->children);
4479 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4481 for (node = g_list_last (children); node; node = node->prev)
4483 gdk_window_process_updates (node->data, TRUE);
4484 g_object_unref (node->data);
4487 g_list_free (children);
4490 g_object_unref (window);
4494 gdk_window_invalidate_rect_full (GdkWindow *window,
4495 const GdkRectangle *rect,
4496 gboolean invalidate_children,
4499 GdkRectangle window_rect;
4500 cairo_region_t *region;
4501 GdkWindowObject *private = (GdkWindowObject *)window;
4503 g_return_if_fail (GDK_IS_WINDOW (window));
4505 if (GDK_WINDOW_DESTROYED (window))
4508 if (private->input_only || !private->viewable)
4515 gdk_drawable_get_size (GDK_DRAWABLE (window),
4517 &window_rect.height);
4518 rect = &window_rect;
4521 region = cairo_region_create_rectangle (rect);
4522 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4523 cairo_region_destroy (region);
4527 * gdk_window_invalidate_rect:
4528 * @window: a #GdkWindow
4529 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4531 * @invalidate_children: whether to also invalidate child windows
4533 * A convenience wrapper around gdk_window_invalidate_region() which
4534 * invalidates a rectangular region. See
4535 * gdk_window_invalidate_region() for details.
4538 gdk_window_invalidate_rect (GdkWindow *window,
4539 const GdkRectangle *rect,
4540 gboolean invalidate_children)
4542 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4546 draw_ugly_color (GdkWindow *window,
4547 const cairo_region_t *region)
4551 cr = gdk_cairo_create (window);
4552 /* Draw ugly color all over the newly-invalid region */
4553 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4554 gdk_cairo_region (cr, region);
4561 impl_window_add_update_area (GdkWindowObject *impl_window,
4562 cairo_region_t *region)
4564 if (impl_window->update_area)
4565 cairo_region_union (impl_window->update_area, region);
4568 gdk_window_add_update_window ((GdkWindow *)impl_window);
4569 impl_window->update_area = cairo_region_copy (region);
4570 gdk_window_schedule_update ((GdkWindow *)impl_window);
4574 /* clear_bg controls if the region will be cleared to
4575 * the background color/pixmap if the exposure mask is not
4576 * set for the window, whereas this might not otherwise be
4577 * done (unless necessary to emulate background settings).
4578 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4579 * need to clear the background, such as when exposing the area beneath a
4580 * hidden or moved window, but not when an app requests repaint or when the
4581 * windowing system exposes a newly visible area (because then the windowing
4582 * system has already cleared the area).
4585 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4586 const cairo_region_t *region,
4588 gboolean (*child_func) (GdkWindow *,
4592 GdkWindowObject *private = (GdkWindowObject *)window;
4593 GdkWindowObject *impl_window;
4594 cairo_region_t *visible_region;
4597 g_return_if_fail (GDK_IS_WINDOW (window));
4599 if (GDK_WINDOW_DESTROYED (window))
4602 if (private->input_only ||
4603 !private->viewable ||
4604 cairo_region_is_empty (region) ||
4605 private->window_type == GDK_WINDOW_ROOT)
4608 visible_region = gdk_drawable_get_visible_region (window);
4609 cairo_region_intersect (visible_region, region);
4611 tmp_list = private->children;
4614 GdkWindowObject *child = tmp_list->data;
4616 if (!child->input_only)
4618 cairo_region_t *child_region;
4619 GdkRectangle child_rect;
4621 child_rect.x = child->x;
4622 child_rect.y = child->y;
4623 child_rect.width = child->width;
4624 child_rect.height = child->height;
4625 child_region = cairo_region_create_rectangle (&child_rect);
4627 /* remove child area from the invalid area of the parent */
4628 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4629 !child->composited &&
4630 !gdk_window_is_offscreen (child))
4631 cairo_region_subtract (visible_region, child_region);
4633 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4635 cairo_region_t *tmp = cairo_region_copy (region);
4637 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4638 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4639 cairo_region_intersect (child_region, tmp);
4641 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4642 child_region, clear_bg, child_func, user_data);
4644 cairo_region_destroy (tmp);
4647 cairo_region_destroy (child_region);
4650 tmp_list = tmp_list->next;
4653 impl_window = gdk_window_get_impl_window (private);
4655 if (!cairo_region_is_empty (visible_region) ||
4656 /* Even if we're not exposing anything, make sure we process
4657 idles for windows with outstanding moves */
4658 (impl_window->outstanding_moves != NULL &&
4659 impl_window->update_area == NULL))
4662 draw_ugly_color (window, region);
4664 /* Convert to impl coords */
4665 cairo_region_translate (visible_region, private->abs_x, private->abs_y);
4667 /* Only invalidate area if app requested expose events or if
4668 we need to clear the area (by request or to emulate background
4669 clearing for non-native windows or native windows with no support
4670 for window backgrounds */
4671 if (private->event_mask & GDK_EXPOSURE_MASK ||
4672 clear_bg == CLEAR_BG_ALL ||
4673 clear_bg == CLEAR_BG_WINCLEARED)
4674 impl_window_add_update_area (impl_window, visible_region);
4677 cairo_region_destroy (visible_region);
4681 * gdk_window_invalidate_maybe_recurse:
4682 * @window: a #GdkWindow
4683 * @region: a #cairo_region_t
4684 * @child_func: function to use to decide if to recurse to a child,
4685 * %NULL means never recurse.
4686 * @user_data: data passed to @child_func
4688 * Adds @region to the update area for @window. The update area is the
4689 * region that needs to be redrawn, or "dirty region." The call
4690 * gdk_window_process_updates() sends one or more expose events to the
4691 * window, which together cover the entire update area. An
4692 * application would normally redraw the contents of @window in
4693 * response to those expose events.
4695 * GDK will call gdk_window_process_all_updates() on your behalf
4696 * whenever your program returns to the main loop and becomes idle, so
4697 * normally there's no need to do that manually, you just need to
4698 * invalidate regions that you know should be redrawn.
4700 * The @child_func parameter controls whether the region of
4701 * each child window that intersects @region will also be invalidated.
4702 * Only children for which @child_func returns TRUE will have the area
4706 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4707 const cairo_region_t *region,
4708 gboolean (*child_func) (GdkWindow *,
4712 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4713 child_func, user_data);
4717 true_predicate (GdkWindow *window,
4724 gdk_window_invalidate_region_full (GdkWindow *window,
4725 const cairo_region_t *region,
4726 gboolean invalidate_children,
4729 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4730 invalidate_children ?
4731 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4736 * gdk_window_invalidate_region:
4737 * @window: a #GdkWindow
4738 * @region: a #cairo_region_t
4739 * @invalidate_children: %TRUE to also invalidate child windows
4741 * Adds @region to the update area for @window. The update area is the
4742 * region that needs to be redrawn, or "dirty region." The call
4743 * gdk_window_process_updates() sends one or more expose events to the
4744 * window, which together cover the entire update area. An
4745 * application would normally redraw the contents of @window in
4746 * response to those expose events.
4748 * GDK will call gdk_window_process_all_updates() on your behalf
4749 * whenever your program returns to the main loop and becomes idle, so
4750 * normally there's no need to do that manually, you just need to
4751 * invalidate regions that you know should be redrawn.
4753 * The @invalidate_children parameter controls whether the region of
4754 * each child window that intersects @region will also be invalidated.
4755 * If %FALSE, then the update area for child windows will remain
4756 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4757 * fine grained control over which children are invalidated.
4760 gdk_window_invalidate_region (GdkWindow *window,
4761 const cairo_region_t *region,
4762 gboolean invalidate_children)
4764 gdk_window_invalidate_maybe_recurse (window, region,
4765 invalidate_children ?
4766 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4771 * _gdk_window_invalidate_for_expose:
4772 * @window: a #GdkWindow
4773 * @region: a #cairo_region_t
4775 * Adds @region to the update area for @window. The update area is the
4776 * region that needs to be redrawn, or "dirty region." The call
4777 * gdk_window_process_updates() sends one or more expose events to the
4778 * window, which together cover the entire update area. An
4779 * application would normally redraw the contents of @window in
4780 * response to those expose events.
4782 * GDK will call gdk_window_process_all_updates() on your behalf
4783 * whenever your program returns to the main loop and becomes idle, so
4784 * normally there's no need to do that manually, you just need to
4785 * invalidate regions that you know should be redrawn.
4787 * This version of invalidation is used when you recieve expose events
4788 * from the native window system. It exposes the native window, plus
4789 * any non-native child windows (but not native child windows, as those would
4790 * have gotten their own expose events).
4793 _gdk_window_invalidate_for_expose (GdkWindow *window,
4794 cairo_region_t *region)
4796 GdkWindowObject *private = (GdkWindowObject *) window;
4797 GdkWindowRegionMove *move;
4798 cairo_region_t *move_region;
4801 /* Any invalidations comming from the windowing system will
4802 be in areas that may be moved by outstanding moves,
4803 so we need to modify the expose region correspondingly,
4804 otherwise we would expose in the wrong place, as the
4805 outstanding moves will be copied before we draw the
4807 for (l = private->outstanding_moves; l != NULL; l = l->next)
4811 /* covert to move source region */
4812 move_region = cairo_region_copy (move->dest_region);
4813 cairo_region_translate (move_region, -move->dx, -move->dy);
4815 /* Move area of region that intersects with move source
4816 by dx, dy of the move*/
4817 cairo_region_intersect (move_region, region);
4818 cairo_region_subtract (region, move_region);
4819 cairo_region_translate (move_region, move->dx, move->dy);
4820 cairo_region_union (region, move_region);
4822 cairo_region_destroy (move_region);
4825 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4826 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4832 * gdk_window_get_update_area:
4833 * @window: a #GdkWindow
4835 * Transfers ownership of the update area from @window to the caller
4836 * of the function. That is, after calling this function, @window will
4837 * no longer have an invalid/dirty region; the update area is removed
4838 * from @window and handed to you. If a window has no update area,
4839 * gdk_window_get_update_area() returns %NULL. You are responsible for
4840 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4842 * Return value: the update area for @window
4845 gdk_window_get_update_area (GdkWindow *window)
4847 GdkWindowObject *private = (GdkWindowObject *)window;
4848 GdkWindowObject *impl_window;
4849 cairo_region_t *tmp_region;
4851 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4853 impl_window = gdk_window_get_impl_window (private);
4855 if (impl_window->update_area)
4857 tmp_region = cairo_region_copy (private->clip_region_with_children);
4858 /* Convert to impl coords */
4859 cairo_region_translate (tmp_region, private->abs_x, private->abs_y);
4860 cairo_region_intersect (tmp_region, impl_window->update_area);
4862 if (cairo_region_is_empty (tmp_region))
4864 cairo_region_destroy (tmp_region);
4869 cairo_region_subtract (impl_window->update_area, tmp_region);
4871 if (cairo_region_is_empty (impl_window->update_area) &&
4872 impl_window->outstanding_moves == NULL)
4874 cairo_region_destroy (impl_window->update_area);
4875 impl_window->update_area = NULL;
4877 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4880 /* Convert from impl coords */
4881 cairo_region_translate (tmp_region, -private->abs_x, -private->abs_y);
4891 * _gdk_window_clear_update_area:
4892 * @window: a #GdkWindow.
4894 * Internal function to clear the update area for a window. This
4895 * is called when the window is hidden or destroyed.
4898 _gdk_window_clear_update_area (GdkWindow *window)
4900 GdkWindowObject *private = (GdkWindowObject *)window;
4902 g_return_if_fail (GDK_IS_WINDOW (window));
4904 if (private->update_area)
4906 gdk_window_remove_update_window (window);
4908 cairo_region_destroy (private->update_area);
4909 private->update_area = NULL;
4914 * gdk_window_freeze_updates:
4915 * @window: a #GdkWindow
4917 * Temporarily freezes a window such that it won't receive expose
4918 * events. The window will begin receiving expose events again when
4919 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4920 * has been called more than once, gdk_window_thaw_updates() must be called
4921 * an equal number of times to begin processing exposes.
4924 gdk_window_freeze_updates (GdkWindow *window)
4926 GdkWindowObject *private = (GdkWindowObject *)window;
4927 GdkWindowObject *impl_window;
4929 g_return_if_fail (GDK_IS_WINDOW (window));
4931 impl_window = gdk_window_get_impl_window (private);
4932 impl_window->update_freeze_count++;
4936 * gdk_window_thaw_updates:
4937 * @window: a #GdkWindow
4939 * Thaws a window frozen with gdk_window_freeze_updates().
4942 gdk_window_thaw_updates (GdkWindow *window)
4944 GdkWindowObject *private = (GdkWindowObject *)window;
4945 GdkWindowObject *impl_window;
4947 g_return_if_fail (GDK_IS_WINDOW (window));
4949 impl_window = gdk_window_get_impl_window (private);
4951 g_return_if_fail (impl_window->update_freeze_count > 0);
4953 if (--impl_window->update_freeze_count == 0)
4954 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4958 * gdk_window_freeze_toplevel_updates_libgtk_only:
4959 * @window: a #GdkWindow
4961 * Temporarily freezes a window and all its descendants such that it won't
4962 * receive expose events. The window will begin receiving expose events
4963 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4964 * gdk_window_freeze_toplevel_updates_libgtk_only()
4965 * has been called more than once,
4966 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4967 * an equal number of times to begin processing exposes.
4969 * This function is not part of the GDK public API and is only
4973 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4975 GdkWindowObject *private = (GdkWindowObject *)window;
4977 g_return_if_fail (GDK_IS_WINDOW (window));
4978 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4980 private->update_and_descendants_freeze_count++;
4984 * gdk_window_thaw_toplevel_updates_libgtk_only:
4985 * @window: a #GdkWindow
4987 * Thaws a window frozen with
4988 * gdk_window_freeze_toplevel_updates_libgtk_only().
4990 * This function is not part of the GDK public API and is only
4994 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4996 GdkWindowObject *private = (GdkWindowObject *)window;
4998 g_return_if_fail (GDK_IS_WINDOW (window));
4999 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
5000 g_return_if_fail (private->update_and_descendants_freeze_count > 0);
5002 private->update_and_descendants_freeze_count--;
5004 gdk_window_schedule_update (window);
5008 * gdk_window_set_debug_updates:
5009 * @setting: %TRUE to turn on update debugging
5011 * With update debugging enabled, calls to
5012 * gdk_window_invalidate_region() clear the invalidated region of the
5013 * screen to a noticeable color, and GDK pauses for a short time
5014 * before sending exposes to windows during
5015 * gdk_window_process_updates(). The net effect is that you can see
5016 * the invalid region for each window and watch redraws as they
5017 * occur. This allows you to diagnose inefficiencies in your application.
5019 * In essence, because the GDK rendering model prevents all flicker,
5020 * if you are redrawing the same region 400 times you may never
5021 * notice, aside from noticing a speed problem. Enabling update
5022 * debugging causes GTK to flicker slowly and noticeably, so you can
5023 * see exactly what's being redrawn when, in what order.
5025 * The --gtk-debug=updates command line option passed to GTK+ programs
5026 * enables this debug option at application startup time. That's
5027 * usually more useful than calling gdk_window_set_debug_updates()
5028 * yourself, though you might want to use this function to enable
5029 * updates sometime after application startup time.
5033 gdk_window_set_debug_updates (gboolean setting)
5035 debug_updates = setting;
5039 * gdk_window_constrain_size:
5040 * @geometry: a #GdkGeometry structure
5041 * @flags: a mask indicating what portions of @geometry are set
5042 * @width: desired width of window
5043 * @height: desired height of the window
5044 * @new_width: location to store resulting width
5045 * @new_height: location to store resulting height
5047 * Constrains a desired width and height according to a
5048 * set of geometry hints (such as minimum and maximum size).
5051 gdk_window_constrain_size (GdkGeometry *geometry,
5058 /* This routine is partially borrowed from fvwm.
5060 * Copyright 1993, Robert Nation
5061 * You may use this code for any purpose, as long as the original
5062 * copyright remains in the source code and all documentation
5064 * which in turn borrows parts of the algorithm from uwm
5067 gint min_height = 0;
5068 gint base_width = 0;
5069 gint base_height = 0;
5072 gint max_width = G_MAXINT;
5073 gint max_height = G_MAXINT;
5075 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
5077 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
5079 base_width = geometry->base_width;
5080 base_height = geometry->base_height;
5081 min_width = geometry->min_width;
5082 min_height = geometry->min_height;
5084 else if (flags & GDK_HINT_BASE_SIZE)
5086 base_width = geometry->base_width;
5087 base_height = geometry->base_height;
5088 min_width = geometry->base_width;
5089 min_height = geometry->base_height;
5091 else if (flags & GDK_HINT_MIN_SIZE)
5093 base_width = geometry->min_width;
5094 base_height = geometry->min_height;
5095 min_width = geometry->min_width;
5096 min_height = geometry->min_height;
5099 if (flags & GDK_HINT_MAX_SIZE)
5101 max_width = geometry->max_width ;
5102 max_height = geometry->max_height;
5105 if (flags & GDK_HINT_RESIZE_INC)
5107 xinc = MAX (xinc, geometry->width_inc);
5108 yinc = MAX (yinc, geometry->height_inc);
5111 /* clamp width and height to min and max values
5113 width = CLAMP (width, min_width, max_width);
5114 height = CLAMP (height, min_height, max_height);
5116 /* shrink to base + N * inc
5118 width = base_width + FLOOR (width - base_width, xinc);
5119 height = base_height + FLOOR (height - base_height, yinc);
5121 /* constrain aspect ratio, according to:
5124 * min_aspect <= -------- <= max_aspect
5128 if (flags & GDK_HINT_ASPECT &&
5129 geometry->min_aspect > 0 &&
5130 geometry->max_aspect > 0)
5134 if (geometry->min_aspect * height > width)
5136 delta = FLOOR (height - width / geometry->min_aspect, yinc);
5137 if (height - delta >= min_height)
5141 delta = FLOOR (height * geometry->min_aspect - width, xinc);
5142 if (width + delta <= max_width)
5147 if (geometry->max_aspect * height < width)
5149 delta = FLOOR (width - height * geometry->max_aspect, xinc);
5150 if (width - delta >= min_width)
5154 delta = FLOOR (width / geometry->max_aspect - height, yinc);
5155 if (height + delta <= max_height)
5164 *new_height = height;
5168 * gdk_window_get_pointer:
5169 * @window: a #GdkWindow
5170 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
5171 * return the X coordinate
5172 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
5173 * return the Y coordinate
5174 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
5177 * Obtains the current pointer position and modifier state.
5178 * The position is given in coordinates relative to the upper left
5179 * corner of @window.
5181 * Return value: (transfer none): the window containing the pointer (as with
5182 * gdk_window_at_pointer()), or %NULL if the window containing the
5183 * pointer isn't known to GDK
5185 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
5188 gdk_window_get_pointer (GdkWindow *window,
5191 GdkModifierType *mask)
5193 GdkDisplay *display;
5195 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5197 display = gdk_drawable_get_display (window);
5199 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
5203 * gdk_window_get_device_position:
5204 * @window: a #GdkWindow.
5205 * @device: #GdkDevice to query to.
5206 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
5207 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
5208 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
5210 * Obtains the current device position and modifier state.
5211 * The position is given in coordinates relative to the upper left
5212 * corner of @window.
5214 * Return value: (transfer none): The window underneath @device (as with
5215 * gdk_display_get_window_at_device_position()), or %NULL if the
5216 * window is not known to GDK.
5221 gdk_window_get_device_position (GdkWindow *window,
5225 GdkModifierType *mask)
5227 GdkDisplay *display;
5229 GdkModifierType tmp_mask;
5232 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5233 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
5235 display = gdk_drawable_get_display (window);
5236 child = display->device_hooks->window_get_device_position (display, device, window,
5237 &tmp_x, &tmp_y, &tmp_mask);
5246 _gdk_display_enable_motion_hints (display, device);
5252 * gdk_window_at_pointer:
5253 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
5254 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
5256 * Obtains the window underneath the mouse pointer, returning the
5257 * location of that window in @win_x, @win_y. Returns %NULL if the
5258 * window under the mouse pointer is not known to GDK (if the window
5259 * belongs to another application and a #GdkWindow hasn't been created
5260 * for it with gdk_window_foreign_new())
5262 * NOTE: For multihead-aware widgets or applications use
5263 * gdk_display_get_window_at_pointer() instead.
5265 * Return value: (transfer none): window under the mouse pointer
5267 * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
5270 gdk_window_at_pointer (gint *win_x,
5273 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
5277 * gdk_get_default_root_window:
5279 * Obtains the root window (parent all other windows are inside)
5280 * for the default display and screen.
5282 * Return value: the default root window
5285 gdk_get_default_root_window (void)
5287 return gdk_screen_get_root_window (gdk_screen_get_default ());
5291 * gdk_window_foreign_new:
5292 * @anid: a native window handle.
5294 * Wraps a native window for the default display in a #GdkWindow.
5295 * This may fail if the window has been destroyed.
5297 * For example in the X backend, a native window handle is an Xlib
5300 * Return value: the newly-created #GdkWindow wrapper for the
5301 * native window or %NULL if the window has been destroyed.
5304 gdk_window_foreign_new (GdkNativeWindow anid)
5306 return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
5310 get_all_native_children (GdkWindowObject *private,
5313 GdkWindowObject *child;
5316 for (l = private->children; l != NULL; l = l->next)
5320 if (gdk_window_has_impl (child))
5321 *native = g_list_prepend (*native, child);
5323 get_all_native_children (child, native);
5329 gdk_window_raise_internal (GdkWindow *window)
5331 GdkWindowObject *private = (GdkWindowObject *)window;
5332 GdkWindowObject *parent = private->parent;
5333 GdkWindowObject *above;
5334 GList *native_children;
5336 GdkWindowImplIface *impl_iface;
5340 parent->children = g_list_remove (parent->children, window);
5341 parent->children = g_list_prepend (parent->children, window);
5344 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5345 /* Just do native raise for toplevels */
5346 if (gdk_window_is_toplevel (private) ||
5347 /* The restack_under codepath should work correctly even if the parent
5348 is native, but it relies on the order of ->children to be correct,
5349 and some apps like SWT reorder the x windows without gdks knowledge,
5350 so we use raise directly in order to make these behave as before
5351 when using native windows */
5352 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5354 impl_iface->raise (window);
5356 else if (gdk_window_has_impl (private))
5358 above = find_native_sibling_above (parent, private);
5361 listhead.data = window;
5362 listhead.next = NULL;
5363 listhead.prev = NULL;
5364 impl_iface->restack_under ((GdkWindow *)above,
5368 impl_iface->raise (window);
5372 native_children = NULL;
5373 get_all_native_children (private, &native_children);
5374 if (native_children != NULL)
5376 above = find_native_sibling_above (parent, private);
5379 impl_iface->restack_under ((GdkWindow *)above,
5383 /* Right order, since native_children is bottom-topmost first */
5384 for (l = native_children; l != NULL; l = l->next)
5385 impl_iface->raise (l->data);
5388 g_list_free (native_children);
5394 /* Returns TRUE If the native window was mapped or unmapped */
5396 set_viewable (GdkWindowObject *w,
5399 GdkWindowObject *child;
5400 GdkWindowImplIface *impl_iface;
5403 if (w->viewable == val)
5409 recompute_visible_regions (w, FALSE, FALSE);
5411 for (l = w->children; l != NULL; l = l->next)
5415 if (GDK_WINDOW_IS_MAPPED (child) &&
5416 child->window_type != GDK_WINDOW_FOREIGN)
5417 set_viewable (child, val);
5420 if (!_gdk_native_windows &&
5421 gdk_window_has_impl (w) &&
5422 w->window_type != GDK_WINDOW_FOREIGN &&
5423 !gdk_window_is_toplevel (w))
5425 /* For most native windows we show/hide them not when they are
5426 * mapped/unmapped, because that may not produce the correct results.
5427 * For instance, if a native window have a non-native parent which is
5428 * hidden, but its native parent is viewable then showing the window
5429 * would make it viewable to X but its not viewable wrt the non-native
5430 * hierarchy. In order to handle this we track the gdk side viewability
5431 * and only map really viewable windows.
5433 * There are two exceptions though:
5435 * For foreign windows we don't want ever change the mapped state
5436 * except when explicitly done via gdk_window_show/hide, as this may
5437 * cause problems for client owning the foreign window when its window
5438 * is suddenly mapped or unmapped.
5440 * For toplevel windows embedded in a foreign window (e.g. a plug)
5441 * we sometimes synthesize a map of a window, but the native
5442 * window is really shown by the embedder, so we don't want to
5443 * do the show ourselves. We can't really tell this case from the normal
5444 * toplevel show as such toplevels are seen by gdk as parents of the
5445 * root window, so we make an exception for all toplevels.
5447 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
5448 * like this, so we just always show/hide directly.
5451 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
5453 impl_iface->show ((GdkWindow *)w, FALSE);
5455 impl_iface->hide ((GdkWindow *)w);
5463 /* Returns TRUE If the native window was mapped or unmapped */
5465 _gdk_window_update_viewable (GdkWindow *window)
5467 GdkWindowObject *priv = (GdkWindowObject *)window;
5470 if (priv->window_type == GDK_WINDOW_FOREIGN ||
5471 priv->window_type == GDK_WINDOW_ROOT)
5473 else if (gdk_window_is_toplevel (priv) ||
5474 priv->parent->viewable)
5475 viewable = GDK_WINDOW_IS_MAPPED (priv);
5479 return set_viewable (priv, viewable);
5483 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5485 GdkWindowObject *private;
5486 GdkWindowImplIface *impl_iface;
5487 gboolean was_mapped, was_viewable;
5490 g_return_if_fail (GDK_IS_WINDOW (window));
5492 private = (GdkWindowObject *) window;
5493 if (private->destroyed)
5496 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5497 was_viewable = private->viewable;
5500 /* Keep children in (reverse) stacking order */
5501 gdk_window_raise_internal (window);
5503 if (gdk_window_has_impl (private))
5506 gdk_synthesize_window_state (window,
5507 GDK_WINDOW_STATE_WITHDRAWN,
5515 did_show = _gdk_window_update_viewable (window);
5517 /* If it was already viewable the backend show op won't be called, call it
5518 again to ensure things happen right if the mapped tracking was not right
5519 for e.g. a foreign window.
5520 Dunno if this is strictly needed but its what happened pre-csw.
5521 Also show if not done by gdk_window_update_viewable. */
5522 if (gdk_window_has_impl (private) && (was_viewable || !did_show))
5524 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5525 impl_iface->show ((GdkWindow *)private,
5526 !did_show ? was_mapped : TRUE);
5529 if (!was_mapped && !gdk_window_has_impl (private))
5531 if (private->event_mask & GDK_STRUCTURE_MASK)
5532 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5534 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5535 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5538 if (!was_mapped || raise)
5540 recompute_visible_regions (private, TRUE, FALSE);
5542 /* If any decendants became visible we need to send visibility notify */
5543 gdk_window_update_visibility_recursively (private, NULL);
5545 if (gdk_window_is_viewable (window))
5547 _gdk_synthesize_crossing_events_for_geometry_change (window);
5548 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5554 * gdk_window_show_unraised:
5555 * @window: a #GdkWindow
5557 * Shows a #GdkWindow onscreen, but does not modify its stacking
5558 * order. In contrast, gdk_window_show() will raise the window
5559 * to the top of the window stack.
5561 * On the X11 platform, in Xlib terms, this function calls
5562 * XMapWindow() (it also updates some internal GDK state, which means
5563 * that you can't really use XMapWindow() directly on a GDK window).
5566 gdk_window_show_unraised (GdkWindow *window)
5568 gdk_window_show_internal (window, FALSE);
5573 * @window: a #GdkWindow
5575 * Raises @window to the top of the Z-order (stacking order), so that
5576 * other windows with the same parent window appear below @window.
5577 * This is true whether or not the windows are visible.
5579 * If @window is a toplevel, the window manager may choose to deny the
5580 * request to move the window in the Z-order, gdk_window_raise() only
5581 * requests the restack, does not guarantee it.
5584 gdk_window_raise (GdkWindow *window)
5586 GdkWindowObject *private;
5587 cairo_region_t *old_region, *new_region;
5589 g_return_if_fail (GDK_IS_WINDOW (window));
5591 private = (GdkWindowObject *) window;
5592 if (private->destroyed)
5595 gdk_window_flush_if_exposing (window);
5598 if (gdk_window_is_viewable (window) &&
5599 !private->input_only)
5600 old_region = cairo_region_copy (private->clip_region);
5602 /* Keep children in (reverse) stacking order */
5603 gdk_window_raise_internal (window);
5605 recompute_visible_regions (private, TRUE, FALSE);
5609 new_region = cairo_region_copy (private->clip_region);
5611 cairo_region_subtract (new_region, old_region);
5612 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5614 cairo_region_destroy (old_region);
5615 cairo_region_destroy (new_region);
5620 gdk_window_lower_internal (GdkWindow *window)
5622 GdkWindowObject *private = (GdkWindowObject *)window;
5623 GdkWindowObject *parent = private->parent;
5624 GdkWindowImplIface *impl_iface;
5625 GdkWindowObject *above;
5626 GList *native_children;
5631 parent->children = g_list_remove (parent->children, window);
5632 parent->children = g_list_append (parent->children, window);
5635 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5636 /* Just do native lower for toplevels */
5637 if (gdk_window_is_toplevel (private) ||
5638 /* The restack_under codepath should work correctly even if the parent
5639 is native, but it relies on the order of ->children to be correct,
5640 and some apps like SWT reorder the x windows without gdks knowledge,
5641 so we use lower directly in order to make these behave as before
5642 when using native windows */
5643 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5645 impl_iface->lower (window);
5647 else if (gdk_window_has_impl (private))
5649 above = find_native_sibling_above (parent, private);
5652 listhead.data = window;
5653 listhead.next = NULL;
5654 listhead.prev = NULL;
5655 impl_iface->restack_under ((GdkWindow *)above, &listhead);
5658 impl_iface->raise (window);
5662 native_children = NULL;
5663 get_all_native_children (private, &native_children);
5664 if (native_children != NULL)
5666 above = find_native_sibling_above (parent, private);
5669 impl_iface->restack_under ((GdkWindow *)above,
5673 /* Right order, since native_children is bottom-topmost first */
5674 for (l = native_children; l != NULL; l = l->next)
5675 impl_iface->raise (l->data);
5678 g_list_free (native_children);
5685 gdk_window_invalidate_in_parent (GdkWindowObject *private)
5687 GdkRectangle r, child;
5689 if (gdk_window_is_toplevel (private))
5692 /* get the visible rectangle of the parent */
5694 r.width = private->parent->width;
5695 r.height = private->parent->height;
5697 child.x = private->x;
5698 child.y = private->y;
5699 child.width = private->width;
5700 child.height = private->height;
5701 gdk_rectangle_intersect (&r, &child, &r);
5703 gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
5709 * @window: a #GdkWindow
5711 * Lowers @window to the bottom of the Z-order (stacking order), so that
5712 * other windows with the same parent window appear above @window.
5713 * This is true whether or not the other windows are visible.
5715 * If @window is a toplevel, the window manager may choose to deny the
5716 * request to move the window in the Z-order, gdk_window_lower() only
5717 * requests the restack, does not guarantee it.
5719 * Note that gdk_window_show() raises the window again, so don't call this
5720 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5723 gdk_window_lower (GdkWindow *window)
5725 GdkWindowObject *private;
5727 g_return_if_fail (GDK_IS_WINDOW (window));
5729 private = (GdkWindowObject *) window;
5730 if (private->destroyed)
5733 gdk_window_flush_if_exposing (window);
5735 /* Keep children in (reverse) stacking order */
5736 gdk_window_lower_internal (window);
5738 recompute_visible_regions (private, TRUE, FALSE);
5740 _gdk_synthesize_crossing_events_for_geometry_change (window);
5741 gdk_window_invalidate_in_parent (private);
5745 * gdk_window_restack:
5746 * @window: a #GdkWindow
5747 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5750 * Changes the position of @window in the Z-order (stacking order), so that
5751 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5754 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5755 * lowers the window.
5757 * If @window is a toplevel, the window manager may choose to deny the
5758 * request to move the window in the Z-order, gdk_window_restack() only
5759 * requests the restack, does not guarantee it.
5764 gdk_window_restack (GdkWindow *window,
5768 GdkWindowObject *private;
5769 GdkWindowImplIface *impl_iface;
5770 GdkWindowObject *parent;
5771 GdkWindowObject *above_native;
5772 GList *sibling_link;
5773 GList *native_children;
5776 g_return_if_fail (GDK_IS_WINDOW (window));
5777 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5779 private = (GdkWindowObject *) window;
5780 if (private->destroyed)
5783 if (sibling == NULL)
5786 gdk_window_raise (window);
5788 gdk_window_lower (window);
5792 gdk_window_flush_if_exposing (window);
5794 if (gdk_window_is_toplevel (private))
5796 g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
5797 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5798 impl_iface->restack_toplevel (window, sibling, above);
5802 parent = private->parent;
5805 sibling_link = g_list_find (parent->children, sibling);
5806 g_return_if_fail (sibling_link != NULL);
5807 if (sibling_link == NULL)
5810 parent->children = g_list_remove (parent->children, window);
5812 parent->children = g_list_insert_before (parent->children,
5816 parent->children = g_list_insert_before (parent->children,
5820 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5821 if (gdk_window_has_impl (private))
5823 above_native = find_native_sibling_above (parent, private);
5826 listhead.data = window;
5827 listhead.next = NULL;
5828 listhead.prev = NULL;
5829 impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
5832 impl_iface->raise (window);
5836 native_children = NULL;
5837 get_all_native_children (private, &native_children);
5838 if (native_children != NULL)
5840 above_native = find_native_sibling_above (parent, private);
5842 impl_iface->restack_under ((GdkWindow *)above_native,
5846 /* Right order, since native_children is bottom-topmost first */
5847 for (l = native_children; l != NULL; l = l->next)
5848 impl_iface->raise (l->data);
5851 g_list_free (native_children);
5856 recompute_visible_regions (private, TRUE, FALSE);
5858 _gdk_synthesize_crossing_events_for_geometry_change (window);
5859 gdk_window_invalidate_in_parent (private);
5865 * @window: a #GdkWindow
5867 * Like gdk_window_show_unraised(), but also raises the window to the
5868 * top of the window stack (moves the window to the front of the
5871 * This function maps a window so it's visible onscreen. Its opposite
5872 * is gdk_window_hide().
5874 * When implementing a #GtkWidget, you should call this function on the widget's
5875 * #GdkWindow as part of the "map" method.
5878 gdk_window_show (GdkWindow *window)
5880 gdk_window_show_internal (window, TRUE);
5885 * @window: a #GdkWindow
5887 * For toplevel windows, withdraws them, so they will no longer be
5888 * known to the window manager; for all windows, unmaps them, so
5889 * they won't be displayed. Normally done automatically as
5890 * part of gtk_widget_hide().
5893 gdk_window_hide (GdkWindow *window)
5895 GdkWindowObject *private;
5896 GdkWindowImplIface *impl_iface;
5897 gboolean was_mapped, did_hide;
5899 g_return_if_fail (GDK_IS_WINDOW (window));
5901 private = (GdkWindowObject *) window;
5902 if (private->destroyed)
5905 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5907 if (gdk_window_has_impl (private))
5910 if (GDK_WINDOW_IS_MAPPED (window))
5911 gdk_synthesize_window_state (window,
5913 GDK_WINDOW_STATE_WITHDRAWN);
5915 else if (was_mapped)
5917 GdkDisplay *display;
5918 GdkDeviceManager *device_manager;
5921 /* May need to break grabs on children */
5922 display = gdk_drawable_get_display (window);
5923 device_manager = gdk_display_get_device_manager (display);
5925 /* Get all devices */
5926 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5927 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5928 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5930 for (d = devices; d; d = d->next)
5932 GdkDevice *device = d->data;
5934 if (_gdk_display_end_device_grab (display, device,
5935 _gdk_windowing_window_get_next_serial (display),
5938 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5941 private->state = GDK_WINDOW_STATE_WITHDRAWN;
5942 g_list_free (devices);
5945 did_hide = _gdk_window_update_viewable (window);
5947 /* Hide foreign window as those are not handled by update_viewable. */
5948 if (gdk_window_has_impl (private) && (!did_hide))
5950 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5951 impl_iface->hide (window);
5954 recompute_visible_regions (private, TRUE, FALSE);
5956 /* all decendants became non-visible, we need to send visibility notify */
5957 gdk_window_update_visibility_recursively (private, NULL);
5959 if (was_mapped && !gdk_window_has_impl (private))
5961 if (private->event_mask & GDK_STRUCTURE_MASK)
5962 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5964 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5965 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5967 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5970 /* Invalidate the rect */
5972 gdk_window_invalidate_in_parent (private);
5976 * gdk_window_withdraw:
5977 * @window: a toplevel #GdkWindow
5979 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5980 * This function is not really useful as gdk_window_hide() automatically
5981 * withdraws toplevel windows before hiding them.
5984 gdk_window_withdraw (GdkWindow *window)
5986 GdkWindowObject *private;
5987 GdkWindowImplIface *impl_iface;
5988 gboolean was_mapped;
5990 g_return_if_fail (GDK_IS_WINDOW (window));
5992 private = (GdkWindowObject *) window;
5993 if (private->destroyed)
5996 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5998 if (gdk_window_has_impl (private))
6000 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6001 impl_iface->withdraw (window);
6005 if (private->event_mask & GDK_STRUCTURE_MASK)
6006 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
6008 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
6009 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
6011 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
6014 recompute_visible_regions (private, TRUE, FALSE);
6019 * gdk_window_set_events:
6020 * @window: a #GdkWindow
6021 * @event_mask: event mask for @window
6023 * The event mask for a window determines which events will be reported
6024 * for that window from all master input devices. For example, an event mask
6025 * including #GDK_BUTTON_PRESS_MASK means the window should report button
6026 * press events. The event mask is the bitwise OR of values from the
6027 * #GdkEventMask enumeration.
6030 gdk_window_set_events (GdkWindow *window,
6031 GdkEventMask event_mask)
6033 GdkWindowObject *private;
6034 GdkWindowImplIface *impl_iface;
6035 GdkDisplay *display;
6037 g_return_if_fail (GDK_IS_WINDOW (window));
6039 private = (GdkWindowObject *) window;
6040 if (private->destroyed)
6043 /* If motion hint is disabled, enable motion events again */
6044 display = gdk_drawable_get_display (window);
6045 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
6046 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
6048 GList *devices = private->devices_inside;
6052 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
6053 devices = devices->next;
6057 private->event_mask = event_mask;
6059 if (gdk_window_has_impl (private))
6061 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6062 impl_iface->set_events (window,
6063 get_native_event_mask (private));
6069 * gdk_window_get_events:
6070 * @window: a #GdkWindow
6072 * Gets the event mask for @window for all master input devices. See
6073 * gdk_window_set_events().
6075 * Return value: event mask for @window
6078 gdk_window_get_events (GdkWindow *window)
6080 GdkWindowObject *private;
6082 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6084 private = (GdkWindowObject *) window;
6085 if (private->destroyed)
6088 return private->event_mask;
6092 * gdk_window_set_device_events:
6093 * @window: a #GdkWindow
6094 * @device: #GdkDevice to enable events for.
6095 * @event_mask: event mask for @window
6097 * Sets the event mask for a given device (Normally a floating device, not
6098 * attached to any visible pointer) to @window. For example, an event mask
6099 * including #GDK_BUTTON_PRESS_MASK means the window should report button
6100 * press events. The event mask is the bitwise OR of values from the
6101 * #GdkEventMask enumeration.
6106 gdk_window_set_device_events (GdkWindow *window,
6108 GdkEventMask event_mask)
6110 GdkEventMask device_mask;
6111 GdkWindowObject *private;
6112 GdkDisplay *display;
6115 g_return_if_fail (GDK_IS_WINDOW (window));
6116 g_return_if_fail (GDK_IS_DEVICE (device));
6118 if (GDK_WINDOW_DESTROYED (window))
6121 private = (GdkWindowObject *) window;
6123 /* If motion hint is disabled, enable motion events again */
6124 display = gdk_drawable_get_display (window);
6125 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
6126 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
6127 _gdk_display_enable_motion_hints (display, device);
6129 if (G_UNLIKELY (!private->device_events))
6130 private->device_events = g_hash_table_new (NULL, NULL);
6132 if (event_mask == 0)
6134 /* FIXME: unsetting events on a master device
6135 * would restore private->event_mask
6137 g_hash_table_remove (private->device_events, device);
6140 g_hash_table_insert (private->device_events, device,
6141 GINT_TO_POINTER (event_mask));
6143 if (_gdk_native_windows)
6146 native = gdk_window_get_toplevel (window);
6148 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
6150 native = gdk_offscreen_window_get_embedder (native);
6152 if (native == NULL ||
6153 (!_gdk_window_has_impl (native) &&
6154 !gdk_window_is_viewable (native)))
6157 native = gdk_window_get_toplevel (native);
6160 device_mask = get_native_device_event_mask (private, device);
6161 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
6165 * gdk_window_get_device_events:
6166 * @window: a #GdkWindow.
6167 * @device: a #GdkDevice.
6169 * Returns the event mask for @window corresponding to an specific device.
6171 * Returns: device event mask for @window
6176 gdk_window_get_device_events (GdkWindow *window,
6179 GdkWindowObject *private;
6182 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6183 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
6185 if (GDK_WINDOW_DESTROYED (window))
6188 private = (GdkWindowObject *) window;
6190 if (!private->device_events)
6193 mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
6195 /* FIXME: device could be controlled by private->event_mask */
6201 gdk_window_move_resize_toplevel (GdkWindow *window,
6208 GdkWindowObject *private;
6209 cairo_region_t *old_region, *new_region;
6210 GdkWindowImplIface *impl_iface;
6212 int old_x, old_y, old_abs_x, old_abs_y;
6216 private = (GdkWindowObject *) window;
6224 is_resize = (width != -1) || (height != -1);
6226 if (gdk_window_is_viewable (window) &&
6227 !private->input_only)
6230 old_region = cairo_region_copy (private->clip_region);
6233 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6234 impl_iface->move_resize (window, with_move, x, y, width, height);
6236 dx = private->x - old_x;
6237 dy = private->y - old_y;
6239 old_abs_x = private->abs_x;
6240 old_abs_y = private->abs_y;
6242 /* Avoid recomputing for pure toplevel moves, for performance reasons */
6244 recompute_visible_regions (private, TRUE, FALSE);
6248 new_region = cairo_region_copy (private->clip_region);
6250 /* This is the newly exposed area (due to any resize),
6251 * X will expose it, but lets do that without the
6254 cairo_region_subtract (new_region, old_region);
6255 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
6257 cairo_region_destroy (old_region);
6258 cairo_region_destroy (new_region);
6261 _gdk_synthesize_crossing_events_for_geometry_change (window);
6266 move_native_children (GdkWindowObject *private)
6269 GdkWindowObject *child;
6270 GdkWindowImplIface *impl_iface;
6272 for (l = private->children; l; l = l->next)
6276 if (child->impl != private->impl)
6278 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
6279 impl_iface->move_resize ((GdkWindow *)child, TRUE,
6281 child->width, child->height);
6284 move_native_children (child);
6289 collect_native_child_region_helper (GdkWindowObject *window,
6291 cairo_region_t **region,
6295 GdkWindowObject *child;
6296 cairo_region_t *tmp;
6299 for (l = window->children; l != NULL; l = l->next)
6303 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
6306 if (child->impl != impl)
6308 tmp = cairo_region_copy (child->clip_region);
6309 cairo_region_translate (tmp,
6310 x_offset + child->x,
6311 y_offset + child->y);
6312 if (*region == NULL)
6316 cairo_region_union (*region, tmp);
6317 cairo_region_destroy (tmp);
6321 collect_native_child_region_helper (child, impl, region,
6322 x_offset + child->x,
6323 y_offset + child->y);
6329 static cairo_region_t *
6330 collect_native_child_region (GdkWindowObject *window,
6331 gboolean include_this)
6333 cairo_region_t *region;
6335 if (include_this && gdk_window_has_impl (window) && window->viewable)
6336 return cairo_region_copy (window->clip_region);
6340 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6347 gdk_window_move_resize_internal (GdkWindow *window,
6354 GdkWindowObject *private;
6355 cairo_region_t *old_region, *new_region, *copy_area;
6356 cairo_region_t *old_native_child_region, *new_native_child_region;
6357 GdkWindowObject *impl_window;
6358 GdkWindowImplIface *impl_iface;
6360 int old_x, old_y, old_abs_x, old_abs_y;
6363 g_return_if_fail (GDK_IS_WINDOW (window));
6365 private = (GdkWindowObject *) window;
6366 if (private->destroyed)
6369 if (gdk_window_is_toplevel (private))
6371 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6375 /* Bail early if no change */
6376 if (private->width == width &&
6377 private->height == height &&
6383 gdk_window_flush_if_exposing (window);
6385 /* Handle child windows */
6390 impl_window = gdk_window_get_impl_window (private);
6395 old_native_child_region = NULL;
6396 if (gdk_window_is_viewable (window) &&
6397 !private->input_only)
6401 old_region = cairo_region_copy (private->clip_region);
6402 /* Adjust region to parent window coords */
6403 cairo_region_translate (old_region, private->x, private->y);
6405 old_native_child_region = collect_native_child_region (private, TRUE);
6406 if (old_native_child_region)
6408 /* Adjust region to parent window coords */
6409 cairo_region_translate (old_native_child_region, private->x, private->y);
6411 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6412 * source or destination for a delayed GdkWindowRegionMove. So, we need
6413 * to flush those here for the parent window and all overlapped subwindows
6414 * of it. And we need to do this before setting the new clips as those will be
6417 gdk_window_flush_recursive (private->parent);
6421 /* Set the new position and size */
6427 if (!(width < 0 && height < 0))
6431 private->width = width;
6434 private->height = height;
6437 dx = private->x - old_x;
6438 dy = private->y - old_y;
6440 old_abs_x = private->abs_x;
6441 old_abs_y = private->abs_y;
6443 recompute_visible_regions (private, TRUE, FALSE);
6445 new_native_child_region = NULL;
6446 if (old_native_child_region)
6448 new_native_child_region = collect_native_child_region (private, TRUE);
6449 /* Adjust region to parent window coords */
6450 cairo_region_translate (new_native_child_region, private->x, private->y);
6453 if (gdk_window_has_impl (private))
6455 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6457 /* Do the actual move after recomputing things, as this will have set the shape to
6458 the now correct one, thus avoiding copying regions that should not be copied. */
6459 impl_iface->move_resize (window, TRUE,
6460 private->x, private->y,
6461 private->width, private->height);
6463 else if (old_abs_x != private->abs_x ||
6464 old_abs_y != private->abs_y)
6465 move_native_children (private);
6469 new_region = cairo_region_copy (private->clip_region);
6470 /* Adjust region to parent window coords */
6471 cairo_region_translate (new_region, private->x, private->y);
6474 * Part of the data at the new location can be copied from the
6475 * old location, this area is the intersection of the old region
6476 * moved as the copy will move it and then intersected with
6480 * Everything in the old and new regions that is not copied must be
6481 * invalidated (including children) as this is newly exposed
6483 copy_area = cairo_region_copy (new_region);
6485 cairo_region_union (new_region, old_region);
6487 if (old_native_child_region)
6489 /* Don't copy from inside native children, as this is copied by
6490 * the native window move.
6492 cairo_region_subtract (old_region, old_native_child_region);
6494 cairo_region_translate (old_region, dx, dy);
6496 cairo_region_intersect (copy_area, old_region);
6498 if (new_native_child_region)
6500 /* Don't copy any bits that would cause a read from the moved
6501 native windows, as we can't read that data */
6502 cairo_region_translate (new_native_child_region, dx, dy);
6503 cairo_region_subtract (copy_area, new_native_child_region);
6504 cairo_region_translate (new_native_child_region, -dx, -dy);
6507 cairo_region_subtract (new_region, copy_area);
6509 /* Convert old region to impl coords */
6510 cairo_region_translate (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
6512 /* convert from parent coords to impl */
6513 cairo_region_translate (copy_area, private->abs_x - private->x, private->abs_y - private->y);
6515 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6517 /* Invalidate affected part in the parent window
6518 * (no higher window should be affected)
6519 * We also invalidate any children in that area, which could include
6520 * this window if it still overlaps that area.
6522 if (old_native_child_region)
6524 /* No need to expose the region that the native window move copies */
6525 cairo_region_translate (old_native_child_region, dx, dy);
6526 cairo_region_intersect (old_native_child_region, new_native_child_region);
6527 cairo_region_subtract (new_region, old_native_child_region);
6529 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
6531 cairo_region_destroy (old_region);
6532 cairo_region_destroy (new_region);
6535 if (old_native_child_region)
6537 cairo_region_destroy (old_native_child_region);
6538 cairo_region_destroy (new_native_child_region);
6541 _gdk_synthesize_crossing_events_for_geometry_change (window);
6548 * @window: a #GdkWindow
6549 * @x: X coordinate relative to window's parent
6550 * @y: Y coordinate relative to window's parent
6552 * Repositions a window relative to its parent window.
6553 * For toplevel windows, window managers may ignore or modify the move;
6554 * you should probably use gtk_window_move() on a #GtkWindow widget
6555 * anyway, instead of using GDK functions. For child windows,
6556 * the move will reliably succeed.
6558 * If you're also planning to resize the window, use gdk_window_move_resize()
6559 * to both move and resize simultaneously, for a nicer visual effect.
6562 gdk_window_move (GdkWindow *window,
6566 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6570 * gdk_window_resize:
6571 * @window: a #GdkWindow
6572 * @width: new width of the window
6573 * @height: new height of the window
6575 * Resizes @window; for toplevel windows, asks the window manager to resize
6576 * the window. The window manager may not allow the resize. When using GTK+,
6577 * use gtk_window_resize() instead of this low-level GDK function.
6579 * Windows may not be resized below 1x1.
6581 * If you're also planning to move the window, use gdk_window_move_resize()
6582 * to both move and resize simultaneously, for a nicer visual effect.
6585 gdk_window_resize (GdkWindow *window,
6589 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6594 * gdk_window_move_resize:
6595 * @window: a #GdkWindow
6596 * @x: new X position relative to window's parent
6597 * @y: new Y position relative to window's parent
6599 * @height: new height
6601 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6602 * except that both operations are performed at once, avoiding strange
6603 * visual effects. (i.e. the user may be able to see the window first
6604 * move, then resize, if you don't use gdk_window_move_resize().)
6607 gdk_window_move_resize (GdkWindow *window,
6613 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6618 * gdk_window_scroll:
6619 * @window: a #GdkWindow
6620 * @dx: Amount to scroll in the X direction
6621 * @dy: Amount to scroll in the Y direction
6623 * Scroll the contents of @window, both pixels and children, by the
6624 * given amount. @window itself does not move. Portions of the window
6625 * that the scroll operation brings in from offscreen areas are
6626 * invalidated. The invalidated region may be bigger than what would
6627 * strictly be necessary.
6629 * For X11, a minimum area will be invalidated if the window has no
6630 * subwindows, or if the edges of the window's parent do not extend
6631 * beyond the edges of the window. In other cases, a multi-step process
6632 * is used to scroll the window which may produce temporary visual
6633 * artifacts and unnecessary invalidations.
6636 gdk_window_scroll (GdkWindow *window,
6640 GdkWindowObject *private = (GdkWindowObject *) window;
6641 GdkWindowObject *impl_window;
6642 cairo_region_t *copy_area, *noncopy_area;
6643 cairo_region_t *old_native_child_region, *new_native_child_region;
6646 g_return_if_fail (GDK_IS_WINDOW (window));
6648 if (dx == 0 && dy == 0)
6651 if (private->destroyed)
6654 gdk_window_flush_if_exposing (window);
6656 old_native_child_region = collect_native_child_region (private, FALSE);
6657 if (old_native_child_region)
6659 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6660 * source or destination for a delayed GdkWindowRegionMove. So, we need
6661 * to flush those here for the window and all overlapped subwindows
6662 * of it. And we need to do this before setting the new clips as those will be
6665 gdk_window_flush_recursive (private);
6669 /* First move all child windows, without causing invalidation */
6671 tmp_list = private->children;
6674 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6675 GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
6677 /* Just update the positions, the bits will move with the copy */
6681 tmp_list = tmp_list->next;
6684 recompute_visible_regions (private, FALSE, TRUE);
6686 new_native_child_region = NULL;
6687 if (old_native_child_region)
6688 new_native_child_region = collect_native_child_region (private, FALSE);
6690 move_native_children (private);
6692 /* Then copy the actual bits of the window w/ child windows */
6694 impl_window = gdk_window_get_impl_window (private);
6696 /* Calculate the area that can be gotten by copying the old area */
6697 copy_area = cairo_region_copy (private->clip_region);
6698 if (old_native_child_region)
6700 /* Don't copy from inside native children, as this is copied by
6701 * the native window move.
6703 cairo_region_subtract (copy_area, old_native_child_region);
6705 /* Don't copy any bits that would cause a read from the moved
6706 native windows, as we can't read that data */
6707 cairo_region_subtract (copy_area, new_native_child_region);
6709 cairo_region_translate (copy_area, dx, dy);
6710 cairo_region_intersect (copy_area, private->clip_region);
6712 /* And the rest need to be invalidated */
6713 noncopy_area = cairo_region_copy (private->clip_region);
6714 cairo_region_subtract (noncopy_area, copy_area);
6716 /* convert from window coords to impl */
6717 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6719 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6721 /* Invalidate not copied regions */
6722 if (old_native_child_region)
6724 /* No need to expose the region that the native window move copies */
6725 cairo_region_translate (old_native_child_region, dx, dy);
6726 cairo_region_intersect (old_native_child_region, new_native_child_region);
6727 cairo_region_subtract (noncopy_area, old_native_child_region);
6729 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6731 cairo_region_destroy (noncopy_area);
6733 if (old_native_child_region)
6735 cairo_region_destroy (old_native_child_region);
6736 cairo_region_destroy (new_native_child_region);
6739 _gdk_synthesize_crossing_events_for_geometry_change (window);
6743 * gdk_window_move_region:
6744 * @window: a #GdkWindow
6745 * @region: The #cairo_region_t to move
6746 * @dx: Amount to move in the X direction
6747 * @dy: Amount to move in the Y direction
6749 * Move the part of @window indicated by @region by @dy pixels in the Y
6750 * direction and @dx pixels in the X direction. The portions of @region
6751 * that not covered by the new position of @region are invalidated.
6753 * Child windows are not moved.
6758 gdk_window_move_region (GdkWindow *window,
6759 const cairo_region_t *region,
6763 GdkWindowObject *private = (GdkWindowObject *) window;
6764 GdkWindowObject *impl_window;
6765 cairo_region_t *nocopy_area;
6766 cairo_region_t *copy_area;
6768 g_return_if_fail (GDK_IS_WINDOW (window));
6769 g_return_if_fail (region != NULL);
6771 if (dx == 0 && dy == 0)
6774 if (private->destroyed)
6777 impl_window = gdk_window_get_impl_window (private);
6779 /* compute source regions */
6780 copy_area = cairo_region_copy (region);
6781 cairo_region_intersect (copy_area, private->clip_region_with_children);
6783 /* compute destination regions */
6784 cairo_region_translate (copy_area, dx, dy);
6785 cairo_region_intersect (copy_area, private->clip_region_with_children);
6787 /* Invalidate parts of the region (source and dest) not covered
6789 nocopy_area = cairo_region_copy (region);
6790 cairo_region_translate (nocopy_area, dx, dy);
6791 cairo_region_union (nocopy_area, region);
6792 cairo_region_subtract (nocopy_area, copy_area);
6794 /* convert from window coords to impl */
6795 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6796 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6798 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6799 cairo_region_destroy (nocopy_area);
6803 * gdk_window_set_background:
6804 * @window: a #GdkWindow
6805 * @color: a #GdkColor
6807 * Sets the background color of @window. (However, when using GTK+,
6808 * set the background of a widget with gtk_widget_modify_bg() - if
6809 * you're an application - or gtk_style_set_background() - if you're
6810 * implementing a custom widget.)
6812 * See also gdk_window_set_background_pattern().
6815 gdk_window_set_background (GdkWindow *window,
6816 const GdkColor *color)
6818 cairo_pattern_t *pattern;
6820 g_return_if_fail (GDK_IS_WINDOW (window));
6822 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6823 color->green / 65535.,
6824 color->blue / 65535.);
6826 gdk_window_set_background_pattern (window, pattern);
6828 cairo_pattern_destroy (pattern);
6831 /* NB: This is more or less a hack now and about to go away. */
6833 gdk_window_set_back_pixmap (GdkWindow *window,
6835 gboolean parent_relative)
6837 cairo_pattern_t *pattern;
6839 g_return_if_fail (GDK_IS_WINDOW (window));
6840 g_return_if_fail (pixmap == NULL || !parent_relative);
6842 if (parent_relative || pixmap == NULL)
6846 static cairo_user_data_key_t key;
6847 cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (pixmap);
6848 pattern = cairo_pattern_create_for_surface (surface);
6849 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
6850 g_object_ref (pixmap);
6851 cairo_pattern_set_user_data (pattern, &key, pixmap, g_object_unref);
6854 gdk_window_set_background_pattern (window, pattern);
6857 cairo_pattern_destroy (pattern);
6861 * gdk_window_set_background_pattern:
6862 * @window: a #GdkWindow
6863 * @pattern: (allow-none): a pattern to use, or %NULL
6865 * Sets the background of @window.
6867 * A background of %NULL means that the window will inherit its
6868 * background form its parent window.
6870 * The windowing system will normally fill a window with its background
6871 * when the window is obscured then exposed, and when you call
6872 * gdk_window_clear().
6875 gdk_window_set_background_pattern (GdkWindow *window,
6876 cairo_pattern_t *pattern)
6878 GdkWindowObject *private;
6880 g_return_if_fail (GDK_IS_WINDOW (window));
6882 private = (GdkWindowObject *) window;
6885 cairo_pattern_reference (pattern);
6886 if (private->background)
6887 cairo_pattern_destroy (private->background);
6888 private->background = pattern;
6890 if (gdk_window_has_impl (private) &&
6891 !private->input_only)
6893 GdkWindowImplIface *impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6894 impl_iface->set_background (window, pattern);
6899 * gdk_window_get_background_pattern:
6902 * Gets the pattern used to clear the background on @window. If @window
6903 * does not have its own background and reuses the parent's, %NULL is
6904 * returned and you'll have to query it yourself.
6906 * Returns: The pattern to use for the background or %NULL to use the
6907 * parent's background.
6912 gdk_window_get_background_pattern (GdkWindow *window)
6914 GdkWindowObject *private = (GdkWindowObject *) window;
6916 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6918 return private->background;
6922 update_cursor_foreach (GdkDisplay *display,
6924 GdkPointerWindowInfo *pointer_info,
6927 GdkWindow *window = user_data;
6928 GdkWindowObject *private = (GdkWindowObject *) window;
6930 if (_gdk_native_windows ||
6931 private->window_type == GDK_WINDOW_ROOT ||
6932 private->window_type == GDK_WINDOW_FOREIGN)
6933 GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_device_cursor (window, device, private->cursor);
6934 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6935 update_cursor (display, device);
6939 * gdk_window_get_cursor:
6940 * @window: a #GdkWindow
6942 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6943 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6944 * there is no custom cursor set on the specified window, and it is
6945 * using the cursor for its parent window.
6947 * Return value: a #GdkCursor, or %NULL. The returned object is owned
6948 * by the #GdkWindow and should not be unreferenced directly. Use
6949 * gdk_window_set_cursor() to unset the cursor of the window
6954 gdk_window_get_cursor (GdkWindow *window)
6956 GdkWindowObject *private;
6958 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6960 private = (GdkWindowObject *) window;
6962 return private->cursor;
6966 * gdk_window_set_cursor:
6967 * @window: a #GdkWindow
6968 * @cursor: (allow-none): a cursor
6970 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6971 * or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor
6972 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6973 * to gdk_window_set_cursor() means that @window will use the cursor of its
6974 * parent window. Most windows should use this default.
6977 gdk_window_set_cursor (GdkWindow *window,
6980 GdkWindowObject *private;
6981 GdkDisplay *display;
6983 g_return_if_fail (GDK_IS_WINDOW (window));
6985 private = (GdkWindowObject *) window;
6986 display = gdk_drawable_get_display (window);
6988 if (private->cursor)
6990 gdk_cursor_unref (private->cursor);
6991 private->cursor = NULL;
6994 if (!GDK_WINDOW_DESTROYED (window))
6997 private->cursor = gdk_cursor_ref (cursor);
6999 _gdk_display_pointer_info_foreach (display,
7000 update_cursor_foreach,
7003 g_object_notify (G_OBJECT (window), "cursor");
7008 * gdk_window_get_device_cursor:
7009 * @window: a #GdkWindow.
7010 * @device: a #GdkDevice.
7012 * Retrieves a #GdkCursor pointer for the @device currently set on the
7013 * specified #GdkWindow, or %NULL. If the return value is %NULL then
7014 * there is no custom cursor set on the specified window, and it is
7015 * using the cursor for its parent window.
7017 * Returns: a #GdkCursor, or %NULL. The returned object is owned
7018 * by the #GdkWindow and should not be unreferenced directly. Use
7019 * gdk_window_set_cursor() to unset the cursor of the window
7024 gdk_window_get_device_cursor (GdkWindow *window,
7027 GdkWindowObject *private;
7029 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
7030 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
7032 private = (GdkWindowObject *) window;
7034 return g_hash_table_lookup (private->device_cursor, device);
7038 * gdk_window_set_device_cursor:
7039 * @window: a #Gdkwindow
7040 * @device: a #GdkDevice
7041 * @cursor: a #GdkCursor
7043 * Sets a specific #GdkCursor for a given device when it gets inside @window.
7044 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixmap() to create
7045 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
7046 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
7047 * @window will use the cursor of its parent window. Most windows should
7053 gdk_window_set_device_cursor (GdkWindow *window,
7057 GdkWindowObject *private;
7058 GdkDisplay *display;
7060 g_return_if_fail (GDK_IS_WINDOW (window));
7061 g_return_if_fail (GDK_IS_DEVICE (device));
7063 private = (GdkWindowObject *) window;
7064 display = gdk_drawable_get_display (window);
7067 g_hash_table_remove (private->device_cursor, device);
7069 g_hash_table_replace (private->device_cursor, device, gdk_cursor_ref (cursor));
7071 if (!GDK_WINDOW_DESTROYED (window))
7073 GdkPointerWindowInfo *pointer_info;
7075 pointer_info = _gdk_display_get_pointer_info (display, device);
7077 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
7078 update_cursor (display, device);
7083 * gdk_window_get_geometry:
7084 * @window: a #GdkWindow
7085 * @x: return location for X coordinate of window (relative to its parent)
7086 * @y: return location for Y coordinate of window (relative to its parent)
7087 * @width: return location for width of window
7088 * @height: return location for height of window
7089 * @depth: return location for bit depth of window
7091 * Any of the return location arguments to this function may be %NULL,
7092 * if you aren't interested in getting the value of that field.
7094 * The X and Y coordinates returned are relative to the parent window
7095 * of @window, which for toplevels usually means relative to the
7096 * window decorations (titlebar, etc.) rather than relative to the
7097 * root window (screen-size background window).
7099 * On the X11 platform, the geometry is obtained from the X server,
7100 * so reflects the latest position of @window; this may be out-of-sync
7101 * with the position of @window delivered in the most-recently-processed
7102 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
7103 * position from the most recent configure event.
7106 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
7107 * to call gdk_window_get_position() and gdk_drawable_get_size() instead,
7108 * because it avoids the roundtrip to the X server and because
7109 * gdk_drawable_get_size() supports the full 32-bit coordinate space,
7110 * whereas gdk_window_get_geometry() is restricted to the 16-bit
7111 * coordinates of X11.
7115 gdk_window_get_geometry (GdkWindow *window,
7122 GdkWindowObject *private, *parent;
7123 GdkWindowImplIface *impl_iface;
7127 GDK_NOTE (MULTIHEAD,
7128 g_message ("gdk_window_get_geometry(): Window needs "
7129 "to be non-NULL to be multi head safe"));
7130 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
7133 g_return_if_fail (GDK_IS_WINDOW (window));
7135 private = (GdkWindowObject *) window;
7137 if (!GDK_WINDOW_DESTROYED (window))
7139 if (gdk_window_has_impl (private))
7141 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7142 impl_iface->get_geometry (window, x, y,
7145 /* This reports the position wrt to the native parent, we need to convert
7146 it to be relative to the client side parent */
7147 parent = private->parent;
7148 if (parent && !gdk_window_has_impl (parent))
7151 *x -= parent->abs_x;
7153 *y -= parent->abs_y;
7163 *width = private->width;
7165 *height = private->height;
7167 *depth = private->depth;
7173 * gdk_window_get_origin:
7174 * @window: a #GdkWindow
7175 * @x: return location for X coordinate
7176 * @y: return location for Y coordinate
7178 * Obtains the position of a window in root window coordinates.
7179 * (Compare with gdk_window_get_position() and
7180 * gdk_window_get_geometry() which return the position of a window
7181 * relative to its parent window.)
7183 * Return value: not meaningful, ignore
7186 gdk_window_get_origin (GdkWindow *window,
7190 GdkWindowObject *private;
7191 GdkWindowImplIface *impl_iface;
7193 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7195 if (GDK_WINDOW_DESTROYED (window))
7204 private = (GdkWindowObject *) window;
7206 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7207 impl_iface->get_root_coords (window,
7216 * gdk_window_get_root_coords:
7217 * @window: a #GdkWindow
7218 * @x: X coordinate in window
7219 * @y: Y coordinate in window
7220 * @root_x: return location for X coordinate
7221 * @root_y: return location for Y coordinate
7223 * Obtains the position of a window position in root
7224 * window coordinates. This is similar to
7225 * gdk_window_get_origin() but allows you go pass
7226 * in any position in the window, not just the origin.
7231 gdk_window_get_root_coords (GdkWindow *window,
7237 GdkWindowObject *private;
7238 GdkWindowImplIface *impl_iface;
7240 g_return_if_fail (GDK_IS_WINDOW (window));
7242 private = (GdkWindowObject *) window;
7244 if (GDK_WINDOW_DESTROYED (window))
7253 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7254 impl_iface->get_root_coords (window,
7261 * gdk_window_coords_to_parent:
7262 * @window: a child window
7263 * @x: X coordinate in child's coordinate system
7264 * @y: Y coordinate in child's coordinate system
7265 * @parent_x: (out) (allow-none): return location for X coordinate
7266 * in parent's coordinate system, or %NULL
7267 * @parent_y: (out) (allow-none): return location for Y coordinate
7268 * in parent's coordinate system, or %NULL
7270 * Transforms window coordinates from a child window to its parent
7271 * window, where the parent window is the normal parent as returned by
7272 * gdk_window_get_parent() for normal windows, and the window's
7273 * embedder as returned by gdk_offscreen_window_get_embedder() for
7274 * offscreen windows.
7276 * For normal windows, calling this function is equivalent to adding
7277 * the return values of gdk_window_get_position() to the child coordinates.
7278 * For offscreen windows however (which can be arbitrarily transformed),
7279 * this function calls the GdkWindow::to-embedder: signal to translate
7282 * You should always use this function when writing generic code that
7283 * walks up a window hierarchy.
7285 * See also: gdk_window_coords_from_parent()
7290 gdk_window_coords_to_parent (GdkWindow *window,
7296 GdkWindowObject *obj;
7298 g_return_if_fail (GDK_IS_WINDOW (window));
7300 obj = (GdkWindowObject *) window;
7302 if (gdk_window_is_offscreen (obj))
7306 to_embedder (obj, x, y, &px, &py);
7317 *parent_x = x + obj->x;
7320 *parent_y = y + obj->y;
7325 * gdk_window_coords_from_parent:
7326 * @window: a child window
7327 * @parent_x: X coordinate in parent's coordinate system
7328 * @parent_y: Y coordinate in parent's coordinate system
7329 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7330 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7332 * Transforms window coordinates from a parent window to a child
7333 * window, where the parent window is the normal parent as returned by
7334 * gdk_window_get_parent() for normal windows, and the window's
7335 * embedder as returned by gdk_offscreen_window_get_embedder() for
7336 * offscreen windows.
7338 * For normal windows, calling this function is equivalent to subtracting
7339 * the return values of gdk_window_get_position() from the parent coordinates.
7340 * For offscreen windows however (which can be arbitrarily transformed),
7341 * this function calls the GdkWindow::from-embedder: signal to translate
7344 * You should always use this function when writing generic code that
7345 * walks down a window hierarchy.
7347 * See also: gdk_window_coords_to_parent()
7352 gdk_window_coords_from_parent (GdkWindow *window,
7358 GdkWindowObject *obj;
7360 g_return_if_fail (GDK_IS_WINDOW (window));
7362 obj = (GdkWindowObject *) window;
7364 if (gdk_window_is_offscreen (obj))
7368 from_embedder (obj, parent_x, parent_y, &cx, &cy);
7379 *x = parent_x - obj->x;
7382 *y = parent_y - obj->y;
7387 * gdk_window_shape_combine_region:
7388 * @window: a #GdkWindow
7389 * @shape_region: region of window to be non-transparent
7390 * @offset_x: X position of @shape_region in @window coordinates
7391 * @offset_y: Y position of @shape_region in @window coordinates
7393 * Makes pixels in @window outside @shape_region be transparent,
7394 * so that the window may be nonrectangular.
7396 * If @shape_region is %NULL, the shape will be unset, so the whole
7397 * window will be opaque again. @offset_x and @offset_y are ignored
7398 * if @shape_region is %NULL.
7400 * On the X11 platform, this uses an X server extension which is
7401 * widely available on most common platforms, but not available on
7402 * very old X servers, and occasionally the implementation will be
7403 * buggy. On servers without the shape extension, this function
7406 * This function works on both toplevel and child windows.
7409 gdk_window_shape_combine_region (GdkWindow *window,
7410 const cairo_region_t *shape_region,
7414 GdkWindowObject *private;
7415 cairo_region_t *old_region, *new_region, *diff;
7417 g_return_if_fail (GDK_IS_WINDOW (window));
7419 private = (GdkWindowObject *) window;
7421 if (GDK_WINDOW_DESTROYED (window))
7424 private->shaped = (shape_region != NULL);
7427 cairo_region_destroy (private->shape);
7430 if (GDK_WINDOW_IS_MAPPED (window))
7431 old_region = cairo_region_copy (private->clip_region);
7435 private->shape = cairo_region_copy (shape_region);
7436 cairo_region_translate (private->shape, offset_x, offset_y);
7439 private->shape = NULL;
7441 recompute_visible_regions (private, TRUE, FALSE);
7443 if (gdk_window_has_impl (private) &&
7444 !should_apply_clip_as_shape (private))
7445 apply_shape (private, private->shape);
7449 new_region = cairo_region_copy (private->clip_region);
7451 /* New area in the window, needs invalidation */
7452 diff = cairo_region_copy (new_region);
7453 cairo_region_subtract (diff, old_region);
7455 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7457 cairo_region_destroy (diff);
7459 if (!gdk_window_is_toplevel (private))
7461 /* New area in the non-root parent window, needs invalidation */
7462 diff = cairo_region_copy (old_region);
7463 cairo_region_subtract (diff, new_region);
7465 /* Adjust region to parent window coords */
7466 cairo_region_translate (diff, private->x, private->y);
7468 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
7470 cairo_region_destroy (diff);
7473 cairo_region_destroy (new_region);
7474 cairo_region_destroy (old_region);
7479 do_child_shapes (GdkWindow *window,
7482 GdkWindowObject *private;
7484 cairo_region_t *region;
7486 private = (GdkWindowObject *) window;
7490 r.width = private->width;
7491 r.height = private->height;
7493 region = cairo_region_create_rectangle (&r);
7494 remove_child_area (private, NULL, FALSE, region);
7496 if (merge && private->shape)
7497 cairo_region_subtract (region, private->shape);
7499 gdk_window_shape_combine_region (window, region, 0, 0);
7503 * gdk_window_set_child_shapes:
7504 * @window: a #GdkWindow
7506 * Sets the shape mask of @window to the union of shape masks
7507 * for all children of @window, ignoring the shape mask of @window
7508 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7509 * the shape mask of @window in the masks to be merged.
7512 gdk_window_set_child_shapes (GdkWindow *window)
7514 g_return_if_fail (GDK_IS_WINDOW (window));
7516 do_child_shapes (window, FALSE);
7520 * gdk_window_merge_child_shapes:
7521 * @window: a #GdkWindow
7523 * Merges the shape masks for any child windows into the
7524 * shape mask for @window. i.e. the union of all masks
7525 * for @window and its children will become the new mask
7526 * for @window. See gdk_window_shape_combine_region().
7528 * This function is distinct from gdk_window_set_child_shapes()
7529 * because it includes @window's shape mask in the set of shapes to
7533 gdk_window_merge_child_shapes (GdkWindow *window)
7535 g_return_if_fail (GDK_IS_WINDOW (window));
7537 do_child_shapes (window, TRUE);
7541 * gdk_window_input_shape_combine_region:
7542 * @window: a #GdkWindow
7543 * @shape_region: region of window to be non-transparent
7544 * @offset_x: X position of @shape_region in @window coordinates
7545 * @offset_y: Y position of @shape_region in @window coordinates
7547 * Like gdk_window_shape_combine_region(), but the shape applies
7548 * only to event handling. Mouse events which happen while
7549 * the pointer position corresponds to an unset bit in the
7550 * mask will be passed on the window below @window.
7552 * An input shape is typically used with RGBA windows.
7553 * The alpha channel of the window defines which pixels are
7554 * invisible and allows for nicely antialiased borders,
7555 * and the input shape controls where the window is
7558 * On the X11 platform, this requires version 1.1 of the
7561 * On the Win32 platform, this functionality is not present and the
7562 * function does nothing.
7567 gdk_window_input_shape_combine_region (GdkWindow *window,
7568 const cairo_region_t *shape_region,
7572 GdkWindowObject *private;
7573 GdkWindowImplIface *impl_iface;
7575 g_return_if_fail (GDK_IS_WINDOW (window));
7577 private = (GdkWindowObject *) window;
7579 if (GDK_WINDOW_DESTROYED (window))
7582 if (private->input_shape)
7583 cairo_region_destroy (private->input_shape);
7587 private->input_shape = cairo_region_copy (shape_region);
7588 cairo_region_translate (private->input_shape, offset_x, offset_y);
7591 private->input_shape = NULL;
7593 if (gdk_window_has_impl (private))
7595 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7596 impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
7599 /* Pointer may have e.g. moved outside window due to the input mask change */
7600 _gdk_synthesize_crossing_events_for_geometry_change (window);
7604 do_child_input_shapes (GdkWindow *window,
7607 GdkWindowObject *private;
7609 cairo_region_t *region;
7611 private = (GdkWindowObject *) window;
7615 r.width = private->width;
7616 r.height = private->height;
7618 region = cairo_region_create_rectangle (&r);
7619 remove_child_area (private, NULL, TRUE, region);
7621 if (merge && private->shape)
7622 cairo_region_subtract (region, private->shape);
7623 if (merge && private->input_shape)
7624 cairo_region_subtract (region, private->input_shape);
7626 gdk_window_input_shape_combine_region (window, region, 0, 0);
7631 * gdk_window_set_child_input_shapes:
7632 * @window: a #GdkWindow
7634 * Sets the input shape mask of @window to the union of input shape masks
7635 * for all children of @window, ignoring the input shape mask of @window
7636 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7637 * the input shape mask of @window in the masks to be merged.
7642 gdk_window_set_child_input_shapes (GdkWindow *window)
7644 g_return_if_fail (GDK_IS_WINDOW (window));
7646 do_child_input_shapes (window, FALSE);
7650 * gdk_window_merge_child_input_shapes:
7651 * @window: a #GdkWindow
7653 * Merges the input shape masks for any child windows into the
7654 * input shape mask for @window. i.e. the union of all input masks
7655 * for @window and its children will become the new input mask
7656 * for @window. See gdk_window_input_shape_combine_region().
7658 * This function is distinct from gdk_window_set_child_input_shapes()
7659 * because it includes @window's input shape mask in the set of
7660 * shapes to be merged.
7665 gdk_window_merge_child_input_shapes (GdkWindow *window)
7667 g_return_if_fail (GDK_IS_WINDOW (window));
7669 do_child_input_shapes (window, TRUE);
7674 * gdk_window_set_static_gravities:
7675 * @window: a #GdkWindow
7676 * @use_static: %TRUE to turn on static gravity
7678 * Set the bit gravity of the given window to static, and flag it so
7679 * all children get static subwindow gravity. This is used if you are
7680 * implementing scary features that involve deep knowledge of the
7681 * windowing system. Don't worry about it unless you have to.
7683 * Return value: %TRUE if the server supports static gravity
7686 gdk_window_set_static_gravities (GdkWindow *window,
7687 gboolean use_static)
7689 GdkWindowObject *private;
7690 GdkWindowImplIface *impl_iface;
7692 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7694 private = (GdkWindowObject *) window;
7696 if (gdk_window_has_impl (private))
7698 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7699 return impl_iface->set_static_gravities (window, use_static);
7706 * gdk_window_get_composited:
7707 * @window: a #GdkWindow
7709 * Determines whether @window is composited.
7711 * See gdk_window_set_composited().
7713 * Returns: %TRUE if the window is composited.
7718 gdk_window_get_composited (GdkWindow *window)
7720 GdkWindowObject *private;
7722 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7724 private = (GdkWindowObject *)window;
7726 return private->composited;
7730 * gdk_window_set_composited:
7731 * @window: a #GdkWindow
7732 * @composited: %TRUE to set the window as composited
7734 * Sets a #GdkWindow as composited, or unsets it. Composited
7735 * windows do not automatically have their contents drawn to
7736 * the screen. Drawing is redirected to an offscreen buffer
7737 * and an expose event is emitted on the parent of the composited
7738 * window. It is the responsibility of the parent's expose handler
7739 * to manually merge the off-screen content onto the screen in
7740 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7743 * It only makes sense for child windows to be composited; see
7744 * gdk_window_set_opacity() if you need translucent toplevel
7747 * An additional effect of this call is that the area of this
7748 * window is no longer clipped from regions marked for
7749 * invalidation on its parent. Draws done on the parent
7750 * window are also no longer clipped by the child.
7752 * This call is only supported on some systems (currently,
7753 * only X11 with new enough Xcomposite and Xdamage extensions).
7754 * You must call gdk_display_supports_composite() to check if
7755 * setting a window as composited is supported before
7756 * attempting to do so.
7761 gdk_window_set_composited (GdkWindow *window,
7762 gboolean composited)
7764 GdkWindowObject *private = (GdkWindowObject *)window;
7765 GdkDisplay *display;
7767 g_return_if_fail (GDK_IS_WINDOW (window));
7769 composited = composited != FALSE;
7771 if (private->composited == composited)
7775 gdk_window_ensure_native (window);
7777 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
7779 if (!gdk_display_supports_composite (display) && composited)
7781 g_warning ("gdk_window_set_composited called but "
7782 "compositing is not supported");
7786 _gdk_windowing_window_set_composited (window, composited);
7788 recompute_visible_regions (private, TRUE, FALSE);
7790 if (GDK_WINDOW_IS_MAPPED (window))
7791 gdk_window_invalidate_in_parent (private);
7793 private->composited = composited;
7797 * gdk_window_get_modal_hint:
7798 * @window: A toplevel #GdkWindow.
7800 * Determines whether or not the window manager is hinted that @window
7801 * has modal behaviour.
7803 * Return value: whether or not the window has the modal hint set.
7808 gdk_window_get_modal_hint (GdkWindow *window)
7810 GdkWindowObject *private;
7812 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7814 private = (GdkWindowObject*) window;
7816 return private->modal_hint;
7820 * gdk_window_get_accept_focus:
7821 * @window: a toplevel #GdkWindow.
7823 * Determines whether or not the desktop environment shuld be hinted that
7824 * the window does not want to receive input focus.
7826 * Return value: whether or not the window should receive input focus.
7831 gdk_window_get_accept_focus (GdkWindow *window)
7833 GdkWindowObject *private;
7835 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7837 private = (GdkWindowObject *)window;
7839 return private->accept_focus;
7843 * gdk_window_get_focus_on_map:
7844 * @window: a toplevel #GdkWindow.
7846 * Determines whether or not the desktop environment should be hinted that the
7847 * window does not want to receive input focus when it is mapped.
7849 * Return value: whether or not the window wants to receive input focus when
7855 gdk_window_get_focus_on_map (GdkWindow *window)
7857 GdkWindowObject *private;
7859 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7861 private = (GdkWindowObject *)window;
7863 return private->focus_on_map;
7867 * gdk_window_is_input_only:
7868 * @window: a toplevel #GdkWindow
7870 * Determines whether or not the window is an input only window.
7872 * Return value: %TRUE if @window is input only
7877 gdk_window_is_input_only (GdkWindow *window)
7879 GdkWindowObject *private;
7881 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7883 private = (GdkWindowObject *)window;
7885 return private->input_only;
7889 * gdk_window_is_shaped:
7890 * @window: a toplevel #GdkWindow
7892 * Determines whether or not the window is shaped.
7894 * Return value: %TRUE if @window is shaped
7899 gdk_window_is_shaped (GdkWindow *window)
7901 GdkWindowObject *private;
7903 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7905 private = (GdkWindowObject *)window;
7907 return private->shaped;
7911 window_get_size_rectangle (GdkWindow *window,
7914 GdkWindowObject *private = (GdkWindowObject *) window;
7916 rect->x = rect->y = 0;
7917 rect->width = private->width;
7918 rect->height = private->height;
7921 /* Calculates the real clipping region for a window, in window coordinates,
7922 * taking into account other windows, gc clip region and gc clip mask.
7925 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7926 GdkWindow *base_window,
7927 gboolean do_children,
7928 gint *base_x_offset,
7929 gint *base_y_offset)
7931 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
7932 GdkRectangle visible_rect;
7933 cairo_region_t *real_clip_region;
7934 gint x_offset, y_offset;
7935 GdkWindowObject *parentwin, *lastwin;
7942 if (!private->viewable || private->input_only)
7943 return cairo_region_create ();
7945 window_get_size_rectangle (window, &visible_rect);
7947 /* real_clip_region is in window coordinates */
7948 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7950 x_offset = y_offset = 0;
7954 parentwin = lastwin;
7956 parentwin = lastwin->parent;
7958 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7959 for (; parentwin != NULL &&
7960 (parentwin == private || lastwin != (GdkWindowObject*) base_window);
7961 lastwin = parentwin, parentwin = lastwin->parent)
7964 GdkRectangle real_clip_rect;
7966 if (parentwin != private)
7968 x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
7969 y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
7972 /* children is ordered in reverse stack order */
7973 for (cur = parentwin->children;
7974 cur && cur->data != lastwin;
7977 GdkWindow *child = cur->data;
7978 GdkWindowObject *child_private = (GdkWindowObject *)child;
7980 if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
7983 /* Ignore offscreen children, as they don't draw in their parent and
7984 * don't take part in the clipping */
7985 if (gdk_window_is_offscreen (child_private))
7988 window_get_size_rectangle (child, &visible_rect);
7990 /* Convert rect to "window" coords */
7991 visible_rect.x += child_private->x - x_offset;
7992 visible_rect.y += child_private->y - y_offset;
7994 /* This shortcut is really necessary for performance when there are a lot of windows */
7995 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7996 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7997 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7998 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7999 visible_rect.y + visible_rect.height <= real_clip_rect.y)
8002 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
8005 /* Clip to the parent */
8006 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
8007 /* Convert rect to "window" coords */
8008 visible_rect.x += - x_offset;
8009 visible_rect.y += - y_offset;
8011 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
8015 *base_x_offset = x_offset;
8017 *base_y_offset = y_offset;
8019 return real_clip_region;
8023 _gdk_window_add_damage (GdkWindow *toplevel,
8024 cairo_region_t *damaged_region)
8026 GdkDisplay *display;
8027 GdkEvent event = { 0, };
8028 event.expose.type = GDK_DAMAGE;
8029 event.expose.window = toplevel;
8030 event.expose.send_event = FALSE;
8031 event.expose.region = damaged_region;
8032 cairo_region_get_extents (event.expose.region, &event.expose.area);
8033 display = gdk_drawable_get_display (event.expose.window);
8034 _gdk_event_queue_append (display, gdk_event_copy (&event));
8037 /* Gets the toplevel for a window as used for events,
8038 i.e. including offscreen parents */
8039 static GdkWindowObject *
8040 get_event_parent (GdkWindowObject *window)
8042 if (gdk_window_is_offscreen (window))
8043 return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
8045 return window->parent;
8048 /* Gets the toplevel for a window as used for events,
8049 i.e. including offscreen parents going up to the native
8052 get_event_toplevel (GdkWindow *w)
8054 GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
8055 GdkWindowObject *parent;
8057 while ((parent = get_event_parent (private)) != NULL &&
8058 (parent->window_type != GDK_WINDOW_ROOT))
8061 return GDK_WINDOW (private);
8065 _gdk_window_event_parent_of (GdkWindow *parent,
8076 w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
8083 update_cursor (GdkDisplay *display,
8086 GdkWindowObject *cursor_window, *parent, *toplevel;
8087 GdkWindow *pointer_window;
8088 GdkWindowImplIface *impl_iface;
8089 GdkPointerWindowInfo *pointer_info;
8090 GdkDeviceGrabInfo *grab;
8093 pointer_info = _gdk_display_get_pointer_info (display, device);
8094 pointer_window = pointer_info->window_under_pointer;
8096 /* We ignore the serials here and just pick the last grab
8097 we've sent, as that would shortly be used anyway. */
8098 grab = _gdk_display_get_last_device_grab (display, device);
8101 /* the pointer is not in a descendant of the grab window */
8102 !_gdk_window_event_parent_of (grab->window, pointer_window))
8104 /* use the cursor from the grab window */
8105 cursor_window = (GdkWindowObject *) grab->window;
8109 /* otherwise use the cursor from the pointer window */
8110 cursor_window = (GdkWindowObject *) pointer_window;
8113 /* Find the first window with the cursor actually set, as
8114 the cursor is inherited from the parent */
8115 while (cursor_window->cursor == NULL &&
8116 (parent = get_event_parent (cursor_window)) != NULL &&
8117 parent->window_type != GDK_WINDOW_ROOT)
8118 cursor_window = parent;
8120 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
8123 cursor = cursor_window->cursor;
8125 /* Set all cursors on toplevel, otherwise its tricky to keep track of
8126 * which native window has what cursor set. */
8127 toplevel = (GdkWindowObject *) get_event_toplevel (pointer_window);
8128 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
8129 impl_iface->set_device_cursor ((GdkWindow *) toplevel, device, cursor);
8133 point_in_window (GdkWindowObject *window,
8138 x >= 0 && x < window->width &&
8139 y >= 0 && y < window->height &&
8140 (window->shape == NULL ||
8141 cairo_region_contains_point (window->shape,
8143 (window->input_shape == NULL ||
8144 cairo_region_contains_point (window->input_shape,
8149 convert_native_coords_to_toplevel (GdkWindow *window,
8152 gdouble *toplevel_x,
8153 gdouble *toplevel_y)
8155 GdkWindowObject *private = (GdkWindowObject *)window;
8161 while (!gdk_window_is_toplevel (private))
8165 private = private->parent;
8171 return (GdkWindow *)private;
8175 convert_toplevel_coords_to_window (GdkWindow *window,
8181 GdkWindowObject *private;
8182 GdkWindowObject *parent;
8184 GList *children, *l;
8186 private = GDK_WINDOW_OBJECT (window);
8192 while ((parent = get_event_parent (private)) != NULL &&
8193 (parent->window_type != GDK_WINDOW_ROOT))
8195 children = g_list_prepend (children, private);
8199 for (l = children; l != NULL; l = l->next)
8200 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
8202 g_list_free (children);
8208 static GdkWindowObject *
8209 pick_embedded_child (GdkWindowObject *window,
8213 GdkWindowObject *res;
8216 g_signal_emit (window,
8217 signals[PICK_EMBEDDED_CHILD], 0,
8224 _gdk_window_find_child_at (GdkWindow *window,
8228 GdkWindowObject *private, *sub;
8229 double child_x, child_y;
8232 private = (GdkWindowObject *)window;
8234 if (point_in_window (private, x, y))
8236 /* Children is ordered in reverse stack order, i.e. first is topmost */
8237 for (l = private->children; l != NULL; l = l->next)
8241 if (!GDK_WINDOW_IS_MAPPED (sub))
8244 gdk_window_coords_from_parent ((GdkWindow *)sub,
8246 &child_x, &child_y);
8247 if (point_in_window (sub, child_x, child_y))
8248 return (GdkWindow *)sub;
8251 if (private->num_offscreen_children > 0)
8253 sub = pick_embedded_child (private,
8256 return (GdkWindow *)sub;
8264 _gdk_window_find_descendant_at (GdkWindow *toplevel,
8270 GdkWindowObject *private, *sub;
8271 gdouble child_x, child_y;
8275 private = (GdkWindowObject *)toplevel;
8277 if (point_in_window (private, x, y))
8282 /* Children is ordered in reverse stack order, i.e. first is topmost */
8283 for (l = private->children; l != NULL; l = l->next)
8287 if (!GDK_WINDOW_IS_MAPPED (sub))
8290 gdk_window_coords_from_parent ((GdkWindow *)sub,
8292 &child_x, &child_y);
8293 if (point_in_window (sub, child_x, child_y))
8303 private->num_offscreen_children > 0)
8305 sub = pick_embedded_child (private,
8311 from_embedder (sub, x, y, &x, &y);
8319 /* Not in window at all */
8328 return (GdkWindow *)private;
8333 * @window: a toplevel #GdkWindow
8335 * Emits a short beep associated to @window in the appropriate
8336 * display, if supported. Otherwise, emits a short beep on
8337 * the display just as gdk_display_beep().
8342 gdk_window_beep (GdkWindow *window)
8344 GdkDisplay *display;
8345 GdkWindow *toplevel;
8347 g_return_if_fail (GDK_IS_WINDOW (window));
8349 if (GDK_WINDOW_DESTROYED (window))
8352 toplevel = get_event_toplevel (window);
8353 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
8355 if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
8356 _gdk_windowing_window_beep (toplevel);
8358 gdk_display_beep (display);
8362 * gdk_window_set_support_multidevice:
8363 * @window: a #GdkWindow.
8364 * @support_multidevice: %TRUE to enable multidevice support in @window.
8366 * This function will enable multidevice features in @window.
8368 * Multidevice aware windows will need to handle properly multiple,
8369 * per device enter/leave events, device grabs and grab ownerships.
8374 gdk_window_set_support_multidevice (GdkWindow *window,
8375 gboolean support_multidevice)
8377 GdkWindowObject *private = (GdkWindowObject *) window;
8379 g_return_if_fail (GDK_IS_WINDOW (window));
8381 if (GDK_WINDOW_DESTROYED (window))
8384 if (private->support_multidevice == support_multidevice)
8387 private->support_multidevice = support_multidevice;
8389 /* FIXME: What to do if called when some pointers are inside the window ? */
8393 * gdk_window_get_support_multidevice:
8394 * @window: a #GdkWindow.
8396 * Returns %TRUE if the window is aware of the existence of multiple
8399 * Returns: %TRUE if the window handles multidevice features.
8404 gdk_window_get_support_multidevice (GdkWindow *window)
8406 GdkWindowObject *private = (GdkWindowObject *) window;
8408 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8410 if (GDK_WINDOW_DESTROYED (window))
8413 return private->support_multidevice;
8416 static const guint type_masks[] = {
8417 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8418 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8419 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8420 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8421 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8422 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8423 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8424 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8425 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8426 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8427 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8428 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8429 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8430 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8431 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8432 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8433 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8434 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8435 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8436 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8437 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8438 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8439 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8440 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8441 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8442 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8443 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8444 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8445 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8446 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8447 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8448 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8449 0, /* GDK_WINDOW_STATE = 32 */
8450 0, /* GDK_SETTING = 33 */
8451 0, /* GDK_OWNER_CHANGE = 34 */
8452 0, /* GDK_GRAB_BROKEN = 35 */
8453 0, /* GDK_DAMAGE = 36 */
8455 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8457 /* send motion events if the right buttons are down */
8459 update_evmask_for_button_motion (guint evmask,
8460 GdkModifierType mask)
8462 if (evmask & GDK_BUTTON_MOTION_MASK &&
8463 mask & (GDK_BUTTON1_MASK |
8468 evmask |= GDK_POINTER_MOTION_MASK;
8470 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8471 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8472 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8473 evmask |= GDK_POINTER_MOTION_MASK;
8479 is_button_type (GdkEventType type)
8481 return type == GDK_BUTTON_PRESS ||
8482 type == GDK_2BUTTON_PRESS ||
8483 type == GDK_3BUTTON_PRESS ||
8484 type == GDK_BUTTON_RELEASE ||
8489 is_motion_type (GdkEventType type)
8491 return type == GDK_MOTION_NOTIFY ||
8492 type == GDK_ENTER_NOTIFY ||
8493 type == GDK_LEAVE_NOTIFY;
8496 static GdkWindowObject *
8497 find_common_ancestor (GdkWindowObject *win1,
8498 GdkWindowObject *win2)
8500 GdkWindowObject *tmp;
8501 GList *path1 = NULL, *path2 = NULL;
8502 GList *list1, *list2;
8505 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8507 path1 = g_list_prepend (path1, tmp);
8508 tmp = get_event_parent (tmp);
8512 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8514 path2 = g_list_prepend (path2, tmp);
8515 tmp = get_event_parent (tmp);
8521 while (list1 && list2 && (list1->data == list2->data))
8523 tmp = (GdkWindowObject *)list1->data;
8524 list1 = g_list_next (list1);
8525 list2 = g_list_next (list2);
8527 g_list_free (path1);
8528 g_list_free (path2);
8534 _gdk_make_event (GdkWindow *window,
8536 GdkEvent *event_in_queue,
8537 gboolean before_event)
8539 GdkEvent *event = gdk_event_new (type);
8541 GdkModifierType the_state;
8543 the_time = gdk_event_get_time (event_in_queue);
8544 gdk_event_get_state (event_in_queue, &the_state);
8546 event->any.window = g_object_ref (window);
8547 event->any.send_event = FALSE;
8548 if (event_in_queue && event_in_queue->any.send_event)
8549 event->any.send_event = TRUE;
8553 case GDK_MOTION_NOTIFY:
8554 event->motion.time = the_time;
8555 event->motion.axes = NULL;
8556 event->motion.state = the_state;
8559 case GDK_BUTTON_PRESS:
8560 case GDK_2BUTTON_PRESS:
8561 case GDK_3BUTTON_PRESS:
8562 case GDK_BUTTON_RELEASE:
8563 event->button.time = the_time;
8564 event->button.axes = NULL;
8565 event->button.state = the_state;
8569 event->scroll.time = the_time;
8570 event->scroll.state = the_state;
8574 case GDK_KEY_RELEASE:
8575 event->key.time = the_time;
8576 event->key.state = the_state;
8579 case GDK_ENTER_NOTIFY:
8580 case GDK_LEAVE_NOTIFY:
8581 event->crossing.time = the_time;
8582 event->crossing.state = the_state;
8585 case GDK_PROPERTY_NOTIFY:
8586 event->property.time = the_time;
8587 event->property.state = the_state;
8590 case GDK_SELECTION_CLEAR:
8591 case GDK_SELECTION_REQUEST:
8592 case GDK_SELECTION_NOTIFY:
8593 event->selection.time = the_time;
8596 case GDK_PROXIMITY_IN:
8597 case GDK_PROXIMITY_OUT:
8598 event->proximity.time = the_time;
8601 case GDK_DRAG_ENTER:
8602 case GDK_DRAG_LEAVE:
8603 case GDK_DRAG_MOTION:
8604 case GDK_DRAG_STATUS:
8605 case GDK_DROP_START:
8606 case GDK_DROP_FINISHED:
8607 event->dnd.time = the_time;
8610 case GDK_FOCUS_CHANGE:
8614 case GDK_CLIENT_EVENT:
8615 case GDK_VISIBILITY_NOTIFY:
8627 _gdk_event_queue_insert_before (gdk_drawable_get_display (window), event_in_queue, event);
8629 _gdk_event_queue_insert_after (gdk_drawable_get_display (window), event_in_queue, event);
8632 _gdk_event_queue_append (gdk_drawable_get_display (window), event);
8638 send_crossing_event (GdkDisplay *display,
8639 GdkWindowObject *toplevel,
8640 GdkWindowObject *window,
8642 GdkCrossingMode mode,
8643 GdkNotifyType notify_type,
8644 GdkWindow *subwindow,
8648 GdkModifierType mask,
8650 GdkEvent *event_in_queue,
8654 guint32 window_event_mask, type_event_mask;
8655 GdkDeviceGrabInfo *grab;
8656 gboolean block_event = FALSE;
8658 grab = _gdk_display_has_device_grab (display, device, serial);
8661 !grab->owner_events)
8663 /* !owner_event => only report events wrt grab window, ignore rest */
8664 if ((GdkWindow *)window != grab->window)
8666 window_event_mask = grab->event_mask;
8669 window_event_mask = window->event_mask;
8671 if (type == GDK_LEAVE_NOTIFY)
8673 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8674 window->devices_inside = g_list_remove (window->devices_inside, device);
8676 if (!window->support_multidevice && window->devices_inside)
8678 /* Block leave events unless it's the last pointer */
8684 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8686 if (!window->support_multidevice && window->devices_inside)
8688 /* Only emit enter events for the first device */
8692 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8693 device->mode != GDK_MODE_DISABLED &&
8694 !g_list_find (window->devices_inside, device))
8695 window->devices_inside = g_list_prepend (window->devices_inside, device);
8701 if (window_event_mask & type_event_mask)
8703 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8704 gdk_event_set_device (event, device);
8705 event->crossing.time = time_;
8706 event->crossing.subwindow = subwindow;
8708 g_object_ref (subwindow);
8709 convert_toplevel_coords_to_window ((GdkWindow *)window,
8710 toplevel_x, toplevel_y,
8711 &event->crossing.x, &event->crossing.y);
8712 event->crossing.x_root = toplevel_x + toplevel->x;
8713 event->crossing.y_root = toplevel_y + toplevel->y;
8714 event->crossing.mode = mode;
8715 event->crossing.detail = notify_type;
8716 event->crossing.focus = FALSE;
8717 event->crossing.state = mask;
8722 /* The coordinates are in the toplevel window that src/dest are in.
8723 * src and dest are always (if != NULL) in the same toplevel, as
8724 * we get a leave-notify and set the window_under_pointer to null
8725 * before crossing to another toplevel.
8728 _gdk_synthesize_crossing_events (GdkDisplay *display,
8732 GdkCrossingMode mode,
8735 GdkModifierType mask,
8737 GdkEvent *event_in_queue,
8739 gboolean non_linear)
8742 GdkWindowObject *win, *last, *next;
8746 GdkWindowObject *toplevel;
8747 GdkNotifyType notify_type;
8749 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8751 a = (GdkWindowObject *)src;
8752 b = (GdkWindowObject *)dest;
8754 return; /* No crossings generated between src and dest */
8756 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8758 if (a && gdk_window_get_device_events (src, device) == 0)
8761 if (b && gdk_window_get_device_events (dest, device) == 0)
8768 c = find_common_ancestor (a, b);
8770 non_linear |= (c != a) && (c != b);
8772 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8774 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
8776 /* Traverse up from a to (excluding) c sending leave events */
8778 notify_type = GDK_NOTIFY_NONLINEAR;
8780 notify_type = GDK_NOTIFY_INFERIOR;
8782 notify_type = GDK_NOTIFY_ANCESTOR;
8783 send_crossing_event (display, toplevel,
8784 a, GDK_LEAVE_NOTIFY,
8788 toplevel_x, toplevel_y,
8796 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8798 notify_type = GDK_NOTIFY_VIRTUAL;
8801 win = get_event_parent (a);
8802 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8804 send_crossing_event (display, toplevel,
8805 win, GDK_LEAVE_NOTIFY,
8810 toplevel_x, toplevel_y,
8816 win = get_event_parent (win);
8821 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8823 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
8825 /* Traverse down from c to b */
8829 win = get_event_parent (b);
8830 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8832 path = g_list_prepend (path, win);
8833 win = get_event_parent (win);
8837 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8839 notify_type = GDK_NOTIFY_VIRTUAL;
8844 win = (GdkWindowObject *)list->data;
8845 list = g_list_next (list);
8847 next = (GdkWindowObject *)list->data;
8851 send_crossing_event (display, toplevel,
8852 win, GDK_ENTER_NOTIFY,
8857 toplevel_x, toplevel_y,
8867 notify_type = GDK_NOTIFY_NONLINEAR;
8869 notify_type = GDK_NOTIFY_ANCESTOR;
8871 notify_type = GDK_NOTIFY_INFERIOR;
8873 send_crossing_event (display, toplevel,
8874 b, GDK_ENTER_NOTIFY,
8879 toplevel_x, toplevel_y,
8886 /* Returns the window inside the event window with the pointer in it
8887 * at the specified coordinates, or NULL if its not in any child of
8888 * the toplevel. It also takes into account !owner_events grabs.
8891 get_pointer_window (GdkDisplay *display,
8892 GdkWindow *event_window,
8898 GdkWindow *pointer_window;
8899 GdkDeviceGrabInfo *grab;
8900 GdkPointerWindowInfo *pointer_info;
8902 pointer_info = _gdk_display_get_pointer_info (display, device);
8904 if (event_window == pointer_info->toplevel_under_pointer)
8906 _gdk_window_find_descendant_at (event_window,
8907 toplevel_x, toplevel_y,
8910 pointer_window = NULL;
8912 grab = _gdk_display_has_device_grab (display, device, serial);
8914 !grab->owner_events &&
8915 pointer_window != grab->window)
8916 pointer_window = NULL;
8918 return pointer_window;
8922 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8926 GdkPointerWindowInfo *device_info;
8928 /* We don't track this if all native, and it can cause issues
8929 with the update_cursor call below */
8930 if (_gdk_native_windows)
8933 device_info = _gdk_display_get_pointer_info (display, device);
8935 if (device_info->window_under_pointer)
8936 g_object_unref (device_info->window_under_pointer);
8937 device_info->window_under_pointer = window;
8941 g_object_ref (window);
8942 update_cursor (display, device);
8945 _gdk_display_enable_motion_hints (display, device);
8950 * @window: the #GdkWindow which will own the grab (the grab window).
8951 * @owner_events: if %FALSE then all pointer events are reported with respect to
8952 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8953 * events for this application are reported as normal, but pointer events outside
8954 * this application are reported with respect to @window and only if selected by
8955 * @event_mask. In either mode, unreported events are discarded.
8956 * @event_mask: specifies the event mask, which is used in accordance with
8957 * @owner_events. Note that only pointer events (i.e. button and motion events)
8959 * @confine_to: If non-%NULL, the pointer will be confined to this
8960 * window during the grab. If the pointer is outside @confine_to, it will
8961 * automatically be moved to the closest edge of @confine_to and enter
8962 * and leave events will be generated as necessary.
8963 * @cursor: the cursor to display while the grab is active. If this is %NULL then
8964 * the normal cursors are used for @window and its descendants, and the cursor
8965 * for @window is used for all other windows.
8966 * @time_: the timestamp of the event which led to this pointer grab. This usually
8967 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8968 * the time isn't known.
8970 * Grabs the pointer (usually a mouse) so that all events are passed to this
8971 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8972 * the grab window becomes unviewable.
8973 * This overrides any previous pointer grab by this client.
8975 * Pointer grabs are used for operations which need complete control over mouse
8976 * events, even if the mouse leaves the application.
8977 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8978 * the #GtkHPaned and #GtkVPaned widgets, and for resizing columns in #GtkCList
8981 * Note that if the event mask of an X window has selected both button press and
8982 * button release events, then a button press event will cause an automatic
8983 * pointer grab until the button is released.
8984 * X does this automatically since most applications expect to receive button
8985 * press and release events in pairs.
8986 * It is equivalent to a pointer grab on the window with @owner_events set to
8989 * If you set up anything at the time you take the grab that needs to be cleaned
8990 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8991 * are emitted when the grab ends unvoluntarily.
8993 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8995 * Deprecated: 3.0: Use gdk_device_grab() instead.
8998 gdk_pointer_grab (GdkWindow * window,
8999 gboolean owner_events,
9000 GdkEventMask event_mask,
9001 GdkWindow * confine_to,
9006 GdkDisplay *display;
9007 GdkDeviceManager *device_manager;
9009 GdkGrabStatus res = 0;
9011 GList *devices, *dev;
9013 g_return_val_if_fail (window != NULL, 0);
9014 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
9015 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
9017 /* We need a native window for confine to to work, ensure we have one */
9020 if (!gdk_window_ensure_native (confine_to))
9022 g_warning ("Can't confine to grabbed window, not native");
9027 /* Non-viewable client side window => fail */
9028 if (!_gdk_window_has_impl (window) &&
9029 !gdk_window_is_viewable (window))
9030 return GDK_GRAB_NOT_VIEWABLE;
9032 if (_gdk_native_windows)
9035 native = gdk_window_get_toplevel (window);
9036 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
9038 native = gdk_offscreen_window_get_embedder (native);
9040 if (native == NULL ||
9041 (!_gdk_window_has_impl (native) &&
9042 !gdk_window_is_viewable (native)))
9043 return GDK_GRAB_NOT_VIEWABLE;
9045 native = gdk_window_get_toplevel (native);
9048 display = gdk_drawable_get_display (window);
9050 serial = _gdk_windowing_window_get_next_serial (display);
9051 device_manager = gdk_display_get_device_manager (display);
9052 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
9054 /* FIXME: Should this be generic to all backends? */
9055 /* FIXME: What happens with extended devices? */
9056 for (dev = devices; dev; dev = dev->next)
9060 if (device->source != GDK_SOURCE_MOUSE)
9063 res = _gdk_windowing_device_grab (device,
9067 get_native_grab_event_mask (event_mask),
9072 if (res == GDK_GRAB_SUCCESS)
9073 _gdk_display_add_device_grab (display,
9085 /* FIXME: handle errors when grabbing */
9087 g_list_free (devices);
9093 * gdk_keyboard_grab:
9094 * @window: the #GdkWindow which will own the grab (the grab window).
9095 * @owner_events: if %FALSE then all keyboard events are reported with respect to
9096 * @window. If %TRUE then keyboard events for this application are
9097 * reported as normal, but keyboard events outside this application
9098 * are reported with respect to @window. Both key press and key
9099 * release events are always reported, independant of the event mask
9100 * set by the application.
9101 * @time: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
9104 * Grabs the keyboard so that all events are passed to this
9105 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
9106 * This overrides any previous keyboard grab by this client.
9108 * If you set up anything at the time you take the grab that needs to be cleaned
9109 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
9110 * are emitted when the grab ends unvoluntarily.
9112 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
9114 * Deprecated: 3.0: Use gdk_device_grab() instead.
9117 gdk_keyboard_grab (GdkWindow *window,
9118 gboolean owner_events,
9122 GdkDisplay *display;
9123 GdkDeviceManager *device_manager;
9125 GdkGrabStatus res = 0;
9127 GList *devices, *dev;
9129 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
9131 /* Non-viewable client side window => fail */
9132 if (!_gdk_window_has_impl (window) &&
9133 !gdk_window_is_viewable (window))
9134 return GDK_GRAB_NOT_VIEWABLE;
9136 if (_gdk_native_windows)
9139 native = gdk_window_get_toplevel (window);
9141 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
9143 native = gdk_offscreen_window_get_embedder (native);
9145 if (native == NULL ||
9146 (!_gdk_window_has_impl (native) &&
9147 !gdk_window_is_viewable (native)))
9148 return GDK_GRAB_NOT_VIEWABLE;
9150 native = gdk_window_get_toplevel (native);
9153 display = gdk_drawable_get_display (window);
9155 serial = _gdk_windowing_window_get_next_serial (display);
9156 device_manager = gdk_display_get_device_manager (display);
9157 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
9159 /* FIXME: Should this be generic to all backends? */
9160 /* FIXME: What happens with extended devices? */
9161 for (dev = devices; dev; dev = dev->next)
9165 if (device->source != GDK_SOURCE_KEYBOARD)
9168 res = _gdk_windowing_device_grab (device,
9172 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
9177 if (res == GDK_GRAB_SUCCESS)
9178 _gdk_display_add_device_grab (display,
9189 /* FIXME: handle errors when grabbing */
9191 g_list_free (devices);
9197 * gdk_window_geometry_changed:
9198 * @window: an embedded offscreen #GdkWindow
9200 * This function informs GDK that the geometry of an embedded
9201 * offscreen window has changed. This is necessary for GDK to keep
9202 * track of which offscreen window the pointer is in.
9207 gdk_window_geometry_changed (GdkWindow *window)
9209 _gdk_synthesize_crossing_events_for_geometry_change (window);
9213 do_synthesize_crossing_event (gpointer data)
9215 GdkDisplay *display;
9216 GdkWindow *changed_toplevel;
9217 GdkWindowObject *changed_toplevel_priv;
9218 GHashTableIter iter;
9219 gpointer key, value;
9222 changed_toplevel = data;
9223 changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
9225 changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
9227 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9230 display = gdk_drawable_get_display (changed_toplevel);
9231 serial = _gdk_windowing_window_get_next_serial (display);
9232 g_hash_table_iter_init (&iter, display->pointers_info);
9234 while (g_hash_table_iter_next (&iter, &key, &value))
9236 GdkWindow *new_window_under_pointer;
9237 GdkPointerWindowInfo *pointer_info = value;
9238 GdkDevice *device = key;
9240 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9242 new_window_under_pointer =
9243 get_pointer_window (display, changed_toplevel,
9245 pointer_info->toplevel_x,
9246 pointer_info->toplevel_y,
9248 if (new_window_under_pointer != pointer_info->window_under_pointer)
9250 _gdk_synthesize_crossing_events (display,
9251 pointer_info->window_under_pointer,
9252 new_window_under_pointer,
9254 GDK_CROSSING_NORMAL,
9255 pointer_info->toplevel_x,
9256 pointer_info->toplevel_y,
9257 pointer_info->state,
9262 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9271 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9273 GdkDisplay *display;
9274 GdkWindow *toplevel;
9275 GdkWindowObject *toplevel_priv;
9277 if (_gdk_native_windows)
9278 return; /* We use the native crossing events if all native */
9280 display = gdk_drawable_get_display (changed_window);
9282 toplevel = get_event_toplevel (changed_window);
9283 toplevel_priv = (GdkWindowObject *) toplevel;
9285 if (!toplevel_priv->synthesize_crossing_event_queued)
9287 toplevel_priv->synthesize_crossing_event_queued = TRUE;
9289 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9290 do_synthesize_crossing_event,
9291 g_object_ref (toplevel),
9296 /* Don't use for crossing events */
9298 get_event_window (GdkDisplay *display,
9300 GdkWindow *pointer_window,
9302 GdkModifierType mask,
9307 GdkWindow *grab_window;
9309 GdkDeviceGrabInfo *grab;
9311 grab = _gdk_display_has_device_grab (display, device, serial);
9313 if (grab != NULL && !grab->owner_events)
9315 evmask = grab->event_mask;
9316 evmask = update_evmask_for_button_motion (evmask, mask);
9318 grab_window = grab->window;
9320 if (evmask & type_masks[type])
9323 *evmask_out = evmask;
9330 w = (GdkWindowObject *)pointer_window;
9333 evmask = w->event_mask;
9334 evmask = update_evmask_for_button_motion (evmask, mask);
9336 if (evmask & type_masks[type])
9339 *evmask_out = evmask;
9340 return (GdkWindow *)w;
9343 w = get_event_parent (w);
9349 evmask = grab->event_mask;
9350 evmask = update_evmask_for_button_motion (evmask, mask);
9352 if (evmask & type_masks[type])
9355 *evmask_out = evmask;
9356 return grab->window;
9366 proxy_pointer_event (GdkDisplay *display,
9367 GdkEvent *source_event,
9370 GdkWindow *toplevel_window, *event_window;
9371 GdkWindow *pointer_window;
9372 GdkPointerWindowInfo *pointer_info;
9376 gdouble toplevel_x, toplevel_y;
9378 gboolean non_linear;
9380 event_window = source_event->any.window;
9381 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9382 gdk_event_get_state (source_event, &state);
9383 time_ = gdk_event_get_time (source_event);
9384 device = gdk_event_get_device (source_event);
9385 pointer_info = _gdk_display_get_pointer_info (display, device);
9386 toplevel_window = convert_native_coords_to_toplevel (event_window,
9387 toplevel_x, toplevel_y,
9388 &toplevel_x, &toplevel_y);
9391 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9392 source_event->type == GDK_ENTER_NOTIFY) &&
9393 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9394 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9397 /* If we get crossing events with subwindow unexpectedly being NULL
9398 that means there is a native subwindow that gdk doesn't know about.
9399 We track these and forward them, with the correct virtual window
9401 This is important to get right, as metacity uses gdk for the frame
9402 windows, but gdk doesn't know about the client windows reparented
9404 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9405 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9406 (source_event->type == GDK_ENTER_NOTIFY &&
9407 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9408 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9409 source_event->crossing.subwindow == NULL)
9411 /* Left for an unknown (to gdk) subwindow */
9413 /* Send leave events from window under pointer to event window
9414 that will get the subwindow == NULL window */
9415 _gdk_synthesize_crossing_events (display,
9416 pointer_info->window_under_pointer,
9419 source_event->crossing.mode,
9420 toplevel_x, toplevel_y,
9426 /* Send subwindow == NULL event */
9427 send_crossing_event (display,
9428 (GdkWindowObject *)toplevel_window,
9429 (GdkWindowObject *)event_window,
9431 source_event->crossing.mode,
9432 source_event->crossing.detail,
9435 toplevel_x, toplevel_y,
9440 _gdk_display_set_window_under_pointer (display, device, NULL);
9444 pointer_window = get_pointer_window (display, toplevel_window, device,
9445 toplevel_x, toplevel_y, serial);
9447 if (((source_event->type == GDK_ENTER_NOTIFY &&
9448 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9449 (source_event->type == GDK_LEAVE_NOTIFY &&
9450 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9451 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9452 source_event->crossing.subwindow == NULL)
9454 /* Entered from an unknown (to gdk) subwindow */
9456 /* Send subwindow == NULL event */
9457 send_crossing_event (display,
9458 (GdkWindowObject *)toplevel_window,
9459 (GdkWindowObject *)event_window,
9461 source_event->crossing.mode,
9462 source_event->crossing.detail,
9465 toplevel_x, toplevel_y,
9470 /* Send enter events from event window to pointer_window */
9471 _gdk_synthesize_crossing_events (display,
9475 source_event->crossing.mode,
9476 toplevel_x, toplevel_y,
9479 serial, non_linear);
9480 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9484 if (pointer_info->window_under_pointer != pointer_window)
9486 /* Either a toplevel crossing notify that ended up inside a child window,
9487 or a motion notify that got into another child window */
9489 /* Different than last time, send crossing events */
9490 _gdk_synthesize_crossing_events (display,
9491 pointer_info->window_under_pointer,
9494 GDK_CROSSING_NORMAL,
9495 toplevel_x, toplevel_y,
9498 serial, non_linear);
9499 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9501 else if (source_event->type == GDK_MOTION_NOTIFY)
9503 GdkWindow *event_win;
9507 event_win = get_event_window (display,
9516 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9517 gdk_window_get_device_events (event_win, device) == 0)
9523 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9525 gulong *device_serial;
9527 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9529 if (!device_serial ||
9530 (*device_serial != 0 &&
9531 serial < *device_serial))
9532 event_win = NULL; /* Ignore event */
9536 *device_serial = G_MAXULONG;
9540 if (event_win && !display->ignore_core_events)
9542 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9543 event->motion.time = time_;
9544 convert_toplevel_coords_to_window (event_win,
9545 toplevel_x, toplevel_y,
9546 &event->motion.x, &event->motion.y);
9547 event->motion.x_root = source_event->motion.x_root;
9548 event->motion.y_root = source_event->motion.y_root;
9549 event->motion.state = state;
9550 event->motion.is_hint = is_hint;
9551 event->motion.device = source_event->motion.device;
9552 event->motion.axes = g_memdup (source_event->motion.axes,
9553 sizeof (gdouble) * source_event->motion.device->num_axes);
9557 /* unlink all move events from queue.
9558 We handle our own, including our emulated masks. */
9562 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9563 GDK_BUTTON2_MASK | \
9564 GDK_BUTTON3_MASK | \
9565 GDK_BUTTON4_MASK | \
9569 proxy_button_event (GdkEvent *source_event,
9572 GdkWindow *toplevel_window, *event_window;
9573 GdkWindow *event_win;
9574 GdkWindow *pointer_window;
9575 GdkWindowObject *parent;
9580 gdouble toplevel_x, toplevel_y;
9581 GdkDisplay *display;
9585 type = source_event->any.type;
9586 event_window = source_event->any.window;
9587 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9588 gdk_event_get_state (source_event, &state);
9589 time_ = gdk_event_get_time (source_event);
9590 device = gdk_event_get_device (source_event);
9591 display = gdk_drawable_get_display (source_event->any.window);
9592 toplevel_window = convert_native_coords_to_toplevel (event_window,
9593 toplevel_x, toplevel_y,
9594 &toplevel_x, &toplevel_y);
9596 if (type == GDK_BUTTON_PRESS &&
9597 !source_event->any.send_event &&
9598 _gdk_display_has_device_grab (display, device, serial) == NULL)
9601 _gdk_window_find_descendant_at (toplevel_window,
9602 toplevel_x, toplevel_y,
9605 /* Find the event window, that gets the grab */
9606 w = (GdkWindowObject *)pointer_window;
9608 (parent = get_event_parent (w)) != NULL &&
9609 parent->window_type != GDK_WINDOW_ROOT)
9611 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9615 pointer_window = (GdkWindow *)w;
9617 _gdk_display_add_device_grab (display,
9623 gdk_window_get_events (pointer_window),
9627 _gdk_display_device_grab_update (display, device, serial);
9630 pointer_window = get_pointer_window (display, toplevel_window, device,
9631 toplevel_x, toplevel_y,
9634 event_win = get_event_window (display,
9640 if (event_win == NULL || display->ignore_core_events)
9643 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9644 gdk_window_get_device_events (event_win, device) == 0)
9647 event = _gdk_make_event (event_win, type, source_event, FALSE);
9651 case GDK_BUTTON_PRESS:
9652 case GDK_BUTTON_RELEASE:
9653 event->button.button = source_event->button.button;
9654 convert_toplevel_coords_to_window (event_win,
9655 toplevel_x, toplevel_y,
9656 &event->button.x, &event->button.y);
9657 event->button.x_root = source_event->button.x_root;
9658 event->button.y_root = source_event->button.y_root;
9659 event->button.state = state;
9660 event->button.device = source_event->button.device;
9661 event->button.axes = g_memdup (source_event->button.axes,
9662 sizeof (gdouble) * source_event->button.device->num_axes);
9664 if (type == GDK_BUTTON_PRESS)
9665 _gdk_event_button_generate (display, event);
9669 event->scroll.direction = source_event->scroll.direction;
9670 convert_toplevel_coords_to_window (event_win,
9671 toplevel_x, toplevel_y,
9672 &event->scroll.x, &event->scroll.y);
9673 event->scroll.x_root = source_event->scroll.x_root;
9674 event->scroll.y_root = source_event->scroll.y_root;
9675 event->scroll.state = state;
9676 event->scroll.device = source_event->scroll.device;
9683 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9686 #ifdef DEBUG_WINDOW_PRINTING
9688 gdk_window_print (GdkWindowObject *window,
9692 const char *window_types[] = {
9702 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9703 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9704 window->x, window->y,
9705 window->width, window->height
9708 if (gdk_window_has_impl (window))
9710 #ifdef GDK_WINDOWING_X11
9711 g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
9715 if (window->window_type != GDK_WINDOW_CHILD)
9716 g_print (" %s", window_types[window->window_type]);
9718 if (window->input_only)
9719 g_print (" input-only");
9722 g_print (" shaped");
9724 if (!gdk_window_is_visible ((GdkWindow *)window))
9725 g_print (" hidden");
9727 g_print (" abs[%d,%d]",
9728 window->abs_x, window->abs_y);
9730 cairo_region_get_extents (window->clip_region, &r);
9731 if (cairo_region_is_empty (window->clip_region))
9732 g_print (" clipbox[empty]");
9734 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9741 gdk_window_print_tree (GdkWindow *window,
9743 gboolean include_input_only)
9745 GdkWindowObject *private;
9748 private = (GdkWindowObject *)window;
9750 if (private->input_only && !include_input_only)
9753 gdk_window_print (private, indent);
9755 for (l = private->children; l != NULL; l = l->next)
9756 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9759 #endif /* DEBUG_WINDOW_PRINTING */
9762 _gdk_windowing_got_event (GdkDisplay *display,
9767 GdkWindow *event_window;
9768 GdkWindowObject *event_private;
9770 gboolean unlink_event;
9771 guint old_state, old_button;
9772 GdkDeviceGrabInfo *button_release_grab;
9773 GdkPointerWindowInfo *pointer_info;
9775 gboolean is_toplevel;
9777 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9778 display->last_event_time = gdk_event_get_time (event);
9780 device = gdk_event_get_device (event);
9786 g_object_get (device, "input-mode", &mode, NULL);
9787 _gdk_display_device_grab_update (display, device, serial);
9789 if (mode == GDK_MODE_DISABLED ||
9790 !_gdk_display_check_grab_ownership (display, device, serial))
9792 /* Device events are blocked by another
9793 * device grab, or the device is disabled
9795 unlink_event = TRUE;
9800 event_window = event->any.window;
9804 pointer_info = _gdk_display_get_pointer_info (display, device);
9805 event_private = GDK_WINDOW_OBJECT (event_window);
9807 #ifdef DEBUG_WINDOW_PRINTING
9808 if (event->type == GDK_KEY_PRESS &&
9809 (event->key.keyval == 0xa7 ||
9810 event->key.keyval == 0xbd))
9812 gdk_window_print_tree (event_window, 0,
9813 event->key.keyval == 0xbd);
9817 if (_gdk_native_windows)
9819 if (event->type == GDK_BUTTON_PRESS &&
9820 !event->any.send_event &&
9821 _gdk_display_has_device_grab (display, device, serial) == NULL)
9823 _gdk_display_add_device_grab (display,
9829 gdk_window_get_events (event_window),
9831 gdk_event_get_time (event),
9833 _gdk_display_device_grab_update (display, device, serial);
9835 if (event->type == GDK_BUTTON_RELEASE &&
9836 !event->any.send_event)
9838 button_release_grab =
9839 _gdk_display_has_device_grab (display, device, serial);
9840 if (button_release_grab &&
9841 button_release_grab->implicit &&
9842 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9844 button_release_grab->serial_end = serial;
9845 button_release_grab->implicit_ungrab = FALSE;
9846 _gdk_display_device_grab_update (display, device, serial);
9850 if (event->type == GDK_BUTTON_PRESS)
9851 _gdk_event_button_generate (display, event);
9856 if (event->type == GDK_VISIBILITY_NOTIFY)
9858 event_private->native_visibility = event->visibility.state;
9859 gdk_window_update_visibility_recursively (event_private,
9864 if (!(is_button_type (event->type) ||
9865 is_motion_type (event->type)) ||
9866 event_private->window_type == GDK_WINDOW_ROOT)
9869 is_toplevel = gdk_window_is_toplevel (event_private);
9871 if ((event->type == GDK_ENTER_NOTIFY ||
9872 event->type == GDK_LEAVE_NOTIFY) &&
9873 (event->crossing.mode == GDK_CROSSING_GRAB ||
9874 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9875 (_gdk_display_has_device_grab (display, device, serial) ||
9876 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9878 /* We synthesize all crossing events due to grabs ourselves,
9879 * so we ignore the native ones caused by our native pointer_grab
9880 * calls. Otherwise we would proxy these crossing event and cause
9881 * multiple copies of crossing events for grabs.
9883 * We do want to handle grabs from other clients though, as for
9884 * instance alt-tab in metacity causes grabs like these and
9885 * we want to handle those. Thus the has_pointer_grab check.
9887 * Implicit grabs on child windows create some grabbing events
9888 * that are sent before the button press. This means we can't
9889 * detect these with the has_pointer_grab check (as the implicit
9890 * grab is only noticed when we get button press event), so we
9891 * detect these events by checking for INFERIOR enter or leave
9892 * events. These should never be a problem to filter out.
9895 /* We ended up in this window after some (perhaps other clients)
9896 grab, so update the toplevel_under_window state */
9898 event->type == GDK_ENTER_NOTIFY &&
9899 event->crossing.mode == GDK_CROSSING_UNGRAB)
9901 if (pointer_info->toplevel_under_pointer)
9902 g_object_unref (pointer_info->toplevel_under_pointer);
9903 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9906 unlink_event = TRUE;
9910 /* Track toplevel_under_pointer */
9913 if (event->type == GDK_ENTER_NOTIFY &&
9914 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9916 if (pointer_info->toplevel_under_pointer)
9917 g_object_unref (pointer_info->toplevel_under_pointer);
9918 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9920 else if (event->type == GDK_LEAVE_NOTIFY &&
9921 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9922 pointer_info->toplevel_under_pointer == event_window)
9924 if (pointer_info->toplevel_under_pointer)
9925 g_object_unref (pointer_info->toplevel_under_pointer);
9926 pointer_info->toplevel_under_pointer = NULL;
9930 /* Store last pointer window and position/state */
9931 old_state = pointer_info->state;
9932 old_button = pointer_info->button;
9934 gdk_event_get_coords (event, &x, &y);
9935 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9936 pointer_info->toplevel_x = x;
9937 pointer_info->toplevel_y = y;
9938 gdk_event_get_state (event, &pointer_info->state);
9939 if (event->type == GDK_BUTTON_PRESS ||
9940 event->type == GDK_BUTTON_RELEASE)
9941 pointer_info->button = event->button.button;
9944 (pointer_info->state != old_state ||
9945 pointer_info->button != old_button))
9946 _gdk_display_enable_motion_hints (display, device);
9948 unlink_event = FALSE;
9949 if (is_motion_type (event->type))
9950 unlink_event = proxy_pointer_event (display,
9953 else if (is_button_type (event->type))
9954 unlink_event = proxy_button_event (event,
9957 if (event->type == GDK_BUTTON_RELEASE &&
9958 !event->any.send_event)
9960 button_release_grab =
9961 _gdk_display_has_device_grab (display, device, serial);
9962 if (button_release_grab &&
9963 button_release_grab->implicit &&
9964 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9966 button_release_grab->serial_end = serial;
9967 button_release_grab->implicit_ungrab = FALSE;
9968 _gdk_display_device_grab_update (display, device, serial);
9975 _gdk_event_queue_remove_link (display, event_link);
9976 g_list_free_1 (event_link);
9977 gdk_event_free (event);
9983 get_extension_event_window (GdkDisplay *display,
9984 GdkWindow *pointer_window,
9989 GdkWindow *grab_window;
9991 GdkDeviceGrabInfo *grab;
9993 /* FIXME: which device? */
9994 grab = _gdk_display_has_device_grab (display, display->core_pointer, serial);
9996 if (grab != NULL && !grab->owner_events)
9998 evmask = grab->event_mask;
10000 grab_window = grab->window;
10002 if (evmask & type_masks[type])
10003 return grab_window;
10008 w = (GdkWindowObject *)pointer_window;
10011 evmask = w->extension_events;
10013 if (evmask & type_masks[type])
10014 return (GdkWindow *)w;
10016 w = get_event_parent (w);
10019 if (grab != NULL &&
10020 grab->owner_events)
10022 evmask = grab->event_mask;
10024 if (evmask & type_masks[type])
10025 return grab->window;
10035 _gdk_window_get_input_window_for_event (GdkWindow *native_window,
10036 GdkEventType event_type,
10040 GdkDisplay *display;
10041 GdkWindow *toplevel_window;
10042 GdkWindow *pointer_window;
10043 GdkWindow *event_win;
10044 gdouble toplevel_x, toplevel_y;
10049 display = gdk_drawable_get_display (native_window);
10050 toplevel_window = convert_native_coords_to_toplevel (native_window,
10051 toplevel_x, toplevel_y,
10052 &toplevel_x, &toplevel_y);
10053 /* FIXME: which device? */
10054 pointer_window = get_pointer_window (display, toplevel_window, NULL,
10055 toplevel_x, toplevel_y, serial);
10056 event_win = get_extension_event_window (display,
10065 * gdk_window_create_similar_surface:
10066 * @window: window to make new surface similar to
10067 * @content: the content for the new surface
10068 * @width: width of the new surface
10069 * @height: height of the new surface
10071 * Create a new surface that is as compatible as possible with the
10072 * given @window. For example the new surface will have the same
10073 * fallback resolution and font options as @window. Generally, the new
10074 * surface will also use the same backend as @window, unless that is
10075 * not possible for some reason. The type of the returned surface may
10076 * be examined with cairo_surface_get_type().
10078 * Initially the surface contents are all 0 (transparent if contents
10079 * have transparency, black otherwise.)
10081 * Returns: a pointer to the newly allocated surface. The caller
10082 * owns the surface and should call cairo_surface_destroy() when done
10085 * This function always returns a valid pointer, but it will return a
10086 * pointer to a "nil" surface if @other is already in an error state
10087 * or any other error occurs.
10092 gdk_window_create_similar_surface (GdkWindow * window,
10093 cairo_content_t content,
10097 cairo_surface_t *window_surface, *surface;
10099 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
10101 window_surface = _gdk_drawable_ref_cairo_surface (window);
10103 surface = cairo_surface_create_similar (window_surface,
10107 cairo_surface_destroy (window_surface);