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"
50 #undef DEBUG_WINDOW_PRINTING
55 * @Short_description: Onscreen display areas in the target window system
58 * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
59 * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
60 * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
61 * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
62 * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
65 * <refsect2 id="COMPOSITED-WINDOWS">
66 * <title>Composited Windows</title>
68 * Normally, the windowing system takes care of rendering the contents of a
69 * child window onto its parent window. This mechanism can be intercepted by
70 * calling gdk_window_set_composited() on the child window. For a
71 * <firstterm>composited</firstterm> window it is the responsibility of the
72 * application to render the window contents at the right spot.
74 * <example id="composited-window-example">
75 * <title>Composited windows</title>
77 * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../examples/gdk/composited-window-example.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include>
78 * </programlisting></example>
80 * In the example <xref linkend="composited-window-example"/>, a button is
81 * placed inside of an event box inside of a window. The event box is set as
82 * composited and therefore is no longer automatically drawn to the screen.
84 * When the contents of the event box change, an expose event is generated on
85 * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
86 * The expose handler for this widget is responsible for merging the changes
87 * back on the screen in the way that it wishes.
89 * In our case, we merge the contents with a 50% transparency. We also set the
90 * background colour of the window to red. The effect is that the background
91 * shows through the button.
94 * <refsect2 id="OFFSCREEN-WINDOWS">
95 * <title>Offscreen Windows</title>
97 * Offscreen windows are more general than composited windows, since they allow
98 * not only to modify the rendering of the child window onto its parent, but
99 * also to apply coordinate transformations.
101 * To integrate an offscreen window into a window hierarchy, one has to call
102 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
103 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
104 * select an offscreen child at given coordinates, and the
105 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
106 * offscreen window are used to translate coordinates between the embedder and
107 * the offscreen window.
109 * For rendering an offscreen window onto its embedder, the contents of the
110 * offscreen window are available as a pixmap, via
111 * gdk_offscreen_window_get_pixmap().
117 /* Historically a GdkWindow always matches a platform native window,
118 * be it a toplevel window or a child window. In this setup the
119 * GdkWindow (and other GdkDrawables) were platform independent classes,
120 * and the actual platform specific implementation was in a delegate
121 * object availible as "impl" in the window object.
123 * With the addition of client side windows and offscreen windows this
124 * changes a bit. The application-visible GdkWindow object behaves as
125 * it did before, but not all such windows now have a corresponding native
126 * window. Instead windows that are "client side" are emulated by the gdk
127 * code such that clipping, drawing, moving, events etc work as expected.
129 * For GdkWindows that have a native window the "impl" object is the
130 * same as before. However, for all client side windows the impl object
131 * is shared with its parent (i.e. all client windows descendants of one
132 * native window has the same impl.
134 * Additionally there is a new type of platform independent impl object,
135 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
136 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
137 * windows). Such windows work by allocating a GdkPixmap as the backing store
138 * for drawing operations, which is resized with the window.
140 * GdkWindows have a pointer to the "impl window" they are in, i.e.
141 * the topmost GdkWindow which have the same "impl" value. This is stored
142 * in impl_window, which is different from the window itself only for client
144 * All GdkWindows (native or not) track the position of the window in the parent
145 * (x, y), the size of the window (width, height), the position of the window
146 * with respect to the impl window (abs_x, abs_y). We also track the clip
147 * region of the window wrt parent windows and siblings, in window-relative
148 * coordinates with and without child windows included (clip_region,
149 * clip_region_with_children).
151 * All toplevel windows are native windows, but also child windows can be
152 * native (although not children of offscreens). We always listen to
153 * a basic set of events (see get_native_event_mask) for these windows
154 * so that we can emulate events for any client side children.
156 * For native windows we apply the calculated clip region as a window shape
157 * so that eg. client side siblings that overlap the native child properly
158 * draws over the native child window.
160 * In order to minimize flicker and for performance we use a couple of cacheing
161 * tricks. First of all, every time we do a window to window copy area, for instance
162 * when moving a client side window or when scrolling/moving a region in a window
163 * we store this in outstanding_moves instead of applying immediately. We then
164 * delay this move until we really need it (because something depends on being
165 * able to read it), or until we're handing a redraw from an expose/invalidation
166 * (actually we delay it past redraw, but before blitting the double buffer pixmap
167 * to the window). This gives us two advantages. First of all it minimizes the time
168 * from the window is moved to the exposes related to that move, secondly it allows
169 * us to be smart about how to do the copy. We combine multiple moves into one (when
170 * possible) and we don't actually do copies to anything that is or will be
171 * invalidated and exposed anyway.
173 * Secondly, we use something called a "implicit paint" during repaint handling.
174 * An implicit paint is similar to a regular paint for the paint stack, but it is
175 * not put on the stack. Instead, it is set on the impl window, and later when
176 * regular gdk_window_begin_paint_region() happen on a window of this impl window
177 * we reuse the pixmap from the implicit paint. During repaint we create and at the
178 * end flush an implicit paint, which means we can collect all the paints on
179 * multiple client side windows in the same backing store pixmap.
181 * All drawing to windows are wrapped with macros that set up the GC such that
182 * the offsets and clip region is right for drawing to the paint object or
183 * directly to the emulated window. It also automatically handles any flushing
184 * needed when drawing directly to a window. Adding window/paint clipping is
185 * done using _gdk_gc_add_drawable_clip which lets us efficiently add and then
186 * remove a custom clip region.
189 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
191 /* This adds a local value to the GdkVisibilityState enum */
192 #define GDK_VISIBILITY_NOT_VIEWABLE 3
195 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
208 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
212 struct _GdkWindowPaint
218 cairo_surface_t *surface;
219 guint uses_implicit : 1;
225 GdkRegion *dest_region; /* The destination region */
226 int dx, dy; /* The amount that the source was moved to reach dest_region */
227 } GdkWindowRegionMove;
231 static GdkGC *gdk_window_create_gc (GdkDrawable *drawable,
233 GdkGCValuesMask mask);
234 static void gdk_window_draw_rectangle (GdkDrawable *drawable,
241 static void gdk_window_draw_arc (GdkDrawable *drawable,
250 static void gdk_window_draw_polygon (GdkDrawable *drawable,
255 static void gdk_window_draw_drawable (GdkDrawable *drawable,
264 GdkDrawable *original_src);
265 static void gdk_window_draw_points (GdkDrawable *drawable,
269 static void gdk_window_draw_segments (GdkDrawable *drawable,
273 static void gdk_window_draw_lines (GdkDrawable *drawable,
278 static void gdk_window_draw_glyphs (GdkDrawable *drawable,
283 PangoGlyphString *glyphs);
284 static void gdk_window_draw_glyphs_transformed (GdkDrawable *drawable,
290 PangoGlyphString *glyphs);
292 static void gdk_window_draw_image (GdkDrawable *drawable,
302 static void gdk_window_draw_pixbuf (GdkDrawable *drawable,
315 static void gdk_window_draw_trapezoids (GdkDrawable *drawable,
317 GdkTrapezoid *trapezoids,
320 static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
329 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
330 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
333 static void gdk_window_drop_cairo_surface (GdkWindowObject *private);
334 static void gdk_window_set_cairo_clip (GdkDrawable *drawable,
337 static void gdk_window_real_get_size (GdkDrawable *drawable,
341 static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable);
342 static gint gdk_window_real_get_depth (GdkDrawable *drawable);
343 static GdkScreen* gdk_window_real_get_screen (GdkDrawable *drawable);
344 static void gdk_window_real_set_colormap (GdkDrawable *drawable,
346 static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
348 static GdkDrawable* gdk_window_get_source_drawable (GdkDrawable *drawable);
349 static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable,
354 gint *composite_x_offset,
355 gint *composite_y_offset);
356 static GdkRegion* gdk_window_get_clip_region (GdkDrawable *drawable);
357 static GdkRegion* gdk_window_get_visible_region (GdkDrawable *drawable);
359 static void gdk_window_free_paint_stack (GdkWindow *window);
361 static void gdk_window_init (GdkWindowObject *window);
362 static void gdk_window_class_init (GdkWindowObjectClass *klass);
363 static void gdk_window_finalize (GObject *object);
365 static void gdk_window_set_property (GObject *object,
369 static void gdk_window_get_property (GObject *object,
374 static void gdk_window_clear_backing_region (GdkWindow *window,
376 static void gdk_window_redirect_free (GdkWindowRedirect *redirect);
377 static void apply_redirect_to_children (GdkWindowObject *private,
378 GdkWindowRedirect *redirect);
379 static void remove_redirect_from_children (GdkWindowObject *private,
380 GdkWindowRedirect *redirect);
382 static void recompute_visible_regions (GdkWindowObject *private,
383 gboolean recalculate_siblings,
384 gboolean recalculate_children);
385 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
386 static void gdk_window_flush_recursive (GdkWindowObject *window);
387 static void do_move_region_bits_on_impl (GdkWindowObject *private,
388 GdkRegion *region, /* In impl window coords */
390 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
391 static void move_native_children (GdkWindowObject *private);
392 static void update_cursor (GdkDisplay *display,
394 static void impl_window_add_update_area (GdkWindowObject *impl_window,
396 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
397 static void gdk_window_invalidate_region_full (GdkWindow *window,
398 const GdkRegion *region,
399 gboolean invalidate_children,
401 static void gdk_window_invalidate_rect_full (GdkWindow *window,
402 const GdkRectangle *rect,
403 gboolean invalidate_children,
406 static guint signals[LAST_SIGNAL] = { 0 };
408 static gpointer parent_class = NULL;
410 static const cairo_user_data_key_t gdk_window_cairo_key;
413 new_region_tag (void)
415 static guint32 tag = 0;
421 gdk_window_object_get_type (void)
423 static GType object_type = 0;
426 object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
428 sizeof (GdkWindowObjectClass),
429 (GClassInitFunc) gdk_window_class_init,
430 sizeof (GdkWindowObject),
431 (GInstanceInitFunc) gdk_window_init,
438 _gdk_paintable_get_type (void)
440 static GType paintable_type = 0;
444 const GTypeInfo paintable_info =
446 sizeof (GdkPaintableIface), /* class_size */
447 NULL, /* base_init */
448 NULL, /* base_finalize */
451 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
452 g_intern_static_string ("GdkPaintable"),
455 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
458 return paintable_type;
462 gdk_window_init (GdkWindowObject *window)
464 /* 0-initialization is good for all other fields. */
466 window->window_type = GDK_WINDOW_CHILD;
468 window->state = GDK_WINDOW_STATE_WITHDRAWN;
471 window->toplevel_window_type = -1;
473 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
474 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
475 /* Default to unobscured since some backends don't send visibility events */
476 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
479 /* Stop and return on the first non-NULL parent */
481 accumulate_get_window (GSignalInvocationHint *ihint,
483 const GValue *handler_return,
486 g_value_copy (handler_return, return_accu);
487 /* Continue while returning NULL */
488 return g_value_get_object (handler_return) == NULL;
491 static GQuark quark_pointer_window = 0;
494 gdk_window_class_init (GdkWindowObjectClass *klass)
496 GObjectClass *object_class = G_OBJECT_CLASS (klass);
497 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
499 parent_class = g_type_class_peek_parent (klass);
501 object_class->finalize = gdk_window_finalize;
502 object_class->set_property = gdk_window_set_property;
503 object_class->get_property = gdk_window_get_property;
505 drawable_class->create_gc = gdk_window_create_gc;
506 drawable_class->draw_rectangle = gdk_window_draw_rectangle;
507 drawable_class->draw_arc = gdk_window_draw_arc;
508 drawable_class->draw_polygon = gdk_window_draw_polygon;
509 drawable_class->draw_drawable_with_src = gdk_window_draw_drawable;
510 drawable_class->draw_points = gdk_window_draw_points;
511 drawable_class->draw_segments = gdk_window_draw_segments;
512 drawable_class->draw_lines = gdk_window_draw_lines;
513 drawable_class->draw_glyphs = gdk_window_draw_glyphs;
514 drawable_class->draw_glyphs_transformed = gdk_window_draw_glyphs_transformed;
515 drawable_class->draw_image = gdk_window_draw_image;
516 drawable_class->draw_pixbuf = gdk_window_draw_pixbuf;
517 drawable_class->draw_trapezoids = gdk_window_draw_trapezoids;
518 drawable_class->get_depth = gdk_window_real_get_depth;
519 drawable_class->get_screen = gdk_window_real_get_screen;
520 drawable_class->get_size = gdk_window_real_get_size;
521 drawable_class->set_colormap = gdk_window_real_set_colormap;
522 drawable_class->get_colormap = gdk_window_real_get_colormap;
523 drawable_class->get_visual = gdk_window_real_get_visual;
524 drawable_class->_copy_to_image = gdk_window_copy_to_image;
525 drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
526 drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
527 drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
528 drawable_class->get_clip_region = gdk_window_get_clip_region;
529 drawable_class->get_visible_region = gdk_window_get_visible_region;
530 drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
531 drawable_class->get_source_drawable = gdk_window_get_source_drawable;
533 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
541 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
542 * gdk_window_get_cursor() for details.
546 g_object_class_install_property (object_class,
548 g_param_spec_boxed ("cursor",
555 * GdkWindow::pick-embedded-child:
556 * @window: the window on which the signal is emitted
557 * @x: x coordinate in the window
558 * @y: y coordinate in the window
560 * The ::pick-embedded-child signal is emitted to find an embedded
561 * child at the given position.
563 * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
567 signals[PICK_EMBEDDED_CHILD] =
568 g_signal_new (g_intern_static_string ("pick-embedded-child"),
569 G_OBJECT_CLASS_TYPE (object_class),
572 accumulate_get_window, NULL,
573 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
580 * GdkWindow::to-embedder:
581 * @window: the offscreen window on which the signal is emitted
582 * @offscreen-x: x coordinate in the offscreen window
583 * @offscreen-y: y coordinate in the offscreen window
584 * @embedder-x: return location for the x coordinate in the embedder window
585 * @embedder-y: return location for the y coordinate in the embedder window
587 * The ::to-embedder signal is emitted to translate coordinates
588 * in an offscreen window to its embedder.
590 * See also #GtkWindow::from-embedder.
594 signals[TO_EMBEDDER] =
595 g_signal_new (g_intern_static_string ("to-embedder"),
596 G_OBJECT_CLASS_TYPE (object_class),
600 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
609 * GdkWindow::from-embedder:
610 * @window: the offscreen window on which the signal is emitted
611 * @embedder-x: x coordinate in the embedder window
612 * @embedder-y: y coordinate in the embedder window
613 * @offscreen-x: return location for the x coordinate in the offscreen window
614 * @offscreen-y: return location for the y coordinate in the offscreen window
616 * The ::from-embedder signal is emitted to translate coordinates
617 * in the embedder of an offscreen window to the offscreen window.
619 * See also #GtkWindow::to-embedder.
623 signals[FROM_EMBEDDER] =
624 g_signal_new (g_intern_static_string ("from-embedder"),
625 G_OBJECT_CLASS_TYPE (object_class),
629 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
639 device_removed_cb (GdkDeviceManager *device_manager,
643 GdkWindowObject *private;
645 private = (GdkWindowObject *) window;
647 private->devices_inside = g_list_remove (private->devices_inside, device);
648 g_hash_table_remove (private->device_cursor, device);
650 if (private->device_events)
651 g_hash_table_remove (private->device_events, device);
655 gdk_window_finalize (GObject *object)
657 GdkWindow *window = GDK_WINDOW (object);
658 GdkWindowObject *obj = (GdkWindowObject *) object;
659 GdkDeviceManager *device_manager;
661 device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (window)));
662 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
664 if (!GDK_WINDOW_DESTROYED (window))
666 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
668 g_warning ("losing last reference to undestroyed window\n");
669 _gdk_window_destroy (window, FALSE);
672 /* We use TRUE here, to keep us from actually calling
673 * XDestroyWindow() on the window
675 _gdk_window_destroy (window, TRUE);
680 g_object_unref (obj->impl);
684 if (obj->impl_window != obj)
686 g_object_unref (obj->impl_window);
687 obj->impl_window = NULL;
691 gdk_region_destroy (obj->shape);
693 if (obj->input_shape)
694 gdk_region_destroy (obj->input_shape);
697 gdk_cursor_unref (obj->cursor);
699 if (obj->device_cursor)
700 g_hash_table_destroy (obj->device_cursor);
702 if (obj->device_events)
703 g_hash_table_destroy (obj->device_events);
705 if (obj->devices_inside)
706 g_list_free (obj->devices_inside);
708 G_OBJECT_CLASS (parent_class)->finalize (object);
712 gdk_window_set_property (GObject *object,
717 GdkWindow *window = (GdkWindow *)object;
722 gdk_window_set_cursor (window, g_value_get_boxed (value));
726 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
732 gdk_window_get_property (GObject *object,
737 GdkWindow *window = (GdkWindow *) object;
742 g_value_set_boxed (value, gdk_window_get_cursor (window));
746 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
752 gdk_window_is_offscreen (GdkWindowObject *window)
754 return window->window_type == GDK_WINDOW_OFFSCREEN;
757 static GdkWindowObject *
758 gdk_window_get_impl_window (GdkWindowObject *window)
760 return window->impl_window;
764 _gdk_window_get_impl_window (GdkWindow *window)
766 return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
770 gdk_window_has_impl (GdkWindowObject *window)
772 return window->impl_window == window;
776 gdk_window_is_toplevel (GdkWindowObject *window)
779 window->parent == NULL ||
780 window->parent->window_type == GDK_WINDOW_ROOT;
784 _gdk_window_has_impl (GdkWindow *window)
786 return gdk_window_has_impl ((GdkWindowObject *)window);
790 gdk_window_has_no_impl (GdkWindowObject *window)
792 return window->impl_window != window;
796 remove_child_area (GdkWindowObject *private,
797 GdkWindowObject *until,
801 GdkWindowObject *child;
802 GdkRegion *child_region;
807 for (l = private->children; l; l = l->next)
814 /* If region is empty already, no need to do
815 anything potentially costly */
816 if (gdk_region_empty (region))
819 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
822 /* Ignore offscreen children, as they don't draw in their parent and
823 * don't take part in the clipping */
824 if (gdk_window_is_offscreen (child))
829 r.width = child->width;
830 r.height = child->height;
832 /* Bail early if child totally outside region */
833 if (gdk_region_rect_in (region, &r) == GDK_OVERLAP_RECTANGLE_OUT)
836 child_region = gdk_region_rectangle (&r);
840 /* Adjust shape region to parent window coords */
841 gdk_region_offset (child->shape, child->x, child->y);
842 gdk_region_intersect (child_region, child->shape);
843 gdk_region_offset (child->shape, -child->x, -child->y);
845 else if (private->window_type == GDK_WINDOW_FOREIGN)
847 shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
850 gdk_region_intersect (child_region, shape);
851 gdk_region_destroy (shape);
857 if (child->input_shape)
858 gdk_region_intersect (child_region, child->input_shape);
859 else if (private->window_type == GDK_WINDOW_FOREIGN)
861 shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
864 gdk_region_intersect (child_region, shape);
865 gdk_region_destroy (shape);
870 gdk_region_subtract (region, child_region);
871 gdk_region_destroy (child_region);
876 static GdkVisibilityState
877 effective_visibility (GdkWindowObject *private)
879 GdkVisibilityState native;
881 if (!gdk_window_is_viewable ((GdkWindow *)private))
882 return GDK_VISIBILITY_NOT_VIEWABLE;
884 native = private->impl_window->native_visibility;
886 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
887 private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
888 return GDK_VISIBILITY_FULLY_OBSCURED;
889 else if (native == GDK_VISIBILITY_UNOBSCURED)
890 return private->visibility;
891 else /* native PARTIAL, private partial or unobscured */
892 return GDK_VISIBILITY_PARTIAL;
896 gdk_window_update_visibility (GdkWindowObject *private)
898 GdkVisibilityState new_visibility;
901 new_visibility = effective_visibility (private);
903 if (new_visibility != private->effective_visibility)
905 private->effective_visibility = new_visibility;
907 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
908 private->event_mask & GDK_VISIBILITY_NOTIFY)
910 event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
912 event->visibility.state = new_visibility;
918 gdk_window_update_visibility_recursively (GdkWindowObject *private,
919 GdkWindowObject *only_for_impl)
921 GdkWindowObject *child;
924 gdk_window_update_visibility (private);
925 for (l = private->children; l != NULL; l = l->next)
928 if ((only_for_impl == NULL) ||
929 (only_for_impl == child->impl_window))
930 gdk_window_update_visibility_recursively (child, only_for_impl);
935 should_apply_clip_as_shape (GdkWindowObject *private)
938 gdk_window_has_impl (private) &&
939 /* Not for offscreens */
940 !gdk_window_is_offscreen (private) &&
941 /* or for toplevels */
942 !gdk_window_is_toplevel (private) &&
943 /* or for foreign windows */
944 private->window_type != GDK_WINDOW_FOREIGN &&
945 /* or for the root window */
946 private->window_type != GDK_WINDOW_ROOT;
950 apply_shape (GdkWindowObject *private,
953 GdkWindowImplIface *impl_iface;
955 /* We trash whether we applied a shape so that
956 we can avoid unsetting it many times, which
957 could happen in e.g. apply_clip_as_shape as
958 windows get resized */
959 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
961 impl_iface->shape_combine_region ((GdkWindow *)private,
963 else if (private->applied_shape)
964 impl_iface->shape_combine_region ((GdkWindow *)private,
967 private->applied_shape = region != NULL;
971 apply_clip_as_shape (GdkWindowObject *private)
976 r.width = private->width;
977 r.height = private->height;
979 /* We only apply the clip region if would differ
980 from the actual clip region implied by the size
981 of the window. This is to avoid unneccessarily
982 adding meaningless shapes to all native subwindows */
983 if (!gdk_region_rect_equal (private->clip_region, &r))
984 apply_shape (private, private->clip_region);
986 apply_shape (private, NULL);
990 recompute_visible_regions_internal (GdkWindowObject *private,
991 gboolean recalculate_clip,
992 gboolean recalculate_siblings,
993 gboolean recalculate_children)
997 GdkWindowObject *child;
998 GdkRegion *new_clip, *old_clip_region_with_children;
999 gboolean clip_region_changed;
1000 gboolean abs_pos_changed;
1001 int old_abs_x, old_abs_y;
1003 old_abs_x = private->abs_x;
1004 old_abs_y = private->abs_y;
1006 /* Update absolute position */
1007 if (gdk_window_has_impl (private))
1009 /* Native window starts here */
1015 private->abs_x = private->parent->abs_x + private->x;
1016 private->abs_y = private->parent->abs_y + private->y;
1020 private->abs_x != old_abs_x ||
1021 private->abs_y != old_abs_y;
1023 /* Update clip region based on:
1026 * siblings in parents above window
1028 clip_region_changed = FALSE;
1029 if (recalculate_clip)
1031 if (private->viewable)
1033 /* Calculate visible region (sans children) in parent window coords */
1036 r.width = private->width;
1037 r.height = private->height;
1038 new_clip = gdk_region_rectangle (&r);
1040 if (!gdk_window_is_toplevel (private))
1042 gdk_region_intersect (new_clip, private->parent->clip_region);
1044 /* Remove all overlapping children from parent.
1045 * Unless we're all native, because then we don't need to take
1046 * siblings into account since X does that clipping for us.
1047 * This makes things like SWT that modify the raw X stacking
1048 * order without GDKs knowledge work.
1050 if (!_gdk_native_windows)
1051 remove_child_area (private->parent, private, FALSE, new_clip);
1054 /* Convert from parent coords to window coords */
1055 gdk_region_offset (new_clip, -private->x, -private->y);
1058 gdk_region_intersect (new_clip, private->shape);
1061 new_clip = gdk_region_new ();
1063 if (private->clip_region == NULL ||
1064 !gdk_region_equal (private->clip_region, new_clip))
1065 clip_region_changed = TRUE;
1067 if (private->clip_region)
1068 gdk_region_destroy (private->clip_region);
1069 private->clip_region = new_clip;
1071 old_clip_region_with_children = private->clip_region_with_children;
1072 private->clip_region_with_children = gdk_region_copy (private->clip_region);
1073 if (private->window_type != GDK_WINDOW_ROOT)
1074 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
1076 if (clip_region_changed ||
1077 !gdk_region_equal (private->clip_region_with_children, old_clip_region_with_children))
1078 private->clip_tag = new_region_tag ();
1080 if (old_clip_region_with_children)
1081 gdk_region_destroy (old_clip_region_with_children);
1084 if (clip_region_changed)
1086 GdkVisibilityState visibility;
1087 gboolean fully_visible;
1089 if (gdk_region_empty (private->clip_region))
1090 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
1095 fully_visible = gdk_region_equal (private->clip_region,
1102 r.width = private->width;
1103 r.height = private->height;
1104 fully_visible = gdk_region_rect_equal (private->clip_region, &r);
1108 visibility = GDK_VISIBILITY_UNOBSCURED;
1110 visibility = GDK_VISIBILITY_PARTIAL;
1113 if (private->visibility != visibility)
1115 private->visibility = visibility;
1116 gdk_window_update_visibility (private);
1120 /* Update all children, recursively (except for root, where children are not exact). */
1121 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1122 private->window_type != GDK_WINDOW_ROOT)
1124 for (l = private->children; l; l = l->next)
1127 /* Only recalculate clip if the the clip region changed, otherwise
1128 * there is no way the child clip region could change (its has not e.g. moved)
1129 * Except if recalculate_children is set to force child updates
1131 recompute_visible_regions_internal (child,
1132 recalculate_clip && (clip_region_changed || recalculate_children),
1137 if (clip_region_changed &&
1138 should_apply_clip_as_shape (private))
1139 apply_clip_as_shape (private);
1141 if (recalculate_siblings &&
1142 !gdk_window_is_toplevel (private))
1144 /* If we moved a child window in parent or changed the stacking order, then we
1145 * need to recompute the visible area of all the other children in the parent
1147 for (l = private->parent->children; l; l = l->next)
1151 if (child != private)
1152 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1155 /* We also need to recompute the _with_children clip for the parent */
1156 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1159 if (private->cairo_surface)
1163 /* It would be nice if we had some cairo support here so we
1164 could set the clip rect on the cairo surface */
1165 width = private->abs_x + private->width;
1166 height = private->abs_y + private->height;
1168 _gdk_windowing_set_cairo_surface_size (private->cairo_surface,
1170 cairo_surface_set_device_offset (private->cairo_surface,
1176 /* Call this when private has changed in one or more of these ways:
1180 * stacking order of window changed
1183 * It will recalculate abs_x/y and the clip regions
1185 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1186 * for recalculate_siblings. (Mostly used internally for the recursion)
1188 * If a child window was removed (and you can't use that child for
1189 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1192 recompute_visible_regions (GdkWindowObject *private,
1193 gboolean recalculate_siblings,
1194 gboolean recalculate_children)
1196 recompute_visible_regions_internal (private,
1198 recalculate_siblings,
1199 recalculate_children);
1203 _gdk_window_update_size (GdkWindow *window)
1205 recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1208 /* Find the native window that would be just above "child"
1209 * in the native stacking order if "child" was a native window
1210 * (it doesn't have to be native). If there is no such native
1211 * window inside this native parent then NULL is returned.
1212 * If child is NULL, find lowest native window in parent.
1214 static GdkWindowObject *
1215 find_native_sibling_above_helper (GdkWindowObject *parent,
1216 GdkWindowObject *child)
1223 l = g_list_find (parent->children, child);
1224 g_assert (l != NULL); /* Better be a child of its parent... */
1225 l = l->prev; /* Start looking at the one above the child */
1228 l = g_list_last (parent->children);
1230 for (; l != NULL; l = l->prev)
1234 if (gdk_window_has_impl (w))
1237 g_assert (parent != w);
1238 w = find_native_sibling_above_helper (w, NULL);
1247 static GdkWindowObject *
1248 find_native_sibling_above (GdkWindowObject *parent,
1249 GdkWindowObject *child)
1253 w = find_native_sibling_above_helper (parent, child);
1257 if (gdk_window_has_impl (parent))
1260 return find_native_sibling_above (parent->parent, parent);
1264 get_native_device_event_mask (GdkWindowObject *private,
1267 GdkEventMask event_mask;
1270 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1272 event_mask = private->event_mask;
1274 if (_gdk_native_windows ||
1275 private->window_type == GDK_WINDOW_ROOT ||
1276 private->window_type == GDK_WINDOW_FOREIGN)
1282 /* Do whatever the app asks to, since the app
1283 * may be asking for weird things for native windows,
1284 * but don't use motion hints as that may affect non-native
1285 * child windows that don't want it. Also, we need to
1286 * set all the app-specified masks since they will be picked
1287 * up by any implicit grabs (i.e. if they were not set as
1288 * native we would not get the events we need). */
1289 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1291 /* We need thse for all native windows so we can
1292 emulate events on children: */
1295 GDK_VISIBILITY_NOTIFY_MASK |
1296 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1298 /* Additionally we select for pointer and button events
1299 * for toplevels as we need to get these to emulate
1300 * them for non-native subwindows. Even though we don't
1301 * select on them for all native windows we will get them
1302 * as the events are propagated out to the first window
1303 * that select for them.
1304 * Not selecting for button press on all windows is an
1305 * important thing, because in X only one client can do
1306 * so, and we don't want to unexpectedly prevent another
1307 * client from doing it.
1309 * We also need to do the same if the app selects for button presses
1310 * because then we will get implicit grabs for this window, and the
1311 * event mask used for that grab is based on the rest of the mask
1312 * for the window, but we might need more events than this window
1313 * lists due to some non-native child window.
1315 if (gdk_window_is_toplevel (private) ||
1316 mask & GDK_BUTTON_PRESS_MASK)
1318 GDK_POINTER_MOTION_MASK |
1319 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1327 get_native_grab_event_mask (GdkEventMask grab_mask)
1329 /* Similar to the above but for pointer events only */
1331 GDK_POINTER_MOTION_MASK |
1332 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1333 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1336 ~GDK_POINTER_MOTION_HINT_MASK);
1340 get_native_event_mask (GdkWindowObject *private)
1342 return get_native_device_event_mask (private, NULL);
1345 /* Puts the native window in the right order wrt the other native windows
1346 * in the hierarchy, given the position it has in the client side data.
1347 * This is useful if some operation changed the stacking order.
1348 * This calls assumes the native window is now topmost in its native parent.
1351 sync_native_window_stack_position (GdkWindow *window)
1353 GdkWindowObject *above;
1354 GdkWindowObject *private;
1355 GdkWindowImplIface *impl_iface;
1356 GList listhead = {0};
1358 private = (GdkWindowObject *) window;
1359 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1361 above = find_native_sibling_above (private->parent, private);
1364 listhead.data = window;
1365 impl_iface->restack_under ((GdkWindow *)above,
1372 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1373 * the default root window for the default display.
1374 * @attributes: attributes of the new window
1375 * @attributes_mask: mask indicating which fields in @attributes are valid
1377 * Creates a new #GdkWindow using the attributes from
1378 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1379 * more details. Note: to use this on displays other than the default
1380 * display, @parent must be specified.
1382 * Return value: (transfer none): the new #GdkWindow
1385 gdk_window_new (GdkWindow *parent,
1386 GdkWindowAttr *attributes,
1387 gint attributes_mask)
1390 GdkWindowObject *private;
1395 GdkEventMask event_mask;
1396 GdkWindow *real_parent;
1397 GdkDeviceManager *device_manager;
1399 g_return_val_if_fail (attributes != NULL, NULL);
1403 GDK_NOTE (MULTIHEAD,
1404 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1406 screen = gdk_screen_get_default ();
1407 parent = gdk_screen_get_root_window (screen);
1410 screen = gdk_drawable_get_screen (parent);
1412 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1414 if (GDK_WINDOW_DESTROYED (parent))
1416 g_warning ("gdk_window_new(): parent is destroyed\n");
1420 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1421 _gdk_native_windows)
1423 g_warning ("Offscreen windows not supported with native-windows gdk");
1427 window = g_object_new (GDK_TYPE_WINDOW, NULL);
1428 private = (GdkWindowObject *) window;
1430 /* Windows with a foreign parent are treated as if they are children
1431 * of the root window, except for actual creation.
1433 real_parent = parent;
1434 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1435 parent = gdk_screen_get_root_window (screen);
1437 private->parent = (GdkWindowObject *)parent;
1439 private->accept_focus = TRUE;
1440 private->focus_on_map = TRUE;
1442 if (attributes_mask & GDK_WA_X)
1447 if (attributes_mask & GDK_WA_Y)
1454 private->width = (attributes->width > 1) ? (attributes->width) : (1);
1455 private->height = (attributes->height > 1) ? (attributes->height) : (1);
1457 #ifdef GDK_WINDOWING_X11
1458 /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1459 * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1461 if (attributes->wclass == GDK_INPUT_ONLY &&
1462 private->parent->window_type == GDK_WINDOW_ROOT &&
1463 !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1465 g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1466 attributes->wclass = GDK_INPUT_OUTPUT;
1470 if (attributes->wclass == GDK_INPUT_ONLY)
1472 /* Backwards compatiblity - we've always ignored
1473 * attributes->window_type for input-only windows
1476 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1477 private->window_type = GDK_WINDOW_TEMP;
1479 private->window_type = GDK_WINDOW_CHILD;
1482 private->window_type = attributes->window_type;
1485 switch (private->window_type)
1487 case GDK_WINDOW_TOPLEVEL:
1488 case GDK_WINDOW_DIALOG:
1489 case GDK_WINDOW_TEMP:
1490 case GDK_WINDOW_OFFSCREEN:
1491 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1492 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1493 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1494 case GDK_WINDOW_CHILD:
1498 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1502 if (attributes_mask & GDK_WA_VISUAL)
1503 visual = attributes->visual;
1505 visual = gdk_screen_get_system_visual (screen);
1507 private->event_mask = attributes->event_mask;
1509 if (attributes->wclass == GDK_INPUT_OUTPUT)
1511 private->input_only = FALSE;
1512 private->depth = visual->depth;
1514 private->bg_color.pixel = 0; /* TODO: BlackPixel (xdisplay, screen_x11->screen_num); */
1515 private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
1517 private->bg_pixmap = NULL;
1522 private->input_only = TRUE;
1525 if (private->parent)
1526 private->parent->children = g_list_prepend (private->parent->children, window);
1528 native = _gdk_native_windows; /* Default */
1529 if (private->parent->window_type == GDK_WINDOW_ROOT)
1530 native = TRUE; /* Always use native windows for toplevels */
1531 else if (!private->input_only &&
1532 ((attributes_mask & GDK_WA_COLORMAP &&
1533 attributes->colormap != gdk_drawable_get_colormap ((GdkDrawable *)private->parent)) ||
1534 (attributes_mask & GDK_WA_VISUAL &&
1535 attributes->visual != gdk_drawable_get_visual ((GdkDrawable *)private->parent))))
1536 native = TRUE; /* InputOutput window with different colormap or visual than parent, needs native window */
1538 if (gdk_window_is_offscreen (private))
1540 _gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask);
1541 private->impl_window = private;
1545 event_mask = get_native_event_mask (private);
1547 /* Create the impl */
1548 _gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask);
1549 private->impl_window = private;
1551 /* This will put the native window topmost in the native parent, which may
1552 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1553 if (!_gdk_window_has_impl (real_parent))
1554 sync_native_window_stack_position (window);
1558 private->impl_window = g_object_ref (private->parent->impl_window);
1559 private->impl = g_object_ref (private->impl_window->impl);
1562 recompute_visible_regions (private, TRUE, FALSE);
1564 if (private->parent->window_type != GDK_WINDOW_ROOT)
1566 /* Inherit redirection from parent */
1567 private->redirect = private->parent->redirect;
1570 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1571 (attributes->cursor) :
1574 private->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1575 (GDestroyNotify) gdk_cursor_unref);
1577 device_manager = gdk_display_get_device_manager (gdk_drawable_get_display (GDK_DRAWABLE (parent)));
1578 g_signal_connect (device_manager, "device-removed",
1579 G_CALLBACK (device_removed_cb), window);
1585 is_parent_of (GdkWindow *parent,
1596 w = gdk_window_get_parent (w);
1603 change_impl (GdkWindowObject *private,
1604 GdkWindowObject *impl_window,
1608 GdkWindowObject *child;
1609 GdkDrawable *old_impl;
1610 GdkWindowObject *old_impl_window;
1612 old_impl = private->impl;
1613 old_impl_window = private->impl_window;
1614 if (private != impl_window)
1615 private->impl_window = g_object_ref (impl_window);
1617 private->impl_window = private;
1618 private->impl = g_object_ref (new);
1619 if (old_impl_window != private)
1620 g_object_unref (old_impl_window);
1621 g_object_unref (old_impl);
1623 for (l = private->children; l != NULL; l = l->next)
1627 if (child->impl == old_impl)
1628 change_impl (child, impl_window, new);
1633 reparent_to_impl (GdkWindowObject *private)
1636 GdkWindowObject *child;
1638 GdkWindowImplIface *impl_iface;
1640 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1642 /* Enumerate in reverse order so we get the right order for the native
1643 windows (first in childrens list is topmost, and reparent places on top) */
1644 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1648 if (child->impl == private->impl)
1649 reparent_to_impl (child);
1652 show = impl_iface->reparent ((GdkWindow *)child,
1653 (GdkWindow *)private,
1654 child->x, child->y);
1656 gdk_window_show_unraised ((GdkWindow *)child);
1663 * gdk_window_reparent:
1664 * @window: a #GdkWindow
1665 * @new_parent: new parent to move @window into
1666 * @x: X location inside the new parent
1667 * @y: Y location inside the new parent
1669 * Reparents @window into the given @new_parent. The window being
1670 * reparented will be unmapped as a side effect.
1674 gdk_window_reparent (GdkWindow *window,
1675 GdkWindow *new_parent,
1679 GdkWindowObject *private;
1680 GdkWindowObject *new_parent_private;
1681 GdkWindowObject *old_parent;
1683 gboolean show, was_mapped, applied_clip_as_shape;
1684 gboolean do_reparent_to_impl;
1685 GdkEventMask old_native_event_mask;
1686 GdkWindowImplIface *impl_iface;
1688 g_return_if_fail (GDK_IS_WINDOW (window));
1689 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1690 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1692 if (GDK_WINDOW_DESTROYED (window) ||
1693 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1696 screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
1698 new_parent = gdk_screen_get_root_window (screen);
1700 private = (GdkWindowObject *) window;
1701 new_parent_private = (GdkWindowObject *)new_parent;
1703 /* No input-output children of input-only windows */
1704 if (new_parent_private->input_only && !private->input_only)
1707 /* Don't create loops in hierarchy */
1708 if (is_parent_of (window, new_parent))
1711 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1712 To make sure we're ok, just wipe it. */
1713 gdk_window_drop_cairo_surface (private);
1715 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1716 old_parent = private->parent;
1718 /* Break up redirection if inherited */
1719 if (private->redirect && private->redirect->redirected != private)
1721 remove_redirect_from_children (private, private->redirect);
1722 private->redirect = NULL;
1725 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1728 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1729 if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1730 new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1731 gdk_window_ensure_native (window);
1733 applied_clip_as_shape = should_apply_clip_as_shape (private);
1735 old_native_event_mask = 0;
1736 do_reparent_to_impl = FALSE;
1737 if (gdk_window_has_impl (private))
1739 old_native_event_mask = get_native_event_mask (private);
1741 show = impl_iface->reparent (window, new_parent, x, y);
1745 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1746 g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1747 new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1750 gdk_window_hide (window);
1752 do_reparent_to_impl = TRUE;
1753 change_impl (private,
1754 new_parent_private->impl_window,
1755 new_parent_private->impl);
1758 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1761 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1763 new_parent = gdk_screen_get_root_window (screen);
1764 new_parent_private = (GdkWindowObject *)new_parent;
1768 old_parent->children = g_list_remove (old_parent->children, window);
1770 private->parent = new_parent_private;
1774 new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1776 /* Switch the window type as appropriate */
1778 switch (GDK_WINDOW_TYPE (new_parent))
1780 case GDK_WINDOW_ROOT:
1781 case GDK_WINDOW_FOREIGN:
1782 if (private->toplevel_window_type != -1)
1783 GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1784 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1785 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1787 case GDK_WINDOW_OFFSCREEN:
1788 case GDK_WINDOW_TOPLEVEL:
1789 case GDK_WINDOW_CHILD:
1790 case GDK_WINDOW_DIALOG:
1791 case GDK_WINDOW_TEMP:
1792 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1793 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1795 /* Save the original window type so we can restore it if the
1796 * window is reparented back to be a toplevel
1798 private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1799 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1803 /* We might have changed window type for a native windows, so we
1804 need to change the event mask too. */
1805 if (gdk_window_has_impl (private))
1807 GdkEventMask native_event_mask = get_native_event_mask (private);
1809 if (native_event_mask != old_native_event_mask)
1810 impl_iface->set_events (window, native_event_mask);
1813 /* Inherit parent redirect if we don't have our own */
1814 if (private->parent && private->redirect == NULL)
1816 private->redirect = private->parent->redirect;
1817 apply_redirect_to_children (private, private->redirect);
1820 _gdk_window_update_viewable (window);
1822 recompute_visible_regions (private, TRUE, FALSE);
1823 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1824 recompute_visible_regions (old_parent, FALSE, TRUE);
1826 /* We used to apply the clip as the shape, but no more.
1827 Reset this to the real shape */
1828 if (gdk_window_has_impl (private) &&
1829 applied_clip_as_shape &&
1830 !should_apply_clip_as_shape (private))
1831 apply_shape (private, private->shape);
1833 if (do_reparent_to_impl)
1834 reparent_to_impl (private);
1837 /* The reparent will have put the native window topmost in the native parent,
1838 * which may be wrong wrt other native windows in the non-native hierarchy,
1840 if (!gdk_window_has_impl (new_parent_private))
1841 sync_native_window_stack_position (window);
1845 gdk_window_show_unraised (window);
1847 _gdk_synthesize_crossing_events_for_geometry_change (window);
1851 temporary_disable_extension_events (GdkWindowObject *window)
1853 GdkWindowObject *child;
1857 if (window->extension_events != 0)
1859 g_object_set_data (G_OBJECT (window),
1860 "gdk-window-extension-events",
1861 GINT_TO_POINTER (window->extension_events));
1862 gdk_input_set_extension_events ((GdkWindow *)window, 0,
1863 GDK_EXTENSION_EVENTS_NONE);
1868 for (l = window->children; l != NULL; l = l->next)
1872 if (window->impl_window == child->impl_window)
1873 res |= temporary_disable_extension_events (child);
1880 reenable_extension_events (GdkWindowObject *window)
1882 GdkWindowObject *child;
1886 mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1887 "gdk-window-extension-events"));
1891 /* We don't have the mode here, so we pass in cursor.
1892 This works with the current code since mode is not
1893 stored except as part of the mask, and cursor doesn't
1895 gdk_input_set_extension_events ((GdkWindow *)window, mask,
1896 GDK_EXTENSION_EVENTS_CURSOR);
1897 g_object_set_data (G_OBJECT (window),
1898 "gdk-window-extension-events",
1902 for (l = window->children; l != NULL; l = l->next)
1906 if (window->impl_window == child->impl_window)
1907 reenable_extension_events (window);
1912 * gdk_window_ensure_native:
1913 * @window: a #GdkWindow
1915 * Tries to ensure that there is a window-system native window for this
1916 * GdkWindow. This may fail in some situations, returning %FALSE.
1918 * Offscreen window and children of them can never have native windows.
1920 * Some backends may not support native child windows.
1922 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1927 gdk_window_ensure_native (GdkWindow *window)
1929 GdkWindowObject *private;
1930 GdkWindowObject *impl_window;
1931 GdkDrawable *new_impl, *old_impl;
1934 GdkWindowAttr attributes;
1935 GdkWindowObject *above;
1937 GdkWindowImplIface *impl_iface;
1938 gboolean disabled_extension_events;
1940 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1942 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1943 GDK_WINDOW_DESTROYED (window))
1946 private = (GdkWindowObject *) window;
1948 impl_window = gdk_window_get_impl_window (private);
1950 if (gdk_window_is_offscreen (impl_window))
1951 return FALSE; /* native in offscreens not supported */
1953 if (impl_window == private)
1954 /* Already has an impl, and its not offscreen . */
1957 /* Need to create a native window */
1959 /* First we disable any extension events on the window or its
1960 descendants to handle the native input window moving */
1961 disabled_extension_events = FALSE;
1962 if (impl_window->input_window)
1963 disabled_extension_events = temporary_disable_extension_events (private);
1965 gdk_window_drop_cairo_surface (private);
1967 screen = gdk_drawable_get_screen (window);
1968 visual = gdk_drawable_get_visual (window);
1970 attributes.colormap = gdk_drawable_get_colormap (window);
1972 old_impl = private->impl;
1973 _gdk_window_impl_new (window, (GdkWindow *)private->parent,
1975 get_native_event_mask (private),
1976 &attributes, GDK_WA_COLORMAP);
1977 new_impl = private->impl;
1979 private->impl = old_impl;
1980 change_impl (private, private, new_impl);
1982 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1984 /* Native window creation will put the native window topmost in the
1985 * native parent, which may be wrong wrt the position of the previous
1986 * non-native window wrt to the other non-native children, so correct this.
1988 above = find_native_sibling_above (private->parent, private);
1991 listhead.data = window;
1992 listhead.prev = NULL;
1993 listhead.next = NULL;
1994 impl_iface->restack_under ((GdkWindow *)above, &listhead);
1997 recompute_visible_regions (private, FALSE, FALSE);
1999 /* The shape may not have been set, as the clip region doesn't actually
2000 change, so do it here manually */
2001 if (should_apply_clip_as_shape (private))
2002 apply_clip_as_shape (private);
2004 reparent_to_impl (private);
2006 if (!private->input_only)
2008 impl_iface->set_background (window, &private->bg_color);
2009 if (private->bg_pixmap != NULL)
2010 impl_iface->set_back_pixmap (window, private->bg_pixmap);
2013 impl_iface->input_shape_combine_region (window,
2014 private->input_shape,
2017 if (gdk_window_is_viewable (window))
2018 impl_iface->show (window, FALSE);
2020 if (disabled_extension_events)
2021 reenable_extension_events (private);
2027 window_remove_filters (GdkWindow *window)
2029 GdkWindowObject *obj = (GdkWindowObject*) window;
2035 for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
2036 g_free (tmp_list->data);
2038 g_list_free (obj->filters);
2039 obj->filters = NULL;
2044 update_pointer_info_foreach (GdkDisplay *display,
2046 GdkPointerWindowInfo *pointer_info,
2049 GdkWindow *window = user_data;
2051 if (pointer_info->toplevel_under_pointer == window)
2053 g_object_unref (pointer_info->toplevel_under_pointer);
2054 pointer_info->toplevel_under_pointer = NULL;
2059 window_remove_from_pointer_info (GdkWindow *window,
2060 GdkDisplay *display)
2062 _gdk_display_pointer_info_foreach (display,
2063 update_pointer_info_foreach,
2068 * _gdk_window_destroy_hierarchy:
2069 * @window: a #GdkWindow
2070 * @recursing: If TRUE, then this is being called because a parent
2072 * @recursing_native: If TRUE, then this is being called because a native parent
2073 * was destroyed. This generally means that the call to the
2074 * windowing system to destroy the window can be omitted, since
2075 * it will be destroyed as a result of the parent being destroyed.
2076 * Unless @foreign_destroy.
2077 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2078 * external agency. The window has already been destroyed and no
2079 * windowing system calls should be made. (This may never happen
2080 * for some windowing systems.)
2082 * Internal function to destroy a window. Like gdk_window_destroy(),
2083 * but does not drop the reference count created by gdk_window_new().
2086 _gdk_window_destroy_hierarchy (GdkWindow *window,
2088 gboolean recursing_native,
2089 gboolean foreign_destroy)
2091 GdkWindowObject *private;
2092 GdkWindowObject *temp_private;
2093 GdkWindowImplIface *impl_iface;
2094 GdkWindow *temp_window;
2096 GdkDisplay *display;
2100 g_return_if_fail (GDK_IS_WINDOW (window));
2102 private = (GdkWindowObject*) window;
2104 if (GDK_WINDOW_DESTROYED (window))
2107 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
2108 screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
2109 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
2110 if (temp_window == window)
2111 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
2114 switch (private->window_type)
2116 case GDK_WINDOW_ROOT:
2117 if (!screen->closed)
2119 g_error ("attempted to destroy root window");
2122 /* else fall thru */
2123 case GDK_WINDOW_TOPLEVEL:
2124 case GDK_WINDOW_CHILD:
2125 case GDK_WINDOW_DIALOG:
2126 case GDK_WINDOW_TEMP:
2127 case GDK_WINDOW_FOREIGN:
2128 case GDK_WINDOW_OFFSCREEN:
2129 if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
2131 /* Logically, it probably makes more sense to send
2132 * a "destroy yourself" message to the foreign window
2133 * whether or not it's in our hierarchy; but for historical
2134 * reasons, we only send "destroy yourself" messages to
2135 * foreign windows in our hierarchy.
2137 if (private->parent)
2138 _gdk_windowing_window_destroy_foreign (window);
2140 /* Also for historical reasons, we remove any filters
2141 * on a foreign window when it or a parent is destroyed;
2142 * this likely causes problems if two separate portions
2143 * of code are maintaining filter lists on a foreign window.
2145 window_remove_filters (window);
2149 if (private->parent)
2151 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
2153 if (parent_private->children)
2154 parent_private->children = g_list_remove (parent_private->children, window);
2157 GDK_WINDOW_IS_MAPPED (window))
2159 recompute_visible_regions (private, TRUE, FALSE);
2160 gdk_window_invalidate_in_parent (private);
2164 gdk_window_free_paint_stack (window);
2166 if (private->bg_pixmap &&
2167 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2168 private->bg_pixmap != GDK_NO_BG)
2170 g_object_unref (private->bg_pixmap);
2171 private->bg_pixmap = NULL;
2174 if (private->window_type == GDK_WINDOW_FOREIGN)
2175 g_assert (private->children == NULL);
2178 children = tmp = private->children;
2179 private->children = NULL;
2183 temp_window = tmp->data;
2186 temp_private = (GdkWindowObject*) temp_window;
2188 _gdk_window_destroy_hierarchy (temp_window,
2190 recursing_native || gdk_window_has_impl (private),
2194 g_list_free (children);
2197 _gdk_window_clear_update_area (window);
2199 gdk_window_drop_cairo_surface (private);
2201 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2203 if (gdk_window_has_impl (private))
2204 impl_iface->destroy (window, recursing_native,
2208 /* hide to make sure we repaint and break grabs */
2209 gdk_window_hide (window);
2212 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2213 private->parent = NULL;
2214 private->destroyed = TRUE;
2216 window_remove_filters (window);
2218 gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
2220 /* If we own the redirect, free it */
2221 if (private->redirect && private->redirect->redirected == private)
2222 gdk_window_redirect_free (private->redirect);
2224 private->redirect = NULL;
2226 window_remove_from_pointer_info (window, display);
2228 if (private->clip_region)
2230 gdk_region_destroy (private->clip_region);
2231 private->clip_region = NULL;
2234 if (private->clip_region_with_children)
2236 gdk_region_destroy (private->clip_region_with_children);
2237 private->clip_region_with_children = NULL;
2240 if (private->outstanding_moves)
2242 g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2243 g_list_free (private->outstanding_moves);
2244 private->outstanding_moves = NULL;
2252 * _gdk_window_destroy:
2253 * @window: a #GdkWindow
2254 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2255 * external agency. The window has already been destroyed and no
2256 * windowing system calls should be made. (This may never happen
2257 * for some windowing systems.)
2259 * Internal function to destroy a window. Like gdk_window_destroy(),
2260 * but does not drop the reference count created by gdk_window_new().
2263 _gdk_window_destroy (GdkWindow *window,
2264 gboolean foreign_destroy)
2266 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2270 * gdk_window_destroy:
2271 * @window: a #GdkWindow
2273 * Destroys the window system resources associated with @window and decrements @window's
2274 * reference count. The window system resources for all children of @window are also
2275 * destroyed, but the children's reference counts are not decremented.
2277 * Note that a window will not be destroyed automatically when its reference count
2278 * reaches zero. You must call this function yourself before that happens.
2282 gdk_window_destroy (GdkWindow *window)
2284 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2285 g_object_unref (window);
2289 * gdk_window_set_user_data:
2290 * @window: a #GdkWindow
2291 * @user_data: user data
2293 * For most purposes this function is deprecated in favor of
2294 * g_object_set_data(). However, for historical reasons GTK+ stores
2295 * the #GtkWidget that owns a #GdkWindow as user data on the
2296 * #GdkWindow. So, custom widget implementations should use
2297 * this function for that. If GTK+ receives an event for a #GdkWindow,
2298 * and the user data for the window is non-%NULL, GTK+ will assume the
2299 * user data is a #GtkWidget, and forward the event to that widget.
2303 gdk_window_set_user_data (GdkWindow *window,
2306 g_return_if_fail (GDK_IS_WINDOW (window));
2308 ((GdkWindowObject*)window)->user_data = user_data;
2312 * gdk_window_get_user_data:
2313 * @window: a #GdkWindow
2314 * @data: return location for user data
2316 * Retrieves the user data for @window, which is normally the widget
2317 * that @window belongs to. See gdk_window_set_user_data().
2321 gdk_window_get_user_data (GdkWindow *window,
2324 g_return_if_fail (GDK_IS_WINDOW (window));
2326 *data = ((GdkWindowObject*)window)->user_data;
2330 * gdk_window_get_window_type:
2331 * @window: a #GdkWindow
2333 * Gets the type of the window. See #GdkWindowType.
2335 * Return value: type of window
2338 gdk_window_get_window_type (GdkWindow *window)
2340 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2342 return GDK_WINDOW_TYPE (window);
2346 * gdk_window_is_destroyed:
2347 * @window: a #GdkWindow
2349 * Check to see if a window is destroyed..
2351 * Return value: %TRUE if the window is destroyed
2356 gdk_window_is_destroyed (GdkWindow *window)
2358 return GDK_WINDOW_DESTROYED (window);
2362 to_embedder (GdkWindowObject *window,
2363 gdouble offscreen_x,
2364 gdouble offscreen_y,
2365 gdouble *embedder_x,
2366 gdouble *embedder_y)
2368 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2369 offscreen_x, offscreen_y,
2370 embedder_x, embedder_y);
2374 from_embedder (GdkWindowObject *window,
2377 gdouble *offscreen_x,
2378 gdouble *offscreen_y)
2380 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2381 embedder_x, embedder_y,
2382 offscreen_x, offscreen_y);
2386 * gdk_window_get_position:
2387 * @window: a #GdkWindow
2388 * @x: X coordinate of window
2389 * @y: Y coordinate of window
2391 * Obtains the position of the window as reported in the
2392 * most-recently-processed #GdkEventConfigure. Contrast with
2393 * gdk_window_get_geometry() which queries the X server for the
2394 * current window position, regardless of which events have been
2395 * received or processed.
2397 * The position coordinates are relative to the window's parent window.
2401 gdk_window_get_position (GdkWindow *window,
2405 GdkWindowObject *obj;
2407 g_return_if_fail (GDK_IS_WINDOW (window));
2409 obj = (GdkWindowObject*) window;
2418 * gdk_window_get_parent:
2419 * @window: a #GdkWindow
2421 * Obtains the parent of @window, as known to GDK. Does not query the
2422 * X server; thus this returns the parent as passed to gdk_window_new(),
2423 * not the actual parent. This should never matter unless you're using
2424 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2425 * matter for toplevel windows, because the window manager may choose
2428 * Note that you should use gdk_window_get_effective_parent() when
2429 * writing generic code that walks up a window hierarchy, because
2430 * gdk_window_get_parent() will most likely not do what you expect if
2431 * there are offscreen windows in the hierarchy.
2433 * Return value: parent of @window
2436 gdk_window_get_parent (GdkWindow *window)
2438 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2440 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2444 * gdk_window_get_effective_parent:
2445 * @window: a #GdkWindow
2447 * Obtains the parent of @window, as known to GDK. Works like
2448 * gdk_window_get_parent() for normal windows, but returns the
2449 * window's embedder for offscreen windows.
2451 * See also: gdk_offscreen_window_get_embedder()
2453 * Return value: effective parent of @window
2458 gdk_window_get_effective_parent (GdkWindow *window)
2460 GdkWindowObject *obj;
2462 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2464 obj = (GdkWindowObject *)window;
2466 if (gdk_window_is_offscreen (obj))
2467 return gdk_offscreen_window_get_embedder (window);
2469 return (GdkWindow *) obj->parent;
2473 * gdk_window_get_toplevel:
2474 * @window: a #GdkWindow
2476 * Gets the toplevel window that's an ancestor of @window.
2478 * Any window type but %GDK_WINDOW_CHILD is considered a
2479 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2480 * has a root window as parent.
2482 * Note that you should use gdk_window_get_effective_toplevel() when
2483 * you want to get to a window's toplevel as seen on screen, because
2484 * gdk_window_get_toplevel() will most likely not do what you expect
2485 * if there are offscreen windows in the hierarchy.
2487 * Return value: the toplevel window containing @window
2490 gdk_window_get_toplevel (GdkWindow *window)
2492 GdkWindowObject *obj;
2494 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2496 obj = (GdkWindowObject *)window;
2498 while (obj->window_type == GDK_WINDOW_CHILD)
2500 if (gdk_window_is_toplevel (obj))
2505 return GDK_WINDOW (obj);
2509 * gdk_window_get_effective_toplevel:
2510 * @window: a #GdkWindow
2512 * Gets the toplevel window that's an ancestor of @window.
2514 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2515 * embedder as its parent, using gdk_window_get_effective_parent().
2517 * See also: gdk_offscreen_window_get_embedder()
2519 * Return value: the effective toplevel window containing @window
2524 gdk_window_get_effective_toplevel (GdkWindow *window)
2528 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2530 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2531 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2538 * gdk_window_get_children:
2539 * @window: a #GdkWindow
2541 * Gets the list of children of @window known to GDK.
2542 * This function only returns children created via GDK,
2543 * so for example it's useless when used with the root window;
2544 * it only returns windows an application created itself.
2546 * The returned list must be freed, but the elements in the
2549 * Return value: list of child windows inside @window
2552 gdk_window_get_children (GdkWindow *window)
2554 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2556 if (GDK_WINDOW_DESTROYED (window))
2559 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2563 * gdk_window_peek_children:
2564 * @window: a #GdkWindow
2566 * Like gdk_window_get_children(), but does not copy the list of
2567 * children, so the list does not need to be freed.
2569 * Return value: a reference to the list of child windows in @window
2572 gdk_window_peek_children (GdkWindow *window)
2574 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2576 if (GDK_WINDOW_DESTROYED (window))
2579 return GDK_WINDOW_OBJECT (window)->children;
2583 * gdk_window_add_filter:
2584 * @window: a #GdkWindow
2585 * @function: filter callback
2586 * @data: data to pass to filter callback
2588 * Adds an event filter to @window, allowing you to intercept events
2589 * before they reach GDK. This is a low-level operation and makes it
2590 * easy to break GDK and/or GTK+, so you have to know what you're
2591 * doing. Pass %NULL for @window to get all events for all windows,
2592 * instead of events for a specific window.
2594 * See gdk_display_add_client_message_filter() if you are interested
2595 * in X ClientMessage events.
2598 gdk_window_add_filter (GdkWindow *window,
2599 GdkFilterFunc function,
2602 GdkWindowObject *private;
2604 GdkEventFilter *filter;
2606 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2608 private = (GdkWindowObject*) window;
2609 if (private && GDK_WINDOW_DESTROYED (window))
2612 /* Filters are for the native events on the native window, so
2613 ensure there is a native window. */
2615 gdk_window_ensure_native (window);
2618 tmp_list = private->filters;
2620 tmp_list = _gdk_default_filters;
2624 filter = (GdkEventFilter *)tmp_list->data;
2625 if ((filter->function == function) && (filter->data == data))
2627 tmp_list = tmp_list->next;
2630 filter = g_new (GdkEventFilter, 1);
2631 filter->function = function;
2632 filter->data = data;
2635 private->filters = g_list_append (private->filters, filter);
2637 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2641 * gdk_window_remove_filter:
2642 * @window: a #GdkWindow
2643 * @function: previously-added filter function
2644 * @data: user data for previously-added filter function
2646 * Remove a filter previously added with gdk_window_add_filter().
2650 gdk_window_remove_filter (GdkWindow *window,
2651 GdkFilterFunc function,
2654 GdkWindowObject *private;
2655 GList *tmp_list, *node;
2656 GdkEventFilter *filter;
2658 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2660 private = (GdkWindowObject*) window;
2663 tmp_list = private->filters;
2665 tmp_list = _gdk_default_filters;
2669 filter = (GdkEventFilter *)tmp_list->data;
2671 tmp_list = tmp_list->next;
2673 if ((filter->function == function) && (filter->data == data))
2676 private->filters = g_list_remove_link (private->filters, node);
2678 _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
2679 g_list_free_1 (node);
2688 * gdk_screen_get_toplevel_windows:
2689 * @screen: The #GdkScreen where the toplevels are located.
2691 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2692 * A toplevel window is a child of the root window (see
2693 * gdk_get_default_root_window()).
2695 * The returned list should be freed with g_list_free(), but
2696 * its elements need not be freed.
2698 * Return value: list of toplevel windows, free with g_list_free()
2703 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2705 GdkWindow * root_window;
2706 GList *new_list = NULL;
2709 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2711 root_window = gdk_screen_get_root_window (screen);
2713 tmp_list = ((GdkWindowObject *)root_window)->children;
2716 GdkWindowObject *w = tmp_list->data;
2718 if (w->window_type != GDK_WINDOW_FOREIGN)
2719 new_list = g_list_prepend (new_list, w);
2720 tmp_list = tmp_list->next;
2727 * gdk_window_is_visible:
2728 * @window: a #GdkWindow
2730 * Checks whether the window has been mapped (with gdk_window_show() or
2731 * gdk_window_show_unraised()).
2733 * Return value: %TRUE if the window is mapped
2736 gdk_window_is_visible (GdkWindow *window)
2738 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2740 return GDK_WINDOW_IS_MAPPED (window);
2744 * gdk_window_is_viewable:
2745 * @window: a #GdkWindow
2747 * Check if the window and all ancestors of the window are
2748 * mapped. (This is not necessarily "viewable" in the X sense, since
2749 * we only check as far as we have GDK window parents, not to the root
2752 * Return value: %TRUE if the window is viewable
2755 gdk_window_is_viewable (GdkWindow *window)
2757 GdkWindowObject *private = (GdkWindowObject *)window;
2759 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2761 if (private->destroyed)
2764 return private->viewable;
2768 * gdk_window_get_state:
2769 * @window: a #GdkWindow
2771 * Gets the bitwise OR of the currently active window state flags,
2772 * from the #GdkWindowState enumeration.
2774 * Return value: window state bitfield
2777 gdk_window_get_state (GdkWindow *window)
2779 GdkWindowObject *private = (GdkWindowObject *)window;
2781 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2783 return private->state;
2787 /* This creates an empty "implicit" paint region for the impl window.
2788 * By itself this does nothing, but real paints to this window
2789 * or children of it can use this pixmap as backing to avoid allocating
2790 * multiple pixmaps for subwindow rendering. When doing so they
2791 * add to the region of the implicit paint region, which will be
2792 * pushed to the window when the implicit paint region is ended.
2793 * Such paints should not copy anything to the window on paint end, but
2794 * should rely on the implicit paint end.
2795 * The implicit paint will be automatically ended if someone draws
2796 * directly to the window or a child window.
2799 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2801 GdkWindowObject *private = (GdkWindowObject *)window;
2802 GdkWindowPaint *paint;
2804 g_assert (gdk_window_has_impl (private));
2806 if (_gdk_native_windows)
2807 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2809 if (GDK_IS_PAINTABLE (private->impl))
2810 return FALSE; /* Implementation does double buffering */
2812 if (private->paint_stack != NULL ||
2813 private->implicit_paint != NULL)
2814 return FALSE; /* Don't stack implicit paints */
2816 if (private->outstanding_surfaces != 0)
2817 return FALSE; /* May conflict with direct drawing to cairo surface */
2819 /* Never do implicit paints for foreign windows, they don't need
2820 * double buffer combination since they have no client side children,
2821 * and creating pixmaps for them is risky since they could disappear
2824 if (private->window_type == GDK_WINDOW_FOREIGN)
2827 paint = g_new (GdkWindowPaint, 1);
2828 paint->region = gdk_region_new (); /* Empty */
2829 paint->x_offset = rect->x;
2830 paint->y_offset = rect->y;
2831 paint->uses_implicit = FALSE;
2832 paint->flushed = FALSE;
2833 paint->surface = NULL;
2835 gdk_pixmap_new (window,
2836 MAX (rect->width, 1), MAX (rect->height, 1), -1);
2838 private->implicit_paint = paint;
2843 /* Ensure that all content related to this (sub)window is pushed to the
2844 native region. If there is an active paint then that area is not
2845 pushed, in order to not show partially finished double buffers. */
2847 gdk_window_flush_implicit_paint (GdkWindow *window)
2849 GdkWindowObject *private = (GdkWindowObject *)window;
2850 GdkWindowObject *impl_window;
2851 GdkWindowPaint *paint;
2856 impl_window = gdk_window_get_impl_window (private);
2857 if (impl_window->implicit_paint == NULL)
2860 paint = impl_window->implicit_paint;
2861 paint->flushed = TRUE;
2862 region = gdk_region_copy (private->clip_region_with_children);
2864 /* Don't flush active double buffers, as that may show partially done
2866 for (list = private->paint_stack; list != NULL; list = list->next)
2868 GdkWindowPaint *tmp_paint = list->data;
2870 gdk_region_subtract (region, tmp_paint->region);
2873 gdk_region_offset (region, private->abs_x, private->abs_y);
2874 gdk_region_intersect (region, paint->region);
2876 if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (region))
2878 /* Remove flushed region from the implicit paint */
2879 gdk_region_subtract (paint->region, region);
2881 /* Some regions are valid, push these to window now */
2882 tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE);
2883 _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE);
2884 gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
2885 0, 0, paint->x_offset, paint->y_offset, -1, -1);
2886 /* Reset clip region of the cached GdkGC */
2887 gdk_gc_set_clip_region (tmp_gc, NULL);
2890 gdk_region_destroy (region);
2893 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2895 gdk_window_end_implicit_paint (GdkWindow *window)
2897 GdkWindowObject *private = (GdkWindowObject *)window;
2898 GdkWindowPaint *paint;
2901 g_assert (gdk_window_has_impl (private));
2903 g_assert (private->implicit_paint != NULL);
2905 paint = private->implicit_paint;
2907 private->implicit_paint = NULL;
2909 if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (paint->region))
2911 /* Some regions are valid, push these to window now */
2912 tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE);
2913 _gdk_gc_set_clip_region_internal (tmp_gc, paint->region, TRUE);
2914 gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
2915 0, 0, paint->x_offset, paint->y_offset, -1, -1);
2916 /* Reset clip region of the cached GdkGC */
2917 gdk_gc_set_clip_region (tmp_gc, NULL);
2920 gdk_region_destroy (paint->region);
2922 g_object_unref (paint->pixmap);
2927 * gdk_window_begin_paint_rect:
2928 * @window: a #GdkWindow
2929 * @rectangle: rectangle you intend to draw to
2931 * A convenience wrapper around gdk_window_begin_paint_region() which
2932 * creates a rectangular region for you. See
2933 * gdk_window_begin_paint_region() for details.
2937 gdk_window_begin_paint_rect (GdkWindow *window,
2938 const GdkRectangle *rectangle)
2942 g_return_if_fail (GDK_IS_WINDOW (window));
2944 region = gdk_region_rectangle (rectangle);
2945 gdk_window_begin_paint_region (window, region);
2946 gdk_region_destroy (region);
2950 * gdk_window_begin_paint_region:
2951 * @window: a #GdkWindow
2952 * @region: region you intend to draw to
2954 * Indicates that you are beginning the process of redrawing @region.
2955 * A backing store (offscreen buffer) large enough to contain @region
2956 * will be created. The backing store will be initialized with the
2957 * background color or background pixmap for @window. Then, all
2958 * drawing operations performed on @window will be diverted to the
2959 * backing store. When you call gdk_window_end_paint(), the backing
2960 * store will be copied to @window, making it visible onscreen. Only
2961 * the part of @window contained in @region will be modified; that is,
2962 * drawing operations are clipped to @region.
2964 * The net result of all this is to remove flicker, because the user
2965 * sees the finished product appear all at once when you call
2966 * gdk_window_end_paint(). If you draw to @window directly without
2967 * calling gdk_window_begin_paint_region(), the user may see flicker
2968 * as individual drawing operations are performed in sequence. The
2969 * clipping and background-initializing features of
2970 * gdk_window_begin_paint_region() are conveniences for the
2971 * programmer, so you can avoid doing that work yourself.
2973 * When using GTK+, the widget system automatically places calls to
2974 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2975 * emissions of the expose_event signal. That is, if you're writing an
2976 * expose event handler, you can assume that the exposed area in
2977 * #GdkEventExpose has already been cleared to the window background,
2978 * is already set as the clip region, and already has a backing store.
2979 * Therefore in most cases, application code need not call
2980 * gdk_window_begin_paint_region(). (You can disable the automatic
2981 * calls around expose events on a widget-by-widget basis by calling
2982 * gtk_widget_set_double_buffered().)
2984 * If you call this function multiple times before calling the
2985 * matching gdk_window_end_paint(), the backing stores are pushed onto
2986 * a stack. gdk_window_end_paint() copies the topmost backing store
2987 * onscreen, subtracts the topmost region from all other regions in
2988 * the stack, and pops the stack. All drawing operations affect only
2989 * the topmost backing store in the stack. One matching call to
2990 * gdk_window_end_paint() is required for each call to
2991 * gdk_window_begin_paint_region().
2995 gdk_window_begin_paint_region (GdkWindow *window,
2996 const GdkRegion *region)
2998 #ifdef USE_BACKING_STORE
2999 GdkWindowObject *private = (GdkWindowObject *)window;
3000 GdkRectangle clip_box;
3001 GdkWindowPaint *paint, *implicit_paint;
3002 GdkWindowObject *impl_window;
3005 g_return_if_fail (GDK_IS_WINDOW (window));
3007 if (GDK_WINDOW_DESTROYED (window))
3010 if (GDK_IS_PAINTABLE (private->impl))
3012 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3014 if (iface->begin_paint_region)
3015 iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
3020 impl_window = gdk_window_get_impl_window (private);
3021 implicit_paint = impl_window->implicit_paint;
3023 paint = g_new (GdkWindowPaint, 1);
3024 paint->region = gdk_region_copy (region);
3025 paint->region_tag = new_region_tag ();
3027 gdk_region_intersect (paint->region, private->clip_region_with_children);
3028 gdk_region_get_clipbox (paint->region, &clip_box);
3030 /* Convert to impl coords */
3031 gdk_region_offset (paint->region, private->abs_x, private->abs_y);
3033 /* Mark the region as valid on the implicit paint */
3036 gdk_region_union (implicit_paint->region, paint->region);
3038 /* Convert back to normal coords */
3039 gdk_region_offset (paint->region, -private->abs_x, -private->abs_y);
3045 paint->uses_implicit = TRUE;
3046 paint->pixmap = g_object_ref (implicit_paint->pixmap);
3047 paint->x_offset = -private->abs_x + implicit_paint->x_offset;
3048 paint->y_offset = -private->abs_y + implicit_paint->y_offset;
3050 gdk_drawable_get_size (paint->pixmap, &width, &height);
3051 paint->surface = _gdk_drawable_create_cairo_surface (paint->pixmap, width, height);
3055 paint->uses_implicit = FALSE;
3056 paint->x_offset = clip_box.x;
3057 paint->y_offset = clip_box.y;
3059 gdk_pixmap_new (window,
3060 MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1);
3061 paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap);
3065 cairo_surface_set_device_offset (paint->surface,
3066 -paint->x_offset, -paint->y_offset);
3068 for (list = private->paint_stack; list != NULL; list = list->next)
3070 GdkWindowPaint *tmp_paint = list->data;
3072 gdk_region_subtract (tmp_paint->region, paint->region);
3075 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
3077 if (!gdk_region_empty (paint->region))
3079 gdk_window_clear_backing_region (window,
3083 #endif /* USE_BACKING_STORE */
3087 setup_redirect_clip (GdkWindow *window,
3092 GdkWindowObject *private = (GdkWindowObject *)window;
3093 GdkRegion *visible_region;
3094 GdkRectangle dest_rect;
3096 GdkWindow *toplevel;
3097 int x_offset, y_offset;
3099 toplevel = GDK_WINDOW (private->redirect->redirected);
3101 /* Get the clip region for gc clip rect + window hierarchy in
3102 window relative coords */
3104 _gdk_window_calculate_full_clip_region (window, toplevel,
3109 /* Compensate for the source pos/size */
3110 x_offset -= private->redirect->src_x;
3111 y_offset -= private->redirect->src_y;
3112 dest_rect.x = -x_offset;
3113 dest_rect.y = -y_offset;
3114 dest_rect.width = private->redirect->width;
3115 dest_rect.height = private->redirect->height;
3116 tmpreg = gdk_region_rectangle (&dest_rect);
3117 gdk_region_intersect (visible_region, tmpreg);
3118 gdk_region_destroy (tmpreg);
3120 /* Compensate for the dest pos */
3121 x_offset += private->redirect->dest_x;
3122 y_offset += private->redirect->dest_y;
3124 gdk_gc_set_clip_region (gc, visible_region); /* This resets clip origin! */
3126 /* offset clip and tiles from window coords to pixmaps coords */
3127 gdk_gc_offset (gc, -x_offset, -y_offset);
3129 gdk_region_destroy (visible_region);
3131 *x_offset_out = x_offset;
3132 *y_offset_out = y_offset;
3136 * gdk_window_end_paint:
3137 * @window: a #GdkWindow
3139 * Indicates that the backing store created by the most recent call to
3140 * gdk_window_begin_paint_region() should be copied onscreen and
3141 * deleted, leaving the next-most-recent backing store or no backing
3142 * store at all as the active paint region. See
3143 * gdk_window_begin_paint_region() for full details. It is an error to
3144 * call this function without a matching
3145 * gdk_window_begin_paint_region() first.
3149 gdk_window_end_paint (GdkWindow *window)
3151 #ifdef USE_BACKING_STORE
3152 GdkWindowObject *private = (GdkWindowObject *)window;
3153 GdkWindowObject *composited;
3154 GdkWindowPaint *paint;
3156 GdkRectangle clip_box;
3157 gint x_offset, y_offset;
3158 GdkRegion *full_clip;
3160 g_return_if_fail (GDK_IS_WINDOW (window));
3162 if (GDK_WINDOW_DESTROYED (window))
3165 if (GDK_IS_PAINTABLE (private->impl))
3167 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3169 if (iface->end_paint)
3170 iface->end_paint ((GdkPaintable*)private->impl);
3174 if (private->paint_stack == NULL)
3176 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3180 paint = private->paint_stack->data;
3182 private->paint_stack = g_slist_delete_link (private->paint_stack,
3183 private->paint_stack);
3185 gdk_region_get_clipbox (paint->region, &clip_box);
3187 tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE);
3189 x_offset = -private->abs_x;
3190 y_offset = -private->abs_y;
3192 if (!paint->uses_implicit)
3194 gdk_window_flush_outstanding_moves (window);
3196 full_clip = gdk_region_copy (private->clip_region_with_children);
3197 gdk_region_intersect (full_clip, paint->region);
3198 _gdk_gc_set_clip_region_internal (tmp_gc, full_clip, TRUE); /* Takes ownership of full_clip */
3199 gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset);
3200 gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
3201 clip_box.x - paint->x_offset,
3202 clip_box.y - paint->y_offset,
3203 clip_box.x - x_offset, clip_box.y - y_offset,
3204 clip_box.width, clip_box.height);
3207 if (private->redirect)
3209 int x_offset, y_offset;
3211 /* TODO: Should also use paint->region for clipping */
3212 setup_redirect_clip (window, tmp_gc, &x_offset, &y_offset);
3213 gdk_draw_drawable (private->redirect->pixmap, tmp_gc, paint->pixmap,
3214 clip_box.x - paint->x_offset,
3215 clip_box.y - paint->y_offset,
3216 clip_box.x + x_offset,
3217 clip_box.y + y_offset,
3218 clip_box.width, clip_box.height);
3221 /* Reset clip region of the cached GdkGC */
3222 gdk_gc_set_clip_region (tmp_gc, NULL);
3224 cairo_surface_destroy (paint->surface);
3225 g_object_unref (paint->pixmap);
3226 gdk_region_destroy (paint->region);
3229 /* find a composited window in our hierarchy to signal its
3230 * parent to redraw, calculating the clip box as we go...
3232 * stop if parent becomes NULL since then we'd have nowhere
3233 * to draw (ie: 'composited' will always be non-NULL here).
3235 for (composited = private;
3237 composited = composited->parent)
3241 gdk_drawable_get_size (GDK_DRAWABLE (composited->parent),
3244 clip_box.x += composited->x;
3245 clip_box.y += composited->y;
3246 clip_box.width = MIN (clip_box.width, width - clip_box.x);
3247 clip_box.height = MIN (clip_box.height, height - clip_box.y);
3249 if (composited->composited)
3251 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3256 #endif /* USE_BACKING_STORE */
3260 gdk_window_free_paint_stack (GdkWindow *window)
3262 GdkWindowObject *private = (GdkWindowObject *)window;
3264 if (private->paint_stack)
3266 GSList *tmp_list = private->paint_stack;
3270 GdkWindowPaint *paint = tmp_list->data;
3272 if (tmp_list == private->paint_stack)
3273 g_object_unref (paint->pixmap);
3275 gdk_region_destroy (paint->region);
3278 tmp_list = tmp_list->next;
3281 g_slist_free (private->paint_stack);
3282 private->paint_stack = NULL;
3287 do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3288 GdkRegion *dest_region, /* In impl window coords */
3292 GdkRectangle copy_rect;
3293 GdkWindowObject *private;
3294 GdkWindowImplIface *impl_iface;
3296 /* We need to get data from subwindows here, because we might have
3297 * shaped a native window over the moving region (with bg none,
3298 * so the pixels are still there). In fact we might need to get data
3299 * from overlapping native window that are not children of this window,
3300 * so we copy from the toplevel with INCLUDE_INFERIORS.
3302 private = impl_window;
3303 while (!gdk_window_is_toplevel (private))
3305 dx -= private->parent->abs_x + private->x;
3306 dy -= private->parent->abs_y + private->y;
3307 private = gdk_window_get_impl_window (private->parent);
3309 tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private);
3311 gdk_region_get_clipbox (dest_region, ©_rect);
3312 gdk_gc_set_clip_region (tmp_gc, dest_region);
3314 /* The region area is moved and we queue translations for all expose events
3315 to the source area that were sent prior to the copy */
3316 gdk_region_offset (dest_region, -dx, -dy); /* Move to source region */
3317 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
3319 impl_iface->queue_translation ((GdkWindow *)impl_window,
3321 dest_region, dx, dy);
3323 gdk_draw_drawable (impl_window->impl,
3326 copy_rect.x-dx, copy_rect.y-dy,
3327 copy_rect.x, copy_rect.y,
3328 copy_rect.width, copy_rect.height);
3329 gdk_gc_set_clip_region (tmp_gc, NULL);
3332 static GdkWindowRegionMove *
3333 gdk_window_region_move_new (GdkRegion *region,
3336 GdkWindowRegionMove *move;
3338 move = g_slice_new (GdkWindowRegionMove);
3339 move->dest_region = gdk_region_copy (region);
3347 gdk_window_region_move_free (GdkWindowRegionMove *move)
3349 gdk_region_destroy (move->dest_region);
3350 g_slice_free (GdkWindowRegionMove, move);
3354 append_move_region (GdkWindowObject *impl_window,
3355 GdkRegion *new_dest_region,
3358 GdkWindowRegionMove *move, *old_move;
3359 GdkRegion *new_total_region, *old_total_region;
3360 GdkRegion *source_overlaps_destination;
3361 GdkRegion *non_overwritten;
3362 gboolean added_move;
3365 if (gdk_region_empty (new_dest_region))
3368 /* In principle this could just append the move to the list of outstanding
3369 moves that will be replayed before drawing anything when we're handling
3370 exposes. However, we'd like to do a bit better since its commonly the case
3371 that we get multiple copies where A is copied to B and then B is copied
3372 to C, and we'd like to express this as a simple copy A to C operation. */
3374 /* We approach this by taking the new move and pushing it ahead of moves
3375 starting at the end of the list and stopping when its not safe to do so.
3376 It's not safe to push past a move if either the source of the new move
3377 is in the destination of the old move, or if the destination of the new
3378 move is in the source of the new move, or if the destination of the new
3379 move overlaps the destination of the old move. We simplify this by
3380 just comparing the total regions (src + dest) */
3381 new_total_region = gdk_region_copy (new_dest_region);
3382 gdk_region_offset (new_total_region, -dx, -dy);
3383 gdk_region_union (new_total_region, new_dest_region);
3386 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3391 old_total_region = gdk_region_copy (old_move->dest_region);
3392 gdk_region_offset (old_total_region, -old_move->dx, -old_move->dy);
3393 gdk_region_union (old_total_region, old_move->dest_region);
3395 gdk_region_intersect (old_total_region, new_total_region);
3396 /* If these regions intersect then its not safe to push the
3397 new region before the old one */
3398 if (!gdk_region_empty (old_total_region))
3400 /* The area where the new moves source overlaps the old ones
3402 source_overlaps_destination = gdk_region_copy (new_dest_region);
3403 gdk_region_offset (source_overlaps_destination, -dx, -dy);
3404 gdk_region_intersect (source_overlaps_destination, old_move->dest_region);
3405 gdk_region_offset (source_overlaps_destination, dx, dy);
3407 /* We can do all sort of optimizations here, but to do things safely it becomes
3408 quite complicated. However, a very common case is that you copy something first,
3409 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3410 in the same direction). We'd like to detect this case and optimize it to one
3412 if (gdk_region_equal (source_overlaps_destination, new_dest_region))
3414 /* This means we might be able to replace the old move and the new one
3415 with the new one read from the old ones source, and a second copy of
3416 the non-overwritten parts of the old move. However, such a split
3417 is only valid if the source in the old move isn't overwritten
3418 by the destination of the new one */
3420 /* the new destination of old move if split is ok: */
3421 non_overwritten = gdk_region_copy (old_move->dest_region);
3422 gdk_region_subtract (non_overwritten, new_dest_region);
3423 /* move to source region */
3424 gdk_region_offset (non_overwritten, -old_move->dx, -old_move->dy);
3426 gdk_region_intersect (non_overwritten, new_dest_region);
3427 if (gdk_region_empty (non_overwritten))
3430 move = gdk_window_region_move_new (new_dest_region,
3434 impl_window->outstanding_moves =
3435 g_list_insert_before (impl_window->outstanding_moves,
3437 gdk_region_subtract (old_move->dest_region, new_dest_region);
3439 gdk_region_destroy (non_overwritten);
3442 gdk_region_destroy (source_overlaps_destination);
3443 gdk_region_destroy (old_total_region);
3446 gdk_region_destroy (old_total_region);
3449 gdk_region_destroy (new_total_region);
3453 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3456 impl_window->outstanding_moves =
3457 g_list_prepend (impl_window->outstanding_moves,
3460 impl_window->outstanding_moves =
3461 g_list_insert_before (impl_window->outstanding_moves,
3466 /* Moves bits and update area by dx/dy in impl window.
3467 Takes ownership of region to avoid copy (because we may change it) */
3469 move_region_on_impl (GdkWindowObject *impl_window,
3470 GdkRegion *region, /* In impl window coords */
3473 if ((dx == 0 && dy == 0) ||
3474 gdk_region_empty (region))
3476 gdk_region_destroy (region);
3480 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3482 /* Move any old invalid regions in the copy source area by dx/dy */
3483 if (impl_window->update_area)
3485 GdkRegion *update_area;
3487 update_area = gdk_region_copy (region);
3489 /* Convert from target to source */
3490 gdk_region_offset (update_area, -dx, -dy);
3491 gdk_region_intersect (update_area, impl_window->update_area);
3492 /* We only copy the area, so keep the old update area invalid.
3493 It would be safe to remove it too, as code that uses
3494 move_region_on_impl generally also invalidate the source
3495 area. However, it would just use waste cycles. */
3498 gdk_region_offset (update_area, dx, dy);
3499 gdk_region_union (impl_window->update_area, update_area);
3501 /* This area of the destination is now invalid,
3502 so no need to copy to it. */
3503 gdk_region_subtract (region, update_area);
3505 gdk_region_destroy (update_area);
3508 /* If we're currently exposing this window, don't copy to this
3509 destination, as it will be overdrawn when the expose is done,
3510 instead invalidate it and repaint later. */
3511 if (impl_window->implicit_paint)
3513 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3514 GdkRegion *exposing;
3516 exposing = gdk_region_copy (implicit_paint->region);
3517 gdk_region_intersect (exposing, region);
3518 gdk_region_subtract (region, exposing);
3520 impl_window_add_update_area (impl_window, exposing);
3521 gdk_region_destroy (exposing);
3524 if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3525 append_move_region (impl_window, region, dx, dy);
3527 do_move_region_bits_on_impl (impl_window,
3530 gdk_region_destroy (region);
3533 /* Flushes all outstanding changes to the window, call this
3534 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3537 gdk_window_flush_outstanding_moves (GdkWindow *window)
3539 GdkWindowObject *private;
3540 GdkWindowObject *impl_window;
3542 GdkWindowRegionMove *move;
3544 private = (GdkWindowObject *) window;
3546 impl_window = gdk_window_get_impl_window (private);
3548 for (l = impl_window->outstanding_moves; l != NULL; l = l->next)
3552 do_move_region_bits_on_impl (impl_window,
3553 move->dest_region, move->dx, move->dy);
3555 gdk_window_region_move_free (move);
3558 g_list_free (impl_window->outstanding_moves);
3559 impl_window->outstanding_moves = NULL;
3564 * @window: a #GdkWindow
3566 * Flush all outstanding cached operations on a window, leaving the
3567 * window in a state which reflects all that has been drawn before.
3569 * Gdk uses multiple kinds of caching to get better performance and
3570 * nicer drawing. For instance, during exposes all paints to a window
3571 * using double buffered rendering are keep on a pixmap until the last
3572 * window has been exposed. It also delays window moves/scrolls until
3573 * as long as possible until next update to avoid tearing when moving
3576 * Normally this should be completely invisible to applications, as
3577 * we automatically flush the windows when required, but this might
3578 * be needed if you for instance mix direct native drawing with
3579 * gdk drawing. For Gtk widgets that don't use double buffering this
3580 * will be called automatically before sending the expose event.
3585 gdk_window_flush (GdkWindow *window)
3587 gdk_window_flush_outstanding_moves (window);
3588 gdk_window_flush_implicit_paint (window);
3591 /* If we're about to move/resize or otherwise change the
3592 * hierarchy of a client side window in an impl and we're
3593 * called from an expose event handler then we need to
3594 * flush any already painted parts of the implicit paint
3595 * that are not part of the current paint, as these may
3596 * be used when scrolling or may overdraw the changes
3597 * caused by the hierarchy change.
3600 gdk_window_flush_if_exposing (GdkWindow *window)
3602 GdkWindowObject *private;
3603 GdkWindowObject *impl_window;
3605 private = (GdkWindowObject *) window;
3606 impl_window = gdk_window_get_impl_window (private);
3608 /* If we're in an implicit paint (i.e. in an expose handler, flush
3609 all the already finished exposes to get things to an uptodate state. */
3610 if (impl_window->implicit_paint)
3611 gdk_window_flush (window);
3616 gdk_window_flush_recursive_helper (GdkWindowObject *window,
3619 GdkWindowObject *child;
3622 for (l = window->children; l != NULL; l = l->next)
3626 if (child->impl == impl)
3627 /* Same impl, ignore */
3628 gdk_window_flush_recursive_helper (child, impl);
3630 gdk_window_flush_recursive (child);
3635 gdk_window_flush_recursive (GdkWindowObject *window)
3637 gdk_window_flush ((GdkWindow *)window);
3638 gdk_window_flush_recursive_helper (window, window->impl);
3642 gdk_window_get_offsets (GdkWindow *window,
3646 GdkWindowObject *private = (GdkWindowObject *)window;
3648 if (private->paint_stack)
3650 GdkWindowPaint *paint = private->paint_stack->data;
3651 *x_offset = paint->x_offset;
3652 *y_offset = paint->y_offset;
3656 *x_offset = -private->abs_x;
3657 *y_offset = -private->abs_y;
3662 * gdk_window_get_internal_paint_info:
3663 * @window: a #GdkWindow
3664 * @real_drawable: (out): location to store the drawable to which drawing should be
3666 * @x_offset: (out): location to store the X offset between coordinates in @window,
3667 * and the underlying window system primitive coordinates for
3669 * @y_offset: (out): location to store the Y offset between coordinates in @window,
3670 * and the underlying window system primitive coordinates for
3673 * If you bypass the GDK layer and use windowing system primitives to
3674 * draw directly onto a #GdkWindow, then you need to deal with two
3675 * details: there may be an offset between GDK coordinates and windowing
3676 * system coordinates, and GDK may have redirected drawing to a offscreen
3677 * pixmap as the result of a gdk_window_begin_paint_region() calls.
3678 * This function allows retrieving the information you need to compensate
3679 * for these effects.
3681 * This function exposes details of the GDK implementation, and is thus
3682 * likely to change in future releases of GDK.
3685 gdk_window_get_internal_paint_info (GdkWindow *window,
3686 GdkDrawable **real_drawable,
3692 GdkWindowObject *private;
3694 g_return_if_fail (GDK_IS_WINDOW (window));
3696 private = (GdkWindowObject *)window;
3700 if (private->paint_stack)
3702 GdkWindowPaint *paint = private->paint_stack->data;
3703 *real_drawable = paint->pixmap;
3707 /* This means you're probably gonna be doing some weird shit
3708 directly to the window, so we flush all outstanding stuff */
3709 gdk_window_flush (window);
3710 *real_drawable = window;
3714 gdk_window_get_offsets (window, &x_off, &y_off);
3722 static GdkDrawable *
3723 start_draw_helper (GdkDrawable *drawable,
3728 GdkWindowObject *private = (GdkWindowObject *)drawable;
3729 gint x_offset, y_offset;
3731 gint old_clip_x = gc->clip_x_origin;
3732 gint old_clip_y = gc->clip_y_origin;
3734 guint32 clip_region_tag;
3735 GdkWindowPaint *paint;
3738 if (private->paint_stack)
3739 paint = private->paint_stack->data;
3743 x_offset = paint->x_offset;
3744 y_offset = paint->y_offset;
3748 x_offset = -private->abs_x;
3749 y_offset = -private->abs_y;
3752 if (x_offset != 0 || y_offset != 0)
3754 gdk_gc_set_clip_origin (gc,
3755 old_clip_x - x_offset,
3756 old_clip_y - y_offset);
3757 gdk_gc_set_ts_origin (gc,
3758 gc->ts_x_origin - x_offset,
3759 gc->ts_y_origin - y_offset);
3762 *x_offset_out = x_offset;
3763 *y_offset_out = y_offset;
3765 /* Add client side window clip region to gc */
3769 /* Only need clipping if using implicit paint, otherwise
3770 the pixmap is clipped when copying to the window in end_paint */
3771 if (paint->uses_implicit)
3773 /* This includes the window clip */
3774 clip = paint->region;
3776 clip_region_tag = paint->region_tag;
3778 /* After having set up the drawable clip rect on a GC we need to make sure
3779 * that we draw to th the impl, otherwise the pixmap code will reset the
3781 impl = ((GdkPixmapObject *)(paint->pixmap))->impl;
3785 /* Drawing directly to the window, flush anything outstanding to
3786 guarantee ordering. */
3787 gdk_window_flush ((GdkWindow *)drawable);
3789 /* Don't clip when drawing to root or all native */
3790 if (!_gdk_native_windows && private->window_type != GDK_WINDOW_ROOT)
3792 if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
3793 clip = private->clip_region_with_children;
3795 clip = private->clip_region;
3797 clip_region_tag = private->clip_tag;
3798 impl = private->impl;
3802 _gdk_gc_add_drawable_clip (gc,
3803 clip_region_tag, clip,
3804 /* If there was a clip origin set appart from the
3805 * window offset, need to take that into
3807 -old_clip_x, -old_clip_y);
3812 #define BEGIN_DRAW \
3814 GdkDrawable *impl; \
3815 gint x_offset, y_offset; \
3816 gint old_clip_x = gc->clip_x_origin; \
3817 gint old_clip_y = gc->clip_y_origin; \
3818 gint old_ts_x = gc->ts_x_origin; \
3819 gint old_ts_y = gc->ts_y_origin; \
3820 impl = start_draw_helper (drawable, gc, \
3821 &x_offset, &y_offset);
3824 if (x_offset != 0 || y_offset != 0) \
3826 gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \
3827 gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y); \
3831 #define BEGIN_DRAW_MACRO \
3834 #define END_DRAW_MACRO \
3839 GdkDrawable *drawable;
3852 _gdk_drawable_begin_direct_draw (GdkDrawable *drawable,
3854 gpointer *priv_data,
3858 g_return_val_if_fail (priv_data != NULL, NULL);
3860 GdkDrawable *out_impl = NULL;
3864 if (GDK_IS_PIXMAP (drawable))
3866 /* We bypass the GdkPixmap functions, so do this ourself */
3867 _gdk_gc_remove_drawable_clip (gc);
3869 out_impl = drawable;
3876 if (GDK_WINDOW_DESTROYED (drawable))
3886 *x_offset_out = x_offset;
3887 *y_offset_out = y_offset;
3889 DirectDrawInfo *priv = g_new (DirectDrawInfo, 1);
3891 priv->drawable = impl;
3894 priv->x_offset = x_offset;
3895 priv->y_offset = y_offset;
3896 priv->clip_x = old_clip_x;
3897 priv->clip_y = old_clip_y;
3898 priv->ts_x = old_ts_x;
3899 priv->ts_y = old_ts_y;
3901 *priv_data = (gpointer) priv;
3910 _gdk_drawable_end_direct_draw (gpointer priv_data)
3912 /* Its a GdkPixmap or the call to _gdk_drawable_begin_direct_draw failed. */
3913 if (priv_data == NULL)
3916 DirectDrawInfo *priv = priv_data;
3917 GdkGC *gc = priv->gc;
3919 /* This is only for GdkWindows - if GdkPixmaps need any handling here in
3920 * the future, then we should keep track of what type of drawable it is in
3921 * DirectDrawInfo. */
3924 gint x_offset = priv->x_offset;
3925 gint y_offset = priv->y_offset;
3926 gint old_clip_x = priv->clip_x;
3927 gint old_clip_y = priv->clip_y;
3928 gint old_ts_x = priv->ts_x;
3929 gint old_ts_y = priv->ts_y;
3937 gdk_window_create_gc (GdkDrawable *drawable,
3938 GdkGCValues *values,
3939 GdkGCValuesMask mask)
3941 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
3943 if (GDK_WINDOW_DESTROYED (drawable))
3946 return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl,
3951 gdk_window_draw_rectangle (GdkDrawable *drawable,
3959 if (GDK_WINDOW_DESTROYED (drawable))
3963 gdk_draw_rectangle (impl, gc, filled,
3964 x - x_offset, y - y_offset, width, height);
3969 gdk_window_draw_arc (GdkDrawable *drawable,
3979 if (GDK_WINDOW_DESTROYED (drawable))
3983 gdk_draw_arc (impl, gc, filled,
3984 x - x_offset, y - y_offset,
3985 width, height, angle1, angle2);
3990 gdk_window_draw_polygon (GdkDrawable *drawable,
3996 GdkPoint *new_points;
3998 if (GDK_WINDOW_DESTROYED (drawable))
4003 if (x_offset != 0 || y_offset != 0)
4007 new_points = g_new (GdkPoint, npoints);
4008 for (i=0; i<npoints; i++)
4010 new_points[i].x = points[i].x - x_offset;
4011 new_points[i].y = points[i].y - y_offset;
4015 new_points = points;
4017 gdk_draw_polygon (impl, gc, filled, new_points, npoints);
4019 if (new_points != points)
4020 g_free (new_points);
4025 static GdkDrawable *
4026 gdk_window_get_source_drawable (GdkDrawable *drawable)
4028 GdkWindow *window = GDK_WINDOW (drawable);
4029 GdkWindowObject *private;
4031 private = (GdkWindowObject *) window;
4032 if (GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable)
4033 return GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable (private->impl);
4038 static GdkDrawable *
4039 gdk_window_get_composite_drawable (GdkDrawable *drawable,
4044 gint *composite_x_offset,
4045 gint *composite_y_offset)
4047 GdkWindowObject *private = (GdkWindowObject *)drawable;
4049 GdkPixmap *tmp_pixmap;
4052 gboolean overlap_buffer;
4053 GdkDrawable *source;
4054 GdkWindowObject *impl_window;
4055 GdkWindowPaint *implicit_paint;
4057 *composite_x_offset = -private->abs_x;
4058 *composite_y_offset = -private->abs_y;
4060 if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable)))
4061 return g_object_ref (_gdk_drawable_get_source_drawable (drawable));
4063 /* See if any buffered part is overlapping the part we want
4069 rect.height = height;
4071 overlap_buffer = FALSE;
4073 for (list = private->paint_stack; list != NULL; list = list->next)
4075 GdkWindowPaint *paint = list->data;
4076 GdkOverlapType overlap;
4078 overlap = gdk_region_rect_in (paint->region, &rect);
4080 if (overlap == GDK_OVERLAP_RECTANGLE_IN)
4082 *composite_x_offset = paint->x_offset;
4083 *composite_y_offset = paint->y_offset;
4085 return g_object_ref (paint->pixmap);
4087 else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
4089 overlap_buffer = TRUE;
4094 impl_window = gdk_window_get_impl_window (private);
4095 implicit_paint = impl_window->implicit_paint;
4098 GdkOverlapType overlap;
4100 rect.x += private->abs_x;
4101 rect.y += private->abs_y;
4103 overlap = gdk_region_rect_in (implicit_paint->region, &rect);
4104 if (overlap == GDK_OVERLAP_RECTANGLE_IN)
4106 *composite_x_offset = -private->abs_x + implicit_paint->x_offset;
4107 *composite_y_offset = -private->abs_y + implicit_paint->y_offset;
4109 return g_object_ref (implicit_paint->pixmap);
4111 else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
4112 overlap_buffer = TRUE;
4115 if (!overlap_buffer)
4116 return g_object_ref (_gdk_drawable_get_source_drawable (drawable));
4118 tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1);
4119 tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE);
4121 source = _gdk_drawable_get_source_drawable (drawable);
4123 /* Copy the current window contents */
4124 gdk_draw_drawable (tmp_pixmap,
4126 GDK_WINDOW_OBJECT (source)->impl,
4127 x - *composite_x_offset,
4128 y - *composite_y_offset,
4132 /* paint the backing stores */
4135 GdkWindowPaint *paint = list->data;
4137 gdk_gc_set_clip_region (tmp_gc, paint->region);
4138 gdk_gc_set_clip_origin (tmp_gc, -x - paint->x_offset, -y - paint->y_offset);
4140 gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
4141 x - paint->x_offset,
4142 y - paint->y_offset,
4143 0, 0, width, height);
4146 for (list = private->paint_stack; list != NULL; list = list->next)
4148 GdkWindowPaint *paint = list->data;
4150 if (paint->uses_implicit)
4151 continue; /* We already copied this above */
4153 gdk_gc_set_clip_region (tmp_gc, paint->region);
4154 gdk_gc_set_clip_origin (tmp_gc, -x, -y);
4156 gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
4157 x - paint->x_offset,
4158 y - paint->y_offset,
4159 0, 0, width, height);
4162 /* Reset clip region of the cached GdkGC */
4163 gdk_gc_set_clip_region (tmp_gc, NULL);
4165 /* Set these to location of tmp_pixmap within the window */
4166 *composite_x_offset = x;
4167 *composite_y_offset = y;
4173 gdk_window_get_clip_region (GdkDrawable *drawable)
4175 GdkWindowObject *private = (GdkWindowObject *)drawable;
4178 result = gdk_region_copy (private->clip_region);
4180 if (private->paint_stack)
4182 GdkRegion *paint_region = gdk_region_new ();
4183 GSList *tmp_list = private->paint_stack;
4187 GdkWindowPaint *paint = tmp_list->data;
4189 gdk_region_union (paint_region, paint->region);
4191 tmp_list = tmp_list->next;
4194 gdk_region_intersect (result, paint_region);
4195 gdk_region_destroy (paint_region);
4202 gdk_window_get_visible_region (GdkDrawable *drawable)
4204 GdkWindowObject *private = (GdkWindowObject*) drawable;
4206 return gdk_region_copy (private->clip_region);
4210 gdk_window_draw_drawable (GdkDrawable *drawable,
4219 GdkDrawable *original_src)
4221 GdkWindowObject *private = (GdkWindowObject *)drawable;
4223 if (GDK_WINDOW_DESTROYED (drawable))
4228 /* Call the method directly to avoid getting the composite drawable again */
4229 GDK_DRAWABLE_GET_CLASS (impl)->draw_drawable_with_src (impl, gc,
4237 if (!private->paint_stack)
4239 /* We might have drawn from an obscured part of a client
4240 side window, if so we need to send graphics exposures */
4241 if (_gdk_gc_get_exposures (gc) &&
4242 GDK_IS_WINDOW (original_src))
4244 GdkRegion *exposure_region;
4252 exposure_region = gdk_region_rectangle (&r);
4254 if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
4255 clip = private->clip_region_with_children;
4257 clip = private->clip_region;
4258 gdk_region_intersect (exposure_region, clip);
4260 _gdk_gc_remove_drawable_clip (gc);
4261 clip = _gdk_gc_get_clip_region (gc);
4264 gdk_region_offset (exposure_region,
4267 gdk_region_intersect (exposure_region, clip);
4268 gdk_region_offset (exposure_region,
4273 /* Note: We don't clip by the clip mask if set, so this
4274 may invalidate to much */
4276 /* Remove the area that is correctly copied from the src.
4277 * Note that xsrc/ysrc has been corrected for abs_x/y offsets already,
4278 * which need to be undone */
4279 clip = gdk_drawable_get_visible_region (original_src);
4280 gdk_region_offset (clip,
4281 xdest - (xsrc - GDK_WINDOW_OBJECT (original_src)->abs_x),
4282 ydest - (ysrc - GDK_WINDOW_OBJECT (original_src)->abs_y));
4283 gdk_region_subtract (exposure_region, clip);
4284 gdk_region_destroy (clip);
4286 gdk_window_invalidate_region_full (GDK_WINDOW (private),
4288 _gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS,
4291 gdk_region_destroy (exposure_region);
4299 gdk_window_draw_points (GdkDrawable *drawable,
4304 GdkPoint *new_points;
4306 if (GDK_WINDOW_DESTROYED (drawable))
4311 if (x_offset != 0 || y_offset != 0)
4315 new_points = g_new (GdkPoint, npoints);
4316 for (i=0; i<npoints; i++)
4318 new_points[i].x = points[i].x - x_offset;
4319 new_points[i].y = points[i].y - y_offset;
4323 new_points = points;
4325 gdk_draw_points (impl, gc, new_points, npoints);
4327 if (new_points != points)
4328 g_free (new_points);
4334 gdk_window_draw_segments (GdkDrawable *drawable,
4339 GdkSegment *new_segs;
4341 if (GDK_WINDOW_DESTROYED (drawable))
4346 if (x_offset != 0 || y_offset != 0)
4350 new_segs = g_new (GdkSegment, nsegs);
4351 for (i=0; i<nsegs; i++)
4353 new_segs[i].x1 = segs[i].x1 - x_offset;
4354 new_segs[i].y1 = segs[i].y1 - y_offset;
4355 new_segs[i].x2 = segs[i].x2 - x_offset;
4356 new_segs[i].y2 = segs[i].y2 - y_offset;
4362 gdk_draw_segments (impl, gc, new_segs, nsegs);
4364 if (new_segs != segs)
4371 gdk_window_draw_lines (GdkDrawable *drawable,
4376 GdkPoint *new_points;
4378 if (GDK_WINDOW_DESTROYED (drawable))
4383 if (x_offset != 0 || y_offset != 0)
4387 new_points = g_new (GdkPoint, npoints);
4388 for (i=0; i<npoints; i++)
4390 new_points[i].x = points[i].x - x_offset;
4391 new_points[i].y = points[i].y - y_offset;
4395 new_points = points;
4397 gdk_draw_lines (impl, gc, new_points, npoints);
4399 if (new_points != points)
4400 g_free (new_points);
4406 gdk_window_draw_glyphs (GdkDrawable *drawable,
4411 PangoGlyphString *glyphs)
4413 if (GDK_WINDOW_DESTROYED (drawable))
4417 gdk_draw_glyphs (impl, gc, font,
4418 x - x_offset, y - y_offset, glyphs);
4423 gdk_window_draw_glyphs_transformed (GdkDrawable *drawable,
4425 PangoMatrix *matrix,
4429 PangoGlyphString *glyphs)
4431 PangoMatrix tmp_matrix;
4433 if (GDK_WINDOW_DESTROYED (drawable))
4438 if (x_offset != 0 || y_offset != 0)
4442 tmp_matrix = *matrix;
4443 tmp_matrix.x0 -= x_offset;
4444 tmp_matrix.y0 -= y_offset;
4445 matrix = &tmp_matrix;
4447 else if (GDK_PANGO_UNITS_OVERFLOWS (x_offset, y_offset))
4449 PangoMatrix identity = PANGO_MATRIX_INIT;
4451 tmp_matrix = identity;
4452 tmp_matrix.x0 -= x_offset;
4453 tmp_matrix.y0 -= y_offset;
4454 matrix = &tmp_matrix;
4458 x -= x_offset * PANGO_SCALE;
4459 y -= y_offset * PANGO_SCALE;
4463 gdk_draw_glyphs_transformed (impl, gc, matrix, font, x, y, glyphs);
4469 cairo_t *cr; /* if non-null, it means use this cairo context */
4470 GdkGC *gc; /* if non-null, it means use this GC instead */
4471 } BackingRectMethod;
4474 setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
4476 GdkWindowObject *private = (GdkWindowObject *)window;
4478 if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
4480 GdkWindowPaint tmp_paint;
4483 tmp_paint.x_offset += private->x;
4484 tmp_paint.y_offset += private->y;
4486 x_offset_cairo += private->x;
4487 y_offset_cairo += private->y;
4489 setup_backing_rect_method (method, GDK_WINDOW (private->parent), &tmp_paint, x_offset_cairo, y_offset_cairo);
4491 else if (private->bg_pixmap &&
4492 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
4493 private->bg_pixmap != GDK_NO_BG)
4495 /* This is a workaround for https://bugs.freedesktop.org/show_bug.cgi?id=4320.
4496 * In it, using a pixmap as a repeating pattern in Cairo, and painting it to a
4497 * pixmap destination surface, can be very slow (on the order of seconds for a
4498 * whole-screen copy). The workaround is to use pretty much the same code that
4499 * we used in GTK+ 2.6 (pre-Cairo), which clears the double-buffer pixmap with
4500 * a tiled GC XFillRectangle().
4503 /* Actually computing this flag is left as an exercise for the reader */
4504 #if defined (G_OS_UNIX)
4505 # define GDK_CAIRO_REPEAT_IS_FAST 0
4507 # define GDK_CAIRO_REPEAT_IS_FAST 1
4510 #if GDK_CAIRO_REPEAT_IS_FAST
4511 cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
4512 cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
4513 cairo_surface_destroy (surface);
4515 if (x_offset_cairo != 0 || y_offset_cairo != 0)
4517 cairo_matrix_t matrix;
4518 cairo_matrix_init_translate (&matrix, x_offset_cairo, y_offset_cairo);
4519 cairo_pattern_set_matrix (pattern, &matrix);
4522 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
4524 method->cr = cairo_create (paint->surface);
4527 cairo_set_source (method->cr, pattern);
4528 cairo_pattern_destroy (pattern);
4531 GdkGCValues gc_values;
4533 gc_values.fill = GDK_TILED;
4534 gc_values.tile = private->bg_pixmap;
4535 gc_values.ts_x_origin = -x_offset_cairo;
4536 gc_values.ts_y_origin = -y_offset_cairo;
4538 gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN;
4540 method->gc = gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask);
4545 method->cr = cairo_create (paint->surface);
4547 gdk_cairo_set_source_color (method->cr, &private->bg_color);
4552 gdk_window_clear_backing_region (GdkWindow *window,
4555 GdkWindowObject *private = (GdkWindowObject *)window;
4556 GdkWindowPaint *paint = private->paint_stack->data;
4557 BackingRectMethod method;
4559 GdkRectangle clipbox;
4565 if (GDK_WINDOW_DESTROYED (window))
4569 timer = g_timer_new ();
4574 setup_backing_rect_method (&method, window, paint, 0, 0);
4576 clip = gdk_region_copy (paint->region);
4577 gdk_region_intersect (clip, region);
4578 gdk_region_get_clipbox (clip, &clipbox);
4583 g_assert (method.gc == NULL);
4585 gdk_cairo_region (method.cr, clip);
4586 cairo_fill (method.cr);
4588 cairo_destroy (method.cr);
4590 elapsed = g_timer_elapsed (timer, NULL);
4591 g_print ("Draw the background with Cairo: %fs\n", elapsed);
4596 g_assert (method.gc != NULL);
4598 gdk_gc_set_clip_region (method.gc, clip);
4599 gdk_draw_rectangle (window, method.gc, TRUE,
4600 clipbox.x, clipbox.y,
4601 clipbox.width, clipbox.height);
4602 g_object_unref (method.gc);
4605 elapsed = g_timer_elapsed (timer, NULL);
4606 g_print ("Draw the background with GDK: %fs\n", elapsed);
4610 gdk_region_destroy (clip);
4613 g_timer_destroy (timer);
4618 gdk_window_clear_backing_region_redirect (GdkWindow *window,
4621 GdkWindowObject *private = (GdkWindowObject *)window;
4622 GdkWindowRedirect *redirect = private->redirect;
4623 GdkRegion *clip_region;
4624 GdkRectangle clipbox;
4625 gint x_offset, y_offset;
4626 BackingRectMethod method;
4627 GdkWindowPaint paint;
4629 if (GDK_WINDOW_DESTROYED (window))
4632 clip_region = _gdk_window_calculate_full_clip_region (window,
4633 GDK_WINDOW (redirect->redirected),
4635 &x_offset, &y_offset);
4636 gdk_region_intersect (clip_region, region);
4638 /* offset is from redirected window origin to window origin, convert to
4639 the offset from the redirected pixmap origin to the window origin */
4640 x_offset += redirect->dest_x - redirect->src_x;
4641 y_offset += redirect->dest_y - redirect->src_y;
4643 /* Convert region to pixmap coords */
4644 gdk_region_offset (clip_region, x_offset, y_offset);
4648 paint.pixmap = redirect->pixmap;
4649 paint.surface = _gdk_drawable_ref_cairo_surface (redirect->pixmap);
4653 setup_backing_rect_method (&method, window, &paint, -x_offset, -y_offset);
4657 g_assert (method.gc == NULL);
4659 gdk_cairo_region (method.cr, clip_region);
4660 cairo_fill (method.cr);
4662 cairo_destroy (method.cr);
4666 g_assert (method.gc != NULL);
4668 gdk_region_get_clipbox (clip_region, &clipbox);
4669 gdk_gc_set_clip_region (method.gc, clip_region);
4670 gdk_draw_rectangle (redirect->pixmap, method.gc, TRUE,
4671 clipbox.x, clipbox.y,
4672 clipbox.width, clipbox.height);
4673 g_object_unref (method.gc);
4677 gdk_region_destroy (clip_region);
4678 cairo_surface_destroy (paint.surface);
4682 gdk_window_clear_backing_region_direct (GdkWindow *window,
4685 GdkWindowObject *private = (GdkWindowObject *)window;
4686 BackingRectMethod method;
4687 GdkWindowPaint paint;
4689 GdkRectangle clipbox;
4691 if (GDK_WINDOW_DESTROYED (window))
4696 paint.pixmap = window;
4697 paint.surface = _gdk_drawable_ref_cairo_surface (window);
4701 setup_backing_rect_method (&method, window, &paint, 0, 0);
4703 clip = gdk_region_copy (private->clip_region_with_children);
4704 gdk_region_intersect (clip, region);
4705 gdk_region_get_clipbox (clip, &clipbox);
4709 g_assert (method.gc == NULL);
4711 gdk_cairo_region (method.cr, clip);
4712 cairo_fill (method.cr);
4714 cairo_destroy (method.cr);
4718 g_assert (method.gc != NULL);
4720 gdk_gc_set_clip_region (method.gc, clip);
4721 gdk_draw_rectangle (window, method.gc, TRUE,
4722 clipbox.x, clipbox.y,
4723 clipbox.width, clipbox.height);
4724 g_object_unref (method.gc);
4728 gdk_region_destroy (clip);
4729 cairo_surface_destroy (paint.surface);
4735 * @window: a #GdkWindow
4737 * Clears an entire @window to the background color or background pixmap.
4740 gdk_window_clear (GdkWindow *window)
4744 g_return_if_fail (GDK_IS_WINDOW (window));
4746 gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
4748 gdk_window_clear_area (window, 0, 0,
4752 /* TRUE if the window clears to the same pixels as a native
4753 window clear. This means you can use the native window
4754 clearing operation, and additionally it means any clearing
4755 done by the native window system for you will already be right */
4757 clears_as_native (GdkWindowObject *private)
4759 GdkWindowObject *next;
4765 if (gdk_window_has_impl (private))
4767 next = private->parent;
4769 while (private->bg_pixmap == GDK_PARENT_RELATIVE_BG &&
4770 next && next->window_type != GDK_WINDOW_ROOT);
4775 gdk_window_clear_region_internal (GdkWindow *window,
4777 gboolean send_expose)
4779 GdkWindowObject *private = (GdkWindowObject *)window;
4780 GdkWindowImplIface *impl_iface;
4782 if (private->paint_stack)
4783 gdk_window_clear_backing_region (window, region);
4786 if (private->redirect)
4787 gdk_window_clear_backing_region_redirect (window, region);
4789 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4791 if (impl_iface->clear_region && clears_as_native (private))
4794 copy = gdk_region_copy (region);
4795 gdk_region_intersect (copy,
4796 private->clip_region_with_children);
4799 /* Drawing directly to the window, flush anything outstanding to
4800 guarantee ordering. */
4801 gdk_window_flush (window);
4802 impl_iface->clear_region (window, copy, send_expose);
4804 gdk_region_destroy (copy);
4808 gdk_window_clear_backing_region_direct (window, region);
4810 gdk_window_invalidate_region (window, region, FALSE);
4816 gdk_window_clear_area_internal (GdkWindow *window,
4821 gboolean send_expose)
4826 g_return_if_fail (GDK_IS_WINDOW (window));
4828 if (GDK_WINDOW_DESTROYED (window))
4831 /* Terminate early to avoid weird interpretation of
4832 zero width/height by XClearArea */
4833 if (width == 0 || height == 0)
4839 rect.height = height;
4841 region = gdk_region_rectangle (&rect);
4842 gdk_window_clear_region_internal (window,
4845 gdk_region_destroy (region);
4850 * gdk_window_clear_area:
4851 * @window: a #GdkWindow
4852 * @x: x coordinate of rectangle to clear
4853 * @y: y coordinate of rectangle to clear
4854 * @width: width of rectangle to clear
4855 * @height: height of rectangle to clear
4857 * Clears an area of @window to the background color or background pixmap.
4861 gdk_window_clear_area (GdkWindow *window,
4867 gdk_window_clear_area_internal (window,
4874 * gdk_window_clear_area_e:
4875 * @window: a #GdkWindow
4876 * @x: x coordinate of rectangle to clear
4877 * @y: y coordinate of rectangle to clear
4878 * @width: width of rectangle to clear
4879 * @height: height of rectangle to clear
4881 * Like gdk_window_clear_area(), but also generates an expose event for
4884 * This function has a stupid name because it dates back to the mists
4885 * time, pre-GDK-1.0.
4889 gdk_window_clear_area_e (GdkWindow *window,
4895 gdk_window_clear_area_internal (window,
4902 gdk_window_draw_image (GdkDrawable *drawable,
4912 if (GDK_WINDOW_DESTROYED (drawable))
4916 gdk_draw_image (impl, gc, image, xsrc, ysrc,
4917 xdest - x_offset, ydest - y_offset,
4923 gdk_window_draw_pixbuf (GdkDrawable *drawable,
4932 GdkRgbDither dither,
4936 GdkWindowObject *private = (GdkWindowObject *)drawable;
4937 GdkDrawableClass *klass;
4939 if (GDK_WINDOW_DESTROYED (drawable))
4942 /* If no gc => no user clipping, but we need clipping
4943 for window emulation, so use a scratch gc */
4945 gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
4949 klass = GDK_DRAWABLE_GET_CLASS (impl);
4951 if (private->paint_stack)
4952 klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
4953 dest_x - x_offset, dest_y - y_offset,
4955 dither, x_dither - x_offset, y_dither - y_offset);
4957 klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
4958 dest_x - x_offset, dest_y - y_offset,
4960 dither, x_dither, y_dither);
4965 gdk_window_draw_trapezoids (GdkDrawable *drawable,
4967 GdkTrapezoid *trapezoids,
4970 GdkTrapezoid *new_trapezoids = NULL;
4972 if (GDK_WINDOW_DESTROYED (drawable))
4977 if (x_offset != 0 || y_offset != 0)
4981 new_trapezoids = g_new (GdkTrapezoid, n_trapezoids);
4982 for (i=0; i < n_trapezoids; i++)
4984 new_trapezoids[i].y1 = trapezoids[i].y1 - y_offset;
4985 new_trapezoids[i].x11 = trapezoids[i].x11 - x_offset;
4986 new_trapezoids[i].x21 = trapezoids[i].x21 - x_offset;
4987 new_trapezoids[i].y2 = trapezoids[i].y2 - y_offset;
4988 new_trapezoids[i].x12 = trapezoids[i].x12 - x_offset;
4989 new_trapezoids[i].x22 = trapezoids[i].x22 - x_offset;
4992 trapezoids = new_trapezoids;
4995 gdk_draw_trapezoids (impl, gc, trapezoids, n_trapezoids);
4997 g_free (new_trapezoids);
5003 gdk_window_real_get_size (GdkDrawable *drawable,
5007 GdkWindowObject *private = (GdkWindowObject *)drawable;
5010 *width = private->width;
5012 *height = private->height;
5016 gdk_window_real_get_visual (GdkDrawable *drawable)
5018 GdkColormap *colormap;
5020 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5022 colormap = gdk_drawable_get_colormap (drawable);
5023 return colormap ? gdk_colormap_get_visual (colormap) : NULL;
5027 gdk_window_real_get_depth (GdkDrawable *drawable)
5029 g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
5031 return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
5035 gdk_window_real_get_screen (GdkDrawable *drawable)
5037 return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
5041 gdk_window_real_set_colormap (GdkDrawable *drawable,
5044 GdkWindowObject *private;
5046 g_return_if_fail (GDK_IS_WINDOW (drawable));
5048 if (GDK_WINDOW_DESTROYED (drawable))
5051 private = (GdkWindowObject *)drawable;
5053 /* different colormap than parent, requires native window */
5054 if (!private->input_only &&
5055 cmap != gdk_drawable_get_colormap ((GdkDrawable *)(private->parent)))
5056 gdk_window_ensure_native ((GdkWindow *)drawable);
5058 gdk_drawable_set_colormap (private->impl, cmap);
5062 gdk_window_real_get_colormap (GdkDrawable *drawable)
5064 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5066 if (GDK_WINDOW_DESTROYED (drawable))
5069 return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
5073 gdk_window_copy_to_image (GdkDrawable *drawable,
5082 GdkWindowObject *private = (GdkWindowObject *) drawable;
5083 gint x_offset, y_offset;
5085 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5087 if (GDK_WINDOW_DESTROYED (drawable))
5090 /* If we're here, a composite image was not necessary, so
5091 * we can ignore the paint stack.
5094 /* TODO: Is this right? */
5098 return gdk_drawable_copy_to_image (private->impl,
5107 gdk_window_drop_cairo_surface (GdkWindowObject *private)
5109 if (private->cairo_surface)
5111 cairo_surface_finish (private->cairo_surface);
5112 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
5118 gdk_window_cairo_surface_destroy (void *data)
5120 GdkWindowObject *private = (GdkWindowObject*) data;
5122 private->cairo_surface = NULL;
5123 private->impl_window->outstanding_surfaces--;
5126 static cairo_surface_t *
5127 gdk_window_create_cairo_surface (GdkDrawable *drawable,
5131 return _gdk_windowing_create_cairo_surface (GDK_WINDOW_OBJECT(drawable)->impl,
5136 static cairo_surface_t *
5137 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
5139 GdkWindowObject *private = (GdkWindowObject*) drawable;
5140 cairo_surface_t *surface;
5142 if (private->paint_stack)
5144 GdkWindowPaint *paint = private->paint_stack->data;
5146 surface = paint->surface;
5147 cairo_surface_reference (surface);
5152 /* This will be drawing directly to the window, so flush implicit paint */
5153 gdk_window_flush ((GdkWindow *)drawable);
5155 if (!private->cairo_surface)
5158 GdkDrawable *source;
5160 /* It would be nice if we had some cairo support here so we
5161 could set the clip rect on the cairo surface */
5162 width = private->abs_x + private->width;
5163 height = private->abs_y + private->height;
5165 source = _gdk_drawable_get_source_drawable (drawable);
5167 private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height);
5169 if (private->cairo_surface)
5171 private->impl_window->outstanding_surfaces++;
5173 cairo_surface_set_device_offset (private->cairo_surface,
5177 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
5178 drawable, gdk_window_cairo_surface_destroy);
5182 cairo_surface_reference (private->cairo_surface);
5184 surface = private->cairo_surface;
5191 gdk_window_set_cairo_clip (GdkDrawable *drawable,
5194 GdkWindowObject *private = (GdkWindowObject*) drawable;
5196 if (!private->paint_stack)
5198 cairo_reset_clip (cr);
5201 cairo_identity_matrix (cr);
5203 cairo_new_path (cr);
5204 gdk_cairo_region (cr, private->clip_region_with_children);
5211 GdkWindowPaint *paint = private->paint_stack->data;
5213 /* Only needs to clip to region if piggybacking
5214 on an implicit paint pixmap */
5215 cairo_reset_clip (cr);
5216 if (paint->uses_implicit)
5219 cairo_identity_matrix (cr);
5221 cairo_new_path (cr);
5222 gdk_cairo_region (cr, paint->region);
5230 /* Code for dirty-region queueing
5232 static GSList *update_windows = NULL;
5233 static guint update_idle = 0;
5234 static gboolean debug_updates = FALSE;
5236 static inline gboolean
5237 gdk_window_is_ancestor (GdkWindow *window,
5238 GdkWindow *ancestor)
5242 GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
5244 if (parent == ancestor)
5254 gdk_window_add_update_window (GdkWindow *window)
5257 GSList *prev = NULL;
5258 gboolean has_ancestor_in_list = FALSE;
5260 for (tmp = update_windows; tmp; tmp = tmp->next)
5262 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
5264 /* check if tmp is an ancestor of "window"; if it is, set a
5265 * flag indicating that all following windows are either
5266 * children of "window" or from a differen hierarchy
5268 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
5269 has_ancestor_in_list = TRUE;
5271 /* insert in reverse stacking order when adding around siblings,
5272 * so processing updates properly paints over lower stacked windows
5274 if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
5276 gint index = g_list_index (parent->children, window);
5277 for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
5279 gint sibling_index = g_list_index (parent->children, tmp->data);
5280 if (index > sibling_index)
5284 /* here, tmp got advanced past all lower stacked siblings */
5285 tmp = g_slist_prepend (tmp, window);
5289 update_windows = tmp;
5293 /* if "window" has an ancestor in the list and tmp is one of
5294 * "window's" children, insert "window" before tmp
5296 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
5298 tmp = g_slist_prepend (tmp, window);
5303 update_windows = tmp;
5307 /* if we're at the end of the list and had an ancestor it it,
5308 * append to the list
5310 if (! tmp->next && has_ancestor_in_list)
5312 tmp = g_slist_append (tmp, window);
5319 /* if all above checks failed ("window" is from a different
5320 * hierarchy than what is already in the list) or the list is
5323 update_windows = g_slist_prepend (update_windows, window);
5327 gdk_window_remove_update_window (GdkWindow *window)
5329 update_windows = g_slist_remove (update_windows, window);
5333 gdk_window_update_idle (gpointer data)
5335 gdk_window_process_all_updates ();
5341 gdk_window_is_toplevel_frozen (GdkWindow *window)
5343 GdkWindowObject *toplevel;
5345 toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
5347 return toplevel->update_and_descendants_freeze_count > 0;
5351 gdk_window_schedule_update (GdkWindow *window)
5354 (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
5355 gdk_window_is_toplevel_frozen (window)))
5360 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
5361 gdk_window_update_idle,
5366 _gdk_window_process_updates_recurse (GdkWindow *window,
5367 GdkRegion *expose_region)
5369 GdkWindowObject *private = (GdkWindowObject *)window;
5370 GdkWindowObject *child;
5371 GdkRegion *child_region;
5373 GList *l, *children;
5375 if (gdk_region_empty (expose_region))
5378 /* Make this reentrancy safe for expose handlers freeing windows */
5379 children = g_list_copy (private->children);
5380 g_list_foreach (children, (GFunc)g_object_ref, NULL);
5382 /* Iterate over children, starting at topmost */
5383 for (l = children; l != NULL; l = l->next)
5387 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
5390 /* Ignore offscreen children, as they don't draw in their parent and
5391 * don't take part in the clipping */
5392 if (gdk_window_is_offscreen (child))
5397 r.width = child->width;
5398 r.height = child->height;
5400 child_region = gdk_region_rectangle (&r);
5403 /* Adjust shape region to parent window coords */
5404 gdk_region_offset (child->shape, child->x, child->y);
5405 gdk_region_intersect (child_region, child->shape);
5406 gdk_region_offset (child->shape, -child->x, -child->y);
5409 if (child->impl == private->impl)
5411 /* Client side child, expose */
5412 gdk_region_intersect (child_region, expose_region);
5413 gdk_region_subtract (expose_region, child_region);
5414 gdk_region_offset (child_region, -child->x, -child->y);
5415 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
5419 /* Native child, just remove area from expose region */
5420 gdk_region_subtract (expose_region, child_region);
5422 gdk_region_destroy (child_region);
5425 g_list_foreach (children, (GFunc)g_object_unref, NULL);
5426 g_list_free (children);
5428 if (!gdk_region_empty (expose_region) &&
5429 !private->destroyed)
5431 if (private->event_mask & GDK_EXPOSURE_MASK)
5435 event.expose.type = GDK_EXPOSE;
5436 event.expose.window = g_object_ref (window);
5437 event.expose.send_event = FALSE;
5438 event.expose.count = 0;
5439 event.expose.region = expose_region;
5440 gdk_region_get_clipbox (expose_region, &event.expose.area);
5442 (*_gdk_event_func) (&event, _gdk_event_data);
5444 g_object_unref (window);
5446 else if (private->bg_pixmap != GDK_NO_BG &&
5447 private->window_type != GDK_WINDOW_FOREIGN)
5449 /* No exposure mask set, so nothing will be drawn, the
5450 * app relies on the background being what it specified
5451 * for the window. So, we need to clear this manually.
5453 * For foreign windows if expose is not set that generally
5454 * means some other client paints them, so don't clear
5457 * We use begin/end_paint around the clear so that we can
5458 * piggyback on the implicit paint */
5460 gdk_window_begin_paint_region (window, expose_region);
5461 gdk_window_clear_region_internal (window, expose_region, FALSE);
5462 gdk_window_end_paint (window);
5467 /* Process and remove any invalid area on the native window by creating
5468 * expose events for the window and all non-native descendants.
5469 * Also processes any outstanding moves on the window before doing
5470 * any drawing. Note that its possible to have outstanding moves without
5471 * any invalid area as we use the update idle mechanism to coalesce
5472 * multiple moves as well as multiple invalidations.
5475 gdk_window_process_updates_internal (GdkWindow *window)
5477 GdkWindowObject *private = (GdkWindowObject *)window;
5478 GdkWindowImplIface *impl_iface;
5479 gboolean save_region = FALSE;
5480 GdkRectangle clip_box;
5482 /* Ensure the window lives while updating it */
5483 g_object_ref (window);
5485 /* If an update got queued during update processing, we can get a
5486 * window in the update queue that has an empty update_area.
5489 if (private->update_area)
5491 GdkRegion *update_area = private->update_area;
5492 private->update_area = NULL;
5494 if (_gdk_event_func && gdk_window_is_viewable (window))
5496 GdkRegion *expose_region;
5497 gboolean end_implicit;
5499 /* Clip to part visible in toplevel */
5500 gdk_region_intersect (update_area, private->clip_region);
5504 /* Make sure we see the red invalid area before redrawing. */
5505 gdk_display_sync (gdk_drawable_get_display (window));
5509 /* At this point we will be completely redrawing all of update_area.
5510 * If we have any outstanding moves that end up moving stuff inside
5511 * this area we don't actually need to move that as that part would
5512 * be overdrawn by the expose anyway. So, in order to copy less data
5513 * we remove these areas from the outstanding moves.
5515 if (private->outstanding_moves)
5517 GdkWindowRegionMove *move;
5521 remove = gdk_region_copy (update_area);
5522 /* We iterate backwards, starting from the state that would be
5523 if we had applied all the moves. */
5524 for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
5529 /* Don't need this area */
5530 gdk_region_subtract (move->dest_region, remove);
5532 /* However if any of the destination we do need has a source
5533 in the updated region we do need that as a destination for
5534 the earlier moves */
5535 gdk_region_offset (move->dest_region, -move->dx, -move->dy);
5536 gdk_region_subtract (remove, move->dest_region);
5538 if (gdk_region_empty (move->dest_region))
5540 gdk_window_region_move_free (move);
5541 private->outstanding_moves =
5542 g_list_delete_link (private->outstanding_moves, l);
5544 else /* move back */
5545 gdk_region_offset (move->dest_region, move->dx, move->dy);
5547 gdk_region_destroy (remove);
5550 /* By now we a set of window moves that should be applied, and then
5551 * an update region that should be repainted. A trivial implementation
5552 * would just do that in order, however in order to get nicer drawing
5553 * we do some tricks:
5555 * First of all, each subwindow expose may be double buffered by
5556 * itself (depending on widget setting) via
5557 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
5558 * creating a single pixmap the size of the invalid area on the
5559 * native window which all the individual normal paints will draw
5560 * into. This way in the normal case there will be only one pixmap
5561 * allocated and only once pixmap draw done for all the windows
5562 * in this native window.
5563 * There are a couple of reasons this may fail, for instance, some
5564 * backends (like quartz) do its own double buffering, so we disable
5565 * gdk double buffering there. Secondly, some subwindow could be
5566 * non-double buffered and draw directly to the window outside a
5567 * begin/end_paint pair. That will be lead to a gdk_window_flush
5568 * which immediately executes all outstanding moves and paints+removes
5569 * the implicit paint (further paints will allocate their own pixmap).
5571 * Secondly, in the case of implicit double buffering we expose all
5572 * the child windows into the implicit pixmap before we execute
5573 * the outstanding moves. This way we minimize the time between
5574 * doing the moves and rendering the new update area, thus minimizing
5575 * flashing. Of course, if any subwindow is non-double buffered we
5576 * well flush earlier than that.
5578 * Thirdly, after having done the outstanding moves we queue an
5579 * "antiexpose" on the area that will be drawn by the expose, which
5580 * means that any invalid region on the native window side before
5581 * the first expose drawing operation will be discarded, as it
5582 * has by then been overdrawn with valid data. This means we can
5583 * avoid doing the unnecessary repaint any outstanding expose events.
5586 gdk_region_get_clipbox (update_area, &clip_box);
5587 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
5588 expose_region = gdk_region_copy (update_area);
5591 /* Rendering is not double buffered by gdk, do outstanding
5592 * moves and queue antiexposure immediately. No need to do
5594 gdk_window_flush_outstanding_moves (window);
5595 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5596 save_region = impl_iface->queue_antiexpose (window, update_area);
5599 /* Render the invalid areas to the implicit paint, by sending exposes.
5600 * May flush if non-double buffered widget draw. */
5601 _gdk_windowing_window_process_updates_recurse (window, expose_region);
5605 /* Do moves right before exposes are rendered to the window */
5606 gdk_window_flush_outstanding_moves (window);
5608 /* By this time we know that any outstanding expose for this
5609 * area is invalid and we can avoid it, so queue an antiexpose.
5610 * However, it may be that due to an non-double buffered expose
5611 * we have already started drawing to the window, so it would
5612 * be to late to anti-expose now. Since this is merely an
5613 * optimization we just avoid doing it at all in that case.
5615 if (private->implicit_paint != NULL &&
5616 !private->implicit_paint->flushed)
5618 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5619 save_region = impl_iface->queue_antiexpose (window, update_area);
5622 gdk_window_end_implicit_paint (window);
5624 gdk_region_destroy (expose_region);
5627 gdk_region_destroy (update_area);
5630 if (private->outstanding_moves)
5632 /* Flush any outstanding moves, may happen if we moved a window but got
5633 no actual invalid area */
5634 gdk_window_flush_outstanding_moves (window);
5637 g_object_unref (window);
5641 flush_all_displays (void)
5643 GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
5646 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
5647 gdk_display_flush (tmp_list->data);
5649 g_slist_free (displays);
5652 /* Currently it is not possible to override
5653 * gdk_window_process_all_updates in the same manner as
5654 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
5655 * by implementing the GdkPaintable interface. If in the future a
5656 * backend would need this, the right solution would be to add a
5657 * method to GdkDisplay that can be optionally
5658 * NULL. gdk_window_process_all_updates can then walk the list of open
5659 * displays and call the mehod.
5663 * gdk_window_process_all_updates:
5665 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
5666 * in the application.
5670 gdk_window_process_all_updates (void)
5672 GSList *old_update_windows = update_windows;
5673 GSList *tmp_list = update_windows;
5674 static gboolean in_process_all_updates = FALSE;
5675 static gboolean got_recursive_update = FALSE;
5677 if (in_process_all_updates)
5679 /* We can't do this now since that would recurse, so
5680 delay it until after the recursion is done. */
5681 got_recursive_update = TRUE;
5686 in_process_all_updates = TRUE;
5687 got_recursive_update = FALSE;
5690 g_source_remove (update_idle);
5692 update_windows = NULL;
5695 _gdk_windowing_before_process_all_updates ();
5697 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
5701 GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
5703 if (!GDK_WINDOW_DESTROYED (tmp_list->data))
5705 if (private->update_freeze_count ||
5706 gdk_window_is_toplevel_frozen (tmp_list->data))
5707 gdk_window_add_update_window ((GdkWindow *) private);
5709 gdk_window_process_updates_internal (tmp_list->data);
5712 g_object_unref (tmp_list->data);
5713 tmp_list = tmp_list->next;
5716 g_slist_free (old_update_windows);
5718 flush_all_displays ();
5720 _gdk_windowing_after_process_all_updates ();
5722 in_process_all_updates = FALSE;
5724 /* If we ignored a recursive call, schedule a
5725 redraw now so that it eventually happens,
5726 otherwise we could miss an update if nothing
5727 else schedules an update. */
5728 if (got_recursive_update && !update_idle)
5730 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
5731 gdk_window_update_idle,
5736 * gdk_window_process_updates:
5737 * @window: a #GdkWindow
5738 * @update_children: whether to also process updates for child windows
5740 * Sends one or more expose events to @window. The areas in each
5741 * expose event will cover the entire update area for the window (see
5742 * gdk_window_invalidate_region() for details). Normally GDK calls
5743 * gdk_window_process_all_updates() on your behalf, so there's no
5744 * need to call this function unless you want to force expose events
5745 * to be delivered immediately and synchronously (vs. the usual
5746 * case, where GDK delivers them in an idle handler). Occasionally
5747 * this is useful to produce nicer scrolling behavior, for example.
5751 gdk_window_process_updates (GdkWindow *window,
5752 gboolean update_children)
5754 GdkWindowObject *private = (GdkWindowObject *)window;
5755 GdkWindowObject *impl_window;
5757 g_return_if_fail (GDK_IS_WINDOW (window));
5759 if (GDK_WINDOW_DESTROYED (window))
5762 /* Make sure the window lives during the expose callouts */
5763 g_object_ref (window);
5765 impl_window = gdk_window_get_impl_window (private);
5766 if ((impl_window->update_area ||
5767 impl_window->outstanding_moves) &&
5768 !impl_window->update_freeze_count &&
5769 !gdk_window_is_toplevel_frozen (window) &&
5771 /* Don't recurse into process_updates_internal, we'll
5772 * do the update later when idle instead. */
5773 impl_window->implicit_paint == NULL)
5775 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
5776 gdk_window_remove_update_window ((GdkWindow *)impl_window);
5779 if (update_children)
5781 /* process updates in reverse stacking order so composition or
5782 * painting over achieves the desired effect for offscreen windows
5784 GList *node, *children;
5786 children = g_list_copy (private->children);
5787 g_list_foreach (children, (GFunc)g_object_ref, NULL);
5789 for (node = g_list_last (children); node; node = node->prev)
5791 gdk_window_process_updates (node->data, TRUE);
5792 g_object_unref (node->data);
5795 g_list_free (children);
5798 g_object_unref (window);
5802 gdk_window_invalidate_rect_full (GdkWindow *window,
5803 const GdkRectangle *rect,
5804 gboolean invalidate_children,
5807 GdkRectangle window_rect;
5809 GdkWindowObject *private = (GdkWindowObject *)window;
5811 g_return_if_fail (GDK_IS_WINDOW (window));
5813 if (GDK_WINDOW_DESTROYED (window))
5816 if (private->input_only || !private->viewable)
5823 gdk_drawable_get_size (GDK_DRAWABLE (window),
5825 &window_rect.height);
5826 rect = &window_rect;
5829 region = gdk_region_rectangle (rect);
5830 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
5831 gdk_region_destroy (region);
5835 * gdk_window_invalidate_rect:
5836 * @window: a #GdkWindow
5837 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
5839 * @invalidate_children: whether to also invalidate child windows
5841 * A convenience wrapper around gdk_window_invalidate_region() which
5842 * invalidates a rectangular region. See
5843 * gdk_window_invalidate_region() for details.
5846 gdk_window_invalidate_rect (GdkWindow *window,
5847 const GdkRectangle *rect,
5848 gboolean invalidate_children)
5850 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
5854 draw_ugly_color (GdkWindow *window,
5855 const GdkRegion *region)
5857 /* Draw ugly color all over the newly-invalid region */
5858 GdkColor ugly_color = { 0, 50000, 10000, 10000 };
5860 GdkRectangle clipbox;
5862 ugly_gc = gdk_gc_new (window);
5863 gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
5864 gdk_gc_set_clip_region (ugly_gc, region);
5866 gdk_region_get_clipbox (region, &clipbox);
5868 gdk_draw_rectangle (window,
5871 clipbox.x, clipbox.y,
5872 clipbox.width, clipbox.height);
5874 g_object_unref (ugly_gc);
5878 impl_window_add_update_area (GdkWindowObject *impl_window,
5881 if (impl_window->update_area)
5882 gdk_region_union (impl_window->update_area, region);
5885 gdk_window_add_update_window ((GdkWindow *)impl_window);
5886 impl_window->update_area = gdk_region_copy (region);
5887 gdk_window_schedule_update ((GdkWindow *)impl_window);
5891 /* clear_bg controls if the region will be cleared to
5892 * the background color/pixmap if the exposure mask is not
5893 * set for the window, whereas this might not otherwise be
5894 * done (unless necessary to emulate background settings).
5895 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
5896 * need to clear the background, such as when exposing the area beneath a
5897 * hidden or moved window, but not when an app requests repaint or when the
5898 * windowing system exposes a newly visible area (because then the windowing
5899 * system has already cleared the area).
5902 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
5903 const GdkRegion *region,
5905 gboolean (*child_func) (GdkWindow *,
5909 GdkWindowObject *private = (GdkWindowObject *)window;
5910 GdkWindowObject *impl_window;
5911 GdkRegion *visible_region;
5914 g_return_if_fail (GDK_IS_WINDOW (window));
5916 if (GDK_WINDOW_DESTROYED (window))
5919 if (private->input_only ||
5920 !private->viewable ||
5921 gdk_region_empty (region) ||
5922 private->window_type == GDK_WINDOW_ROOT)
5925 visible_region = gdk_drawable_get_visible_region (window);
5926 gdk_region_intersect (visible_region, region);
5928 tmp_list = private->children;
5931 GdkWindowObject *child = tmp_list->data;
5933 if (!child->input_only)
5935 GdkRegion *child_region;
5936 GdkRectangle child_rect;
5938 child_rect.x = child->x;
5939 child_rect.y = child->y;
5940 child_rect.width = child->width;
5941 child_rect.height = child->height;
5942 child_region = gdk_region_rectangle (&child_rect);
5944 /* remove child area from the invalid area of the parent */
5945 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
5946 !child->composited &&
5947 !gdk_window_is_offscreen (child))
5948 gdk_region_subtract (visible_region, child_region);
5950 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
5952 GdkRegion *tmp = gdk_region_copy (region);
5954 gdk_region_offset (tmp, - child_rect.x, - child_rect.y);
5955 gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
5956 gdk_region_intersect (child_region, tmp);
5958 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
5959 child_region, clear_bg, child_func, user_data);
5961 gdk_region_destroy (tmp);
5964 gdk_region_destroy (child_region);
5967 tmp_list = tmp_list->next;
5970 impl_window = gdk_window_get_impl_window (private);
5972 if (!gdk_region_empty (visible_region) ||
5973 /* Even if we're not exposing anything, make sure we process
5974 idles for windows with outstanding moves */
5975 (impl_window->outstanding_moves != NULL &&
5976 impl_window->update_area == NULL))
5979 draw_ugly_color (window, region);
5981 /* Convert to impl coords */
5982 gdk_region_offset (visible_region, private->abs_x, private->abs_y);
5984 /* Only invalidate area if app requested expose events or if
5985 we need to clear the area (by request or to emulate background
5986 clearing for non-native windows or native windows with no support
5987 for window backgrounds */
5988 if (private->event_mask & GDK_EXPOSURE_MASK ||
5989 clear_bg == CLEAR_BG_ALL ||
5990 (clear_bg == CLEAR_BG_WINCLEARED &&
5991 (!clears_as_native (private) ||
5992 !GDK_WINDOW_IMPL_GET_IFACE (private->impl)->supports_native_bg)))
5993 impl_window_add_update_area (impl_window, visible_region);
5996 gdk_region_destroy (visible_region);
6000 * gdk_window_invalidate_maybe_recurse:
6001 * @window: a #GdkWindow
6002 * @region: a #GdkRegion
6003 * @child_func: function to use to decide if to recurse to a child,
6004 * %NULL means never recurse.
6005 * @user_data: data passed to @child_func
6007 * Adds @region to the update area for @window. The update area is the
6008 * region that needs to be redrawn, or "dirty region." The call
6009 * gdk_window_process_updates() sends one or more expose events to the
6010 * window, which together cover the entire update area. An
6011 * application would normally redraw the contents of @window in
6012 * response to those expose events.
6014 * GDK will call gdk_window_process_all_updates() on your behalf
6015 * whenever your program returns to the main loop and becomes idle, so
6016 * normally there's no need to do that manually, you just need to
6017 * invalidate regions that you know should be redrawn.
6019 * The @child_func parameter controls whether the region of
6020 * each child window that intersects @region will also be invalidated.
6021 * Only children for which @child_func returns TRUE will have the area
6025 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
6026 const GdkRegion *region,
6027 gboolean (*child_func) (GdkWindow *,
6031 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
6032 child_func, user_data);
6036 true_predicate (GdkWindow *window,
6043 gdk_window_invalidate_region_full (GdkWindow *window,
6044 const GdkRegion *region,
6045 gboolean invalidate_children,
6048 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
6049 invalidate_children ?
6050 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
6055 * gdk_window_invalidate_region:
6056 * @window: a #GdkWindow
6057 * @region: a #GdkRegion
6058 * @invalidate_children: %TRUE to also invalidate child windows
6060 * Adds @region to the update area for @window. The update area is the
6061 * region that needs to be redrawn, or "dirty region." The call
6062 * gdk_window_process_updates() sends one or more expose events to the
6063 * window, which together cover the entire update area. An
6064 * application would normally redraw the contents of @window in
6065 * response to those expose events.
6067 * GDK will call gdk_window_process_all_updates() on your behalf
6068 * whenever your program returns to the main loop and becomes idle, so
6069 * normally there's no need to do that manually, you just need to
6070 * invalidate regions that you know should be redrawn.
6072 * The @invalidate_children parameter controls whether the region of
6073 * each child window that intersects @region will also be invalidated.
6074 * If %FALSE, then the update area for child windows will remain
6075 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
6076 * fine grained control over which children are invalidated.
6079 gdk_window_invalidate_region (GdkWindow *window,
6080 const GdkRegion *region,
6081 gboolean invalidate_children)
6083 gdk_window_invalidate_maybe_recurse (window, region,
6084 invalidate_children ?
6085 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
6090 * _gdk_window_invalidate_for_expose:
6091 * @window: a #GdkWindow
6092 * @region: a #GdkRegion
6094 * Adds @region to the update area for @window. The update area is the
6095 * region that needs to be redrawn, or "dirty region." The call
6096 * gdk_window_process_updates() sends one or more expose events to the
6097 * window, which together cover the entire update area. An
6098 * application would normally redraw the contents of @window in
6099 * response to those expose events.
6101 * GDK will call gdk_window_process_all_updates() on your behalf
6102 * whenever your program returns to the main loop and becomes idle, so
6103 * normally there's no need to do that manually, you just need to
6104 * invalidate regions that you know should be redrawn.
6106 * This version of invalidation is used when you recieve expose events
6107 * from the native window system. It exposes the native window, plus
6108 * any non-native child windows (but not native child windows, as those would
6109 * have gotten their own expose events).
6112 _gdk_window_invalidate_for_expose (GdkWindow *window,
6115 GdkWindowObject *private = (GdkWindowObject *) window;
6116 GdkWindowRegionMove *move;
6117 GdkRegion *move_region;
6120 /* Any invalidations comming from the windowing system will
6121 be in areas that may be moved by outstanding moves,
6122 so we need to modify the expose region correspondingly,
6123 otherwise we would expose in the wrong place, as the
6124 outstanding moves will be copied before we draw the
6126 for (l = private->outstanding_moves; l != NULL; l = l->next)
6130 /* covert to move source region */
6131 move_region = gdk_region_copy (move->dest_region);
6132 gdk_region_offset (move_region, -move->dx, -move->dy);
6134 /* Move area of region that intersects with move source
6135 by dx, dy of the move*/
6136 gdk_region_intersect (move_region, region);
6137 gdk_region_subtract (region, move_region);
6138 gdk_region_offset (move_region, move->dx, move->dy);
6139 gdk_region_union (region, move_region);
6141 gdk_region_destroy (move_region);
6144 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
6145 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
6151 * gdk_window_get_update_area:
6152 * @window: a #GdkWindow
6154 * Transfers ownership of the update area from @window to the caller
6155 * of the function. That is, after calling this function, @window will
6156 * no longer have an invalid/dirty region; the update area is removed
6157 * from @window and handed to you. If a window has no update area,
6158 * gdk_window_get_update_area() returns %NULL. You are responsible for
6159 * calling gdk_region_destroy() on the returned region if it's non-%NULL.
6161 * Return value: the update area for @window
6164 gdk_window_get_update_area (GdkWindow *window)
6166 GdkWindowObject *private = (GdkWindowObject *)window;
6167 GdkWindowObject *impl_window;
6168 GdkRegion *tmp_region;
6170 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6172 impl_window = gdk_window_get_impl_window (private);
6174 if (impl_window->update_area)
6176 tmp_region = gdk_region_copy (private->clip_region_with_children);
6177 /* Convert to impl coords */
6178 gdk_region_offset (tmp_region, private->abs_x, private->abs_y);
6179 gdk_region_intersect (tmp_region, impl_window->update_area);
6181 if (gdk_region_empty (tmp_region))
6183 gdk_region_destroy (tmp_region);
6188 gdk_region_subtract (impl_window->update_area, tmp_region);
6190 if (gdk_region_empty (impl_window->update_area) &&
6191 impl_window->outstanding_moves == NULL)
6193 gdk_region_destroy (impl_window->update_area);
6194 impl_window->update_area = NULL;
6196 gdk_window_remove_update_window ((GdkWindow *)impl_window);
6199 /* Convert from impl coords */
6200 gdk_region_offset (tmp_region, -private->abs_x, -private->abs_y);
6210 * _gdk_window_clear_update_area:
6211 * @window: a #GdkWindow.
6213 * Internal function to clear the update area for a window. This
6214 * is called when the window is hidden or destroyed.
6217 _gdk_window_clear_update_area (GdkWindow *window)
6219 GdkWindowObject *private = (GdkWindowObject *)window;
6221 g_return_if_fail (GDK_IS_WINDOW (window));
6223 if (private->update_area)
6225 gdk_window_remove_update_window (window);
6227 gdk_region_destroy (private->update_area);
6228 private->update_area = NULL;
6233 * gdk_window_freeze_updates:
6234 * @window: a #GdkWindow
6236 * Temporarily freezes a window such that it won't receive expose
6237 * events. The window will begin receiving expose events again when
6238 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
6239 * has been called more than once, gdk_window_thaw_updates() must be called
6240 * an equal number of times to begin processing exposes.
6243 gdk_window_freeze_updates (GdkWindow *window)
6245 GdkWindowObject *private = (GdkWindowObject *)window;
6246 GdkWindowObject *impl_window;
6248 g_return_if_fail (GDK_IS_WINDOW (window));
6250 impl_window = gdk_window_get_impl_window (private);
6251 impl_window->update_freeze_count++;
6255 * gdk_window_thaw_updates:
6256 * @window: a #GdkWindow
6258 * Thaws a window frozen with gdk_window_freeze_updates().
6261 gdk_window_thaw_updates (GdkWindow *window)
6263 GdkWindowObject *private = (GdkWindowObject *)window;
6264 GdkWindowObject *impl_window;
6266 g_return_if_fail (GDK_IS_WINDOW (window));
6268 impl_window = gdk_window_get_impl_window (private);
6270 g_return_if_fail (impl_window->update_freeze_count > 0);
6272 if (--impl_window->update_freeze_count == 0)
6273 gdk_window_schedule_update (GDK_WINDOW (impl_window));
6277 * gdk_window_freeze_toplevel_updates_libgtk_only:
6278 * @window: a #GdkWindow
6280 * Temporarily freezes a window and all its descendants such that it won't
6281 * receive expose events. The window will begin receiving expose events
6282 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
6283 * gdk_window_freeze_toplevel_updates_libgtk_only()
6284 * has been called more than once,
6285 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
6286 * an equal number of times to begin processing exposes.
6288 * This function is not part of the GDK public API and is only
6292 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
6294 GdkWindowObject *private = (GdkWindowObject *)window;
6296 g_return_if_fail (GDK_IS_WINDOW (window));
6297 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
6299 private->update_and_descendants_freeze_count++;
6303 * gdk_window_thaw_toplevel_updates_libgtk_only:
6304 * @window: a #GdkWindow
6306 * Thaws a window frozen with
6307 * gdk_window_freeze_toplevel_updates_libgtk_only().
6309 * This function is not part of the GDK public API and is only
6313 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
6315 GdkWindowObject *private = (GdkWindowObject *)window;
6317 g_return_if_fail (GDK_IS_WINDOW (window));
6318 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
6319 g_return_if_fail (private->update_and_descendants_freeze_count > 0);
6321 private->update_and_descendants_freeze_count--;
6323 gdk_window_schedule_update (window);
6327 * gdk_window_set_debug_updates:
6328 * @setting: %TRUE to turn on update debugging
6330 * With update debugging enabled, calls to
6331 * gdk_window_invalidate_region() clear the invalidated region of the
6332 * screen to a noticeable color, and GDK pauses for a short time
6333 * before sending exposes to windows during
6334 * gdk_window_process_updates(). The net effect is that you can see
6335 * the invalid region for each window and watch redraws as they
6336 * occur. This allows you to diagnose inefficiencies in your application.
6338 * In essence, because the GDK rendering model prevents all flicker,
6339 * if you are redrawing the same region 400 times you may never
6340 * notice, aside from noticing a speed problem. Enabling update
6341 * debugging causes GTK to flicker slowly and noticeably, so you can
6342 * see exactly what's being redrawn when, in what order.
6344 * The --gtk-debug=updates command line option passed to GTK+ programs
6345 * enables this debug option at application startup time. That's
6346 * usually more useful than calling gdk_window_set_debug_updates()
6347 * yourself, though you might want to use this function to enable
6348 * updates sometime after application startup time.
6352 gdk_window_set_debug_updates (gboolean setting)
6354 debug_updates = setting;
6358 * gdk_window_constrain_size:
6359 * @geometry: a #GdkGeometry structure
6360 * @flags: a mask indicating what portions of @geometry are set
6361 * @width: desired width of window
6362 * @height: desired height of the window
6363 * @new_width: location to store resulting width
6364 * @new_height: location to store resulting height
6366 * Constrains a desired width and height according to a
6367 * set of geometry hints (such as minimum and maximum size).
6370 gdk_window_constrain_size (GdkGeometry *geometry,
6377 /* This routine is partially borrowed from fvwm.
6379 * Copyright 1993, Robert Nation
6380 * You may use this code for any purpose, as long as the original
6381 * copyright remains in the source code and all documentation
6383 * which in turn borrows parts of the algorithm from uwm
6386 gint min_height = 0;
6387 gint base_width = 0;
6388 gint base_height = 0;
6391 gint max_width = G_MAXINT;
6392 gint max_height = G_MAXINT;
6394 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
6396 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
6398 base_width = geometry->base_width;
6399 base_height = geometry->base_height;
6400 min_width = geometry->min_width;
6401 min_height = geometry->min_height;
6403 else if (flags & GDK_HINT_BASE_SIZE)
6405 base_width = geometry->base_width;
6406 base_height = geometry->base_height;
6407 min_width = geometry->base_width;
6408 min_height = geometry->base_height;
6410 else if (flags & GDK_HINT_MIN_SIZE)
6412 base_width = geometry->min_width;
6413 base_height = geometry->min_height;
6414 min_width = geometry->min_width;
6415 min_height = geometry->min_height;
6418 if (flags & GDK_HINT_MAX_SIZE)
6420 max_width = geometry->max_width ;
6421 max_height = geometry->max_height;
6424 if (flags & GDK_HINT_RESIZE_INC)
6426 xinc = MAX (xinc, geometry->width_inc);
6427 yinc = MAX (yinc, geometry->height_inc);
6430 /* clamp width and height to min and max values
6432 width = CLAMP (width, min_width, max_width);
6433 height = CLAMP (height, min_height, max_height);
6435 /* shrink to base + N * inc
6437 width = base_width + FLOOR (width - base_width, xinc);
6438 height = base_height + FLOOR (height - base_height, yinc);
6440 /* constrain aspect ratio, according to:
6443 * min_aspect <= -------- <= max_aspect
6447 if (flags & GDK_HINT_ASPECT &&
6448 geometry->min_aspect > 0 &&
6449 geometry->max_aspect > 0)
6453 if (geometry->min_aspect * height > width)
6455 delta = FLOOR (height - width / geometry->min_aspect, yinc);
6456 if (height - delta >= min_height)
6460 delta = FLOOR (height * geometry->min_aspect - width, xinc);
6461 if (width + delta <= max_width)
6466 if (geometry->max_aspect * height < width)
6468 delta = FLOOR (width - height * geometry->max_aspect, xinc);
6469 if (width - delta >= min_width)
6473 delta = FLOOR (width / geometry->max_aspect - height, yinc);
6474 if (height + delta <= max_height)
6483 *new_height = height;
6487 * gdk_window_get_pointer:
6488 * @window: a #GdkWindow
6489 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
6490 * return the X coordinate
6491 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
6492 * return the Y coordinate
6493 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
6496 * Obtains the current pointer position and modifier state.
6497 * The position is given in coordinates relative to the upper left
6498 * corner of @window.
6500 * Return value: (transfer none): the window containing the pointer (as with
6501 * gdk_window_at_pointer()), or %NULL if the window containing the
6502 * pointer isn't known to GDK
6504 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
6507 gdk_window_get_pointer (GdkWindow *window,
6510 GdkModifierType *mask)
6512 GdkDisplay *display;
6514 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6516 display = gdk_drawable_get_display (window);
6518 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
6522 * gdk_window_get_device_position:
6523 * @window: a #GdkWindow.
6524 * @device: #GdkDevice to query to.
6525 * @x: return location for the X coordinate of @device, or %NULL.
6526 * @y: return location for the Y coordinate of @device, or %NULL.
6527 * @mask: return location for the modifier mask, or %NULL.
6529 * Obtains the current device position and modifier state.
6530 * The position is given in coordinates relative to the upper left
6531 * corner of @window.
6533 * Returns: The window underneath @device (as with
6534 * gdk_display_get_window_at_device_position()), or %NULL if the
6535 * window is not known to GDK.
6540 gdk_window_get_device_position (GdkWindow *window,
6544 GdkModifierType *mask)
6546 GdkDisplay *display;
6548 GdkModifierType tmp_mask;
6551 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6552 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6554 display = gdk_drawable_get_display (window);
6555 child = display->device_hooks->window_get_device_position (display, device, window,
6556 &tmp_x, &tmp_y, &tmp_mask);
6565 _gdk_display_enable_motion_hints (display, device);
6571 * gdk_window_at_pointer:
6572 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
6573 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
6575 * Obtains the window underneath the mouse pointer, returning the
6576 * location of that window in @win_x, @win_y. Returns %NULL if the
6577 * window under the mouse pointer is not known to GDK (if the window
6578 * belongs to another application and a #GdkWindow hasn't been created
6579 * for it with gdk_window_foreign_new())
6581 * NOTE: For multihead-aware widgets or applications use
6582 * gdk_display_get_window_at_pointer() instead.
6584 * Return value: (transfer none): window under the mouse pointer
6586 * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
6589 gdk_window_at_pointer (gint *win_x,
6592 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
6596 * gdk_get_default_root_window:
6598 * Obtains the root window (parent all other windows are inside)
6599 * for the default display and screen.
6601 * Return value: the default root window
6604 gdk_get_default_root_window (void)
6606 return gdk_screen_get_root_window (gdk_screen_get_default ());
6610 * gdk_window_foreign_new:
6611 * @anid: a native window handle.
6613 * Wraps a native window for the default display in a #GdkWindow.
6614 * This may fail if the window has been destroyed.
6616 * For example in the X backend, a native window handle is an Xlib
6619 * Return value: the newly-created #GdkWindow wrapper for the
6620 * native window or %NULL if the window has been destroyed.
6623 gdk_window_foreign_new (GdkNativeWindow anid)
6625 return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
6629 get_all_native_children (GdkWindowObject *private,
6632 GdkWindowObject *child;
6635 for (l = private->children; l != NULL; l = l->next)
6639 if (gdk_window_has_impl (child))
6640 *native = g_list_prepend (*native, child);
6642 get_all_native_children (child, native);
6648 gdk_window_raise_internal (GdkWindow *window)
6650 GdkWindowObject *private = (GdkWindowObject *)window;
6651 GdkWindowObject *parent = private->parent;
6652 GdkWindowObject *above;
6653 GList *native_children;
6655 GdkWindowImplIface *impl_iface;
6659 parent->children = g_list_remove (parent->children, window);
6660 parent->children = g_list_prepend (parent->children, window);
6663 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6664 /* Just do native raise for toplevels */
6665 if (gdk_window_is_toplevel (private) ||
6666 /* The restack_under codepath should work correctly even if the parent
6667 is native, but it relies on the order of ->children to be correct,
6668 and some apps like SWT reorder the x windows without gdks knowledge,
6669 so we use raise directly in order to make these behave as before
6670 when using native windows */
6671 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
6673 impl_iface->raise (window);
6675 else if (gdk_window_has_impl (private))
6677 above = find_native_sibling_above (parent, private);
6680 listhead.data = window;
6681 listhead.next = NULL;
6682 listhead.prev = NULL;
6683 impl_iface->restack_under ((GdkWindow *)above,
6687 impl_iface->raise (window);
6691 native_children = NULL;
6692 get_all_native_children (private, &native_children);
6693 if (native_children != NULL)
6695 above = find_native_sibling_above (parent, private);
6698 impl_iface->restack_under ((GdkWindow *)above,
6702 /* Right order, since native_children is bottom-topmost first */
6703 for (l = native_children; l != NULL; l = l->next)
6704 impl_iface->raise (l->data);
6707 g_list_free (native_children);
6713 /* Returns TRUE If the native window was mapped or unmapped */
6715 set_viewable (GdkWindowObject *w,
6718 GdkWindowObject *child;
6719 GdkWindowImplIface *impl_iface;
6722 if (w->viewable == val)
6728 recompute_visible_regions (w, FALSE, FALSE);
6730 for (l = w->children; l != NULL; l = l->next)
6734 if (GDK_WINDOW_IS_MAPPED (child) &&
6735 child->window_type != GDK_WINDOW_FOREIGN)
6736 set_viewable (child, val);
6739 if (!_gdk_native_windows &&
6740 gdk_window_has_impl (w) &&
6741 w->window_type != GDK_WINDOW_FOREIGN &&
6742 !gdk_window_is_toplevel (w))
6744 /* For most native windows we show/hide them not when they are
6745 * mapped/unmapped, because that may not produce the correct results.
6746 * For instance, if a native window have a non-native parent which is
6747 * hidden, but its native parent is viewable then showing the window
6748 * would make it viewable to X but its not viewable wrt the non-native
6749 * hierarchy. In order to handle this we track the gdk side viewability
6750 * and only map really viewable windows.
6752 * There are two exceptions though:
6754 * For foreign windows we don't want ever change the mapped state
6755 * except when explicitly done via gdk_window_show/hide, as this may
6756 * cause problems for client owning the foreign window when its window
6757 * is suddenly mapped or unmapped.
6759 * For toplevel windows embedded in a foreign window (e.g. a plug)
6760 * we sometimes synthesize a map of a window, but the native
6761 * window is really shown by the embedder, so we don't want to
6762 * do the show ourselves. We can't really tell this case from the normal
6763 * toplevel show as such toplevels are seen by gdk as parents of the
6764 * root window, so we make an exception for all toplevels.
6766 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
6767 * like this, so we just always show/hide directly.
6770 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
6772 impl_iface->show ((GdkWindow *)w, FALSE);
6774 impl_iface->hide ((GdkWindow *)w);
6782 /* Returns TRUE If the native window was mapped or unmapped */
6784 _gdk_window_update_viewable (GdkWindow *window)
6786 GdkWindowObject *priv = (GdkWindowObject *)window;
6789 if (priv->window_type == GDK_WINDOW_FOREIGN ||
6790 priv->window_type == GDK_WINDOW_ROOT)
6792 else if (gdk_window_is_toplevel (priv) ||
6793 priv->parent->viewable)
6794 viewable = GDK_WINDOW_IS_MAPPED (priv);
6798 return set_viewable (priv, viewable);
6802 gdk_window_show_internal (GdkWindow *window, gboolean raise)
6804 GdkWindowObject *private;
6805 GdkWindowImplIface *impl_iface;
6806 gboolean was_mapped, was_viewable;
6809 g_return_if_fail (GDK_IS_WINDOW (window));
6811 private = (GdkWindowObject *) window;
6812 if (private->destroyed)
6815 was_mapped = GDK_WINDOW_IS_MAPPED (window);
6816 was_viewable = private->viewable;
6819 /* Keep children in (reverse) stacking order */
6820 gdk_window_raise_internal (window);
6822 if (gdk_window_has_impl (private))
6825 gdk_synthesize_window_state (window,
6826 GDK_WINDOW_STATE_WITHDRAWN,
6834 did_show = _gdk_window_update_viewable (window);
6836 /* If it was already viewable the backend show op won't be called, call it
6837 again to ensure things happen right if the mapped tracking was not right
6838 for e.g. a foreign window.
6839 Dunno if this is strictly needed but its what happened pre-csw.
6840 Also show if not done by gdk_window_update_viewable. */
6841 if (gdk_window_has_impl (private) && (was_viewable || !did_show))
6843 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6844 impl_iface->show ((GdkWindow *)private,
6845 !did_show ? was_mapped : TRUE);
6848 if (!was_mapped && !gdk_window_has_impl (private))
6850 if (private->event_mask & GDK_STRUCTURE_MASK)
6851 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
6853 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
6854 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
6857 if (!was_mapped || raise)
6859 recompute_visible_regions (private, TRUE, FALSE);
6861 /* If any decendants became visible we need to send visibility notify */
6862 gdk_window_update_visibility_recursively (private, NULL);
6864 if (gdk_window_is_viewable (window))
6866 _gdk_synthesize_crossing_events_for_geometry_change (window);
6867 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
6873 * gdk_window_show_unraised:
6874 * @window: a #GdkWindow
6876 * Shows a #GdkWindow onscreen, but does not modify its stacking
6877 * order. In contrast, gdk_window_show() will raise the window
6878 * to the top of the window stack.
6880 * On the X11 platform, in Xlib terms, this function calls
6881 * XMapWindow() (it also updates some internal GDK state, which means
6882 * that you can't really use XMapWindow() directly on a GDK window).
6885 gdk_window_show_unraised (GdkWindow *window)
6887 gdk_window_show_internal (window, FALSE);
6892 * @window: a #GdkWindow
6894 * Raises @window to the top of the Z-order (stacking order), so that
6895 * other windows with the same parent window appear below @window.
6896 * This is true whether or not the windows are visible.
6898 * If @window is a toplevel, the window manager may choose to deny the
6899 * request to move the window in the Z-order, gdk_window_raise() only
6900 * requests the restack, does not guarantee it.
6903 gdk_window_raise (GdkWindow *window)
6905 GdkWindowObject *private;
6906 GdkRegion *old_region, *new_region;
6908 g_return_if_fail (GDK_IS_WINDOW (window));
6910 private = (GdkWindowObject *) window;
6911 if (private->destroyed)
6914 gdk_window_flush_if_exposing (window);
6917 if (gdk_window_is_viewable (window) &&
6918 !private->input_only)
6919 old_region = gdk_region_copy (private->clip_region);
6921 /* Keep children in (reverse) stacking order */
6922 gdk_window_raise_internal (window);
6924 recompute_visible_regions (private, TRUE, FALSE);
6928 new_region = gdk_region_copy (private->clip_region);
6930 gdk_region_subtract (new_region, old_region);
6931 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
6933 gdk_region_destroy (old_region);
6934 gdk_region_destroy (new_region);
6939 gdk_window_lower_internal (GdkWindow *window)
6941 GdkWindowObject *private = (GdkWindowObject *)window;
6942 GdkWindowObject *parent = private->parent;
6943 GdkWindowImplIface *impl_iface;
6944 GdkWindowObject *above;
6945 GList *native_children;
6950 parent->children = g_list_remove (parent->children, window);
6951 parent->children = g_list_append (parent->children, window);
6954 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6955 /* Just do native lower for toplevels */
6956 if (gdk_window_is_toplevel (private) ||
6957 /* The restack_under codepath should work correctly even if the parent
6958 is native, but it relies on the order of ->children to be correct,
6959 and some apps like SWT reorder the x windows without gdks knowledge,
6960 so we use lower directly in order to make these behave as before
6961 when using native windows */
6962 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
6964 impl_iface->lower (window);
6966 else if (gdk_window_has_impl (private))
6968 above = find_native_sibling_above (parent, private);
6971 listhead.data = window;
6972 listhead.next = NULL;
6973 listhead.prev = NULL;
6974 impl_iface->restack_under ((GdkWindow *)above, &listhead);
6977 impl_iface->raise (window);
6981 native_children = NULL;
6982 get_all_native_children (private, &native_children);
6983 if (native_children != NULL)
6985 above = find_native_sibling_above (parent, private);
6988 impl_iface->restack_under ((GdkWindow *)above,
6992 /* Right order, since native_children is bottom-topmost first */
6993 for (l = native_children; l != NULL; l = l->next)
6994 impl_iface->raise (l->data);
6997 g_list_free (native_children);
7004 gdk_window_invalidate_in_parent (GdkWindowObject *private)
7006 GdkRectangle r, child;
7008 if (gdk_window_is_toplevel (private))
7011 /* get the visible rectangle of the parent */
7013 r.width = private->parent->width;
7014 r.height = private->parent->height;
7016 child.x = private->x;
7017 child.y = private->y;
7018 child.width = private->width;
7019 child.height = private->height;
7020 gdk_rectangle_intersect (&r, &child, &r);
7022 gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
7028 * @window: a #GdkWindow
7030 * Lowers @window to the bottom of the Z-order (stacking order), so that
7031 * other windows with the same parent window appear above @window.
7032 * This is true whether or not the other windows are visible.
7034 * If @window is a toplevel, the window manager may choose to deny the
7035 * request to move the window in the Z-order, gdk_window_lower() only
7036 * requests the restack, does not guarantee it.
7038 * Note that gdk_window_show() raises the window again, so don't call this
7039 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
7042 gdk_window_lower (GdkWindow *window)
7044 GdkWindowObject *private;
7046 g_return_if_fail (GDK_IS_WINDOW (window));
7048 private = (GdkWindowObject *) window;
7049 if (private->destroyed)
7052 gdk_window_flush_if_exposing (window);
7054 /* Keep children in (reverse) stacking order */
7055 gdk_window_lower_internal (window);
7057 recompute_visible_regions (private, TRUE, FALSE);
7059 _gdk_synthesize_crossing_events_for_geometry_change (window);
7060 gdk_window_invalidate_in_parent (private);
7064 * gdk_window_restack:
7065 * @window: a #GdkWindow
7066 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
7069 * Changes the position of @window in the Z-order (stacking order), so that
7070 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
7073 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
7074 * lowers the window.
7076 * If @window is a toplevel, the window manager may choose to deny the
7077 * request to move the window in the Z-order, gdk_window_restack() only
7078 * requests the restack, does not guarantee it.
7083 gdk_window_restack (GdkWindow *window,
7087 GdkWindowObject *private;
7088 GdkWindowImplIface *impl_iface;
7089 GdkWindowObject *parent;
7090 GdkWindowObject *above_native;
7091 GList *sibling_link;
7092 GList *native_children;
7095 g_return_if_fail (GDK_IS_WINDOW (window));
7096 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
7098 private = (GdkWindowObject *) window;
7099 if (private->destroyed)
7102 if (sibling == NULL)
7105 gdk_window_raise (window);
7107 gdk_window_lower (window);
7111 gdk_window_flush_if_exposing (window);
7113 if (gdk_window_is_toplevel (private))
7115 g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
7116 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7117 impl_iface->restack_toplevel (window, sibling, above);
7121 parent = private->parent;
7124 sibling_link = g_list_find (parent->children, sibling);
7125 g_return_if_fail (sibling_link != NULL);
7126 if (sibling_link == NULL)
7129 parent->children = g_list_remove (parent->children, window);
7131 parent->children = g_list_insert_before (parent->children,
7135 parent->children = g_list_insert_before (parent->children,
7139 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7140 if (gdk_window_has_impl (private))
7142 above_native = find_native_sibling_above (parent, private);
7145 listhead.data = window;
7146 listhead.next = NULL;
7147 listhead.prev = NULL;
7148 impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
7151 impl_iface->raise (window);
7155 native_children = NULL;
7156 get_all_native_children (private, &native_children);
7157 if (native_children != NULL)
7159 above_native = find_native_sibling_above (parent, private);
7161 impl_iface->restack_under ((GdkWindow *)above_native,
7165 /* Right order, since native_children is bottom-topmost first */
7166 for (l = native_children; l != NULL; l = l->next)
7167 impl_iface->raise (l->data);
7170 g_list_free (native_children);
7175 recompute_visible_regions (private, TRUE, FALSE);
7177 _gdk_synthesize_crossing_events_for_geometry_change (window);
7178 gdk_window_invalidate_in_parent (private);
7184 * @window: a #GdkWindow
7186 * Like gdk_window_show_unraised(), but also raises the window to the
7187 * top of the window stack (moves the window to the front of the
7190 * This function maps a window so it's visible onscreen. Its opposite
7191 * is gdk_window_hide().
7193 * When implementing a #GtkWidget, you should call this function on the widget's
7194 * #GdkWindow as part of the "map" method.
7197 gdk_window_show (GdkWindow *window)
7199 gdk_window_show_internal (window, TRUE);
7204 * @window: a #GdkWindow
7206 * For toplevel windows, withdraws them, so they will no longer be
7207 * known to the window manager; for all windows, unmaps them, so
7208 * they won't be displayed. Normally done automatically as
7209 * part of gtk_widget_hide().
7212 gdk_window_hide (GdkWindow *window)
7214 GdkWindowObject *private;
7215 GdkWindowImplIface *impl_iface;
7216 gboolean was_mapped, did_hide;
7218 g_return_if_fail (GDK_IS_WINDOW (window));
7220 private = (GdkWindowObject *) window;
7221 if (private->destroyed)
7224 was_mapped = GDK_WINDOW_IS_MAPPED (private);
7226 if (gdk_window_has_impl (private))
7229 if (GDK_WINDOW_IS_MAPPED (window))
7230 gdk_synthesize_window_state (window,
7232 GDK_WINDOW_STATE_WITHDRAWN);
7234 else if (was_mapped)
7236 GdkDisplay *display;
7237 GdkDeviceManager *device_manager;
7240 /* May need to break grabs on children */
7241 display = gdk_drawable_get_display (window);
7242 device_manager = gdk_display_get_device_manager (display);
7244 /* Get all devices */
7245 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
7246 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
7247 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
7249 for (d = devices; d; d = d->next)
7251 GdkDevice *device = d->data;
7253 if (_gdk_display_end_device_grab (display, device,
7254 _gdk_windowing_window_get_next_serial (display),
7257 gdk_device_ungrab (device, GDK_CURRENT_TIME);
7260 private->state = GDK_WINDOW_STATE_WITHDRAWN;
7261 g_list_free (devices);
7264 did_hide = _gdk_window_update_viewable (window);
7266 /* Hide foreign window as those are not handled by update_viewable. */
7267 if (gdk_window_has_impl (private) && (!did_hide))
7269 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7270 impl_iface->hide (window);
7273 recompute_visible_regions (private, TRUE, FALSE);
7275 /* all decendants became non-visible, we need to send visibility notify */
7276 gdk_window_update_visibility_recursively (private, NULL);
7278 if (was_mapped && !gdk_window_has_impl (private))
7280 if (private->event_mask & GDK_STRUCTURE_MASK)
7281 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7283 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
7284 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7286 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
7289 /* Invalidate the rect */
7291 gdk_window_invalidate_in_parent (private);
7295 * gdk_window_withdraw:
7296 * @window: a toplevel #GdkWindow
7298 * Withdraws a window (unmaps it and asks the window manager to forget about it).
7299 * This function is not really useful as gdk_window_hide() automatically
7300 * withdraws toplevel windows before hiding them.
7303 gdk_window_withdraw (GdkWindow *window)
7305 GdkWindowObject *private;
7306 GdkWindowImplIface *impl_iface;
7307 gboolean was_mapped;
7309 g_return_if_fail (GDK_IS_WINDOW (window));
7311 private = (GdkWindowObject *) window;
7312 if (private->destroyed)
7315 was_mapped = GDK_WINDOW_IS_MAPPED (private);
7317 if (gdk_window_has_impl (private))
7319 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7320 impl_iface->withdraw (window);
7324 if (private->event_mask & GDK_STRUCTURE_MASK)
7325 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7327 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
7328 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7330 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
7333 recompute_visible_regions (private, TRUE, FALSE);
7338 * gdk_window_set_events:
7339 * @window: a #GdkWindow
7340 * @event_mask: event mask for @window
7342 * The event mask for a window determines which events will be reported
7343 * for that window from all master input devices. For example, an event mask
7344 * including #GDK_BUTTON_PRESS_MASK means the window should report button
7345 * press events. The event mask is the bitwise OR of values from the
7346 * #GdkEventMask enumeration.
7349 gdk_window_set_events (GdkWindow *window,
7350 GdkEventMask event_mask)
7352 GdkWindowObject *private;
7353 GdkWindowImplIface *impl_iface;
7354 GdkDisplay *display;
7356 g_return_if_fail (GDK_IS_WINDOW (window));
7358 private = (GdkWindowObject *) window;
7359 if (private->destroyed)
7362 /* If motion hint is disabled, enable motion events again */
7363 display = gdk_drawable_get_display (window);
7364 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
7365 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
7367 GList *devices = private->devices_inside;
7371 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
7372 devices = devices->next;
7376 private->event_mask = event_mask;
7378 if (gdk_window_has_impl (private))
7380 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7381 impl_iface->set_events (window,
7382 get_native_event_mask (private));
7388 * gdk_window_get_events:
7389 * @window: a #GdkWindow
7391 * Gets the event mask for @window for all master input devices. See
7392 * gdk_window_set_events().
7394 * Return value: event mask for @window
7397 gdk_window_get_events (GdkWindow *window)
7399 GdkWindowObject *private;
7401 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7403 private = (GdkWindowObject *) window;
7404 if (private->destroyed)
7407 return private->event_mask;
7411 * gdk_window_set_device_events:
7412 * @window: a #GdkWindow
7413 * @device: #GdkDevice to enable events for.
7414 * @event_mask: event mask for @window
7416 * Sets the event mask for a given device (Normally a floating device, not
7417 * attached to any visible pointer) to @window. For example, an event mask
7418 * including #GDK_BUTTON_PRESS_MASK means the window should report button
7419 * press events. The event mask is the bitwise OR of values from the
7420 * #GdkEventMask enumeration.
7425 gdk_window_set_device_events (GdkWindow *window,
7427 GdkEventMask event_mask)
7429 GdkEventMask device_mask;
7430 GdkWindowObject *private;
7431 GdkDisplay *display;
7434 g_return_if_fail (GDK_IS_WINDOW (window));
7435 g_return_if_fail (GDK_IS_DEVICE (device));
7437 if (GDK_WINDOW_DESTROYED (window))
7440 private = (GdkWindowObject *) window;
7442 /* If motion hint is disabled, enable motion events again */
7443 display = gdk_drawable_get_display (window);
7444 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
7445 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
7446 _gdk_display_enable_motion_hints (display, device);
7448 if (G_UNLIKELY (!private->device_events))
7449 private->device_events = g_hash_table_new (NULL, NULL);
7451 if (event_mask == 0)
7453 /* FIXME: unsetting events on a master device
7454 * would restore private->event_mask
7456 g_hash_table_remove (private->device_events, device);
7459 g_hash_table_insert (private->device_events, device,
7460 GINT_TO_POINTER (event_mask));
7462 if (_gdk_native_windows)
7465 native = gdk_window_get_toplevel (window);
7467 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
7469 native = gdk_offscreen_window_get_embedder (native);
7471 if (native == NULL ||
7472 (!_gdk_window_has_impl (native) &&
7473 !gdk_window_is_viewable (native)))
7476 native = gdk_window_get_toplevel (native);
7479 device_mask = get_native_device_event_mask (private, device);
7480 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
7484 * gdk_window_get_device_events:
7485 * @window: a #GdkWindow.
7486 * @device: a #GdkDevice.
7488 * Returns the event mask for @window corresponding to an specific device.
7490 * Returns: device event mask for @window
7495 gdk_window_get_device_events (GdkWindow *window,
7498 GdkWindowObject *private;
7501 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7502 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
7504 if (GDK_WINDOW_DESTROYED (window))
7507 private = (GdkWindowObject *) window;
7509 if (!private->device_events)
7512 mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
7514 /* FIXME: device could be controlled by private->event_mask */
7520 gdk_window_move_resize_toplevel (GdkWindow *window,
7527 GdkWindowObject *private;
7528 GdkRegion *old_region, *new_region;
7529 GdkWindowImplIface *impl_iface;
7531 int old_x, old_y, old_abs_x, old_abs_y;
7535 private = (GdkWindowObject *) window;
7543 is_resize = (width != -1) || (height != -1);
7545 if (gdk_window_is_viewable (window) &&
7546 !private->input_only)
7549 old_region = gdk_region_copy (private->clip_region);
7552 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7553 impl_iface->move_resize (window, with_move, x, y, width, height);
7555 dx = private->x - old_x;
7556 dy = private->y - old_y;
7558 old_abs_x = private->abs_x;
7559 old_abs_y = private->abs_y;
7561 /* Avoid recomputing for pure toplevel moves, for performance reasons */
7563 recompute_visible_regions (private, TRUE, FALSE);
7567 new_region = gdk_region_copy (private->clip_region);
7569 /* This is the newly exposed area (due to any resize),
7570 * X will expose it, but lets do that without the
7573 gdk_region_subtract (new_region, old_region);
7574 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
7576 gdk_region_destroy (old_region);
7577 gdk_region_destroy (new_region);
7580 _gdk_synthesize_crossing_events_for_geometry_change (window);
7585 move_native_children (GdkWindowObject *private)
7588 GdkWindowObject *child;
7589 GdkWindowImplIface *impl_iface;
7591 for (l = private->children; l; l = l->next)
7595 if (child->impl != private->impl)
7597 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
7598 impl_iface->move_resize ((GdkWindow *)child, TRUE,
7600 child->width, child->height);
7603 move_native_children (child);
7608 collect_native_child_region_helper (GdkWindowObject *window,
7614 GdkWindowObject *child;
7618 for (l = window->children; l != NULL; l = l->next)
7622 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
7625 if (child->impl != impl)
7627 tmp = gdk_region_copy (child->clip_region);
7628 gdk_region_offset (tmp,
7629 x_offset + child->x,
7630 y_offset + child->y);
7631 if (*region == NULL)
7635 gdk_region_union (*region, tmp);
7636 gdk_region_destroy (tmp);
7640 collect_native_child_region_helper (child, impl, region,
7641 x_offset + child->x,
7642 y_offset + child->y);
7649 collect_native_child_region (GdkWindowObject *window,
7650 gboolean include_this)
7654 if (include_this && gdk_window_has_impl (window) && window->viewable)
7655 return gdk_region_copy (window->clip_region);
7659 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
7666 gdk_window_move_resize_internal (GdkWindow *window,
7673 GdkWindowObject *private;
7674 GdkRegion *old_region, *new_region, *copy_area;
7675 GdkRegion *old_native_child_region, *new_native_child_region;
7676 GdkWindowObject *impl_window;
7677 GdkWindowImplIface *impl_iface;
7679 int old_x, old_y, old_abs_x, old_abs_y;
7682 g_return_if_fail (GDK_IS_WINDOW (window));
7684 private = (GdkWindowObject *) window;
7685 if (private->destroyed)
7688 if (gdk_window_is_toplevel (private))
7690 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
7694 /* Bail early if no change */
7695 if (private->width == width &&
7696 private->height == height &&
7702 gdk_window_flush_if_exposing (window);
7704 /* Handle child windows */
7709 impl_window = gdk_window_get_impl_window (private);
7714 old_native_child_region = NULL;
7715 if (gdk_window_is_viewable (window) &&
7716 !private->input_only)
7720 old_region = gdk_region_copy (private->clip_region);
7721 /* Adjust region to parent window coords */
7722 gdk_region_offset (old_region, private->x, private->y);
7724 old_native_child_region = collect_native_child_region (private, TRUE);
7725 if (old_native_child_region)
7727 /* Adjust region to parent window coords */
7728 gdk_region_offset (old_native_child_region, private->x, private->y);
7730 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
7731 * source or destination for a delayed GdkWindowRegionMove. So, we need
7732 * to flush those here for the parent window and all overlapped subwindows
7733 * of it. And we need to do this before setting the new clips as those will be
7736 gdk_window_flush_recursive (private->parent);
7740 /* Set the new position and size */
7746 if (!(width < 0 && height < 0))
7750 private->width = width;
7753 private->height = height;
7756 dx = private->x - old_x;
7757 dy = private->y - old_y;
7759 old_abs_x = private->abs_x;
7760 old_abs_y = private->abs_y;
7762 recompute_visible_regions (private, TRUE, FALSE);
7764 new_native_child_region = NULL;
7765 if (old_native_child_region)
7767 new_native_child_region = collect_native_child_region (private, TRUE);
7768 /* Adjust region to parent window coords */
7769 gdk_region_offset (new_native_child_region, private->x, private->y);
7772 if (gdk_window_has_impl (private))
7774 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7776 /* Do the actual move after recomputing things, as this will have set the shape to
7777 the now correct one, thus avoiding copying regions that should not be copied. */
7778 impl_iface->move_resize (window, TRUE,
7779 private->x, private->y,
7780 private->width, private->height);
7782 else if (old_abs_x != private->abs_x ||
7783 old_abs_y != private->abs_y)
7784 move_native_children (private);
7788 new_region = gdk_region_copy (private->clip_region);
7789 /* Adjust region to parent window coords */
7790 gdk_region_offset (new_region, private->x, private->y);
7793 * Part of the data at the new location can be copied from the
7794 * old location, this area is the intersection of the old region
7795 * moved as the copy will move it and then intersected with
7799 * Everything in the old and new regions that is not copied must be
7800 * invalidated (including children) as this is newly exposed
7802 copy_area = gdk_region_copy (new_region);
7804 gdk_region_union (new_region, old_region);
7806 if (old_native_child_region)
7808 /* Don't copy from inside native children, as this is copied by
7809 * the native window move.
7811 gdk_region_subtract (old_region, old_native_child_region);
7813 gdk_region_offset (old_region, dx, dy);
7815 gdk_region_intersect (copy_area, old_region);
7817 if (new_native_child_region)
7819 /* Don't copy any bits that would cause a read from the moved
7820 native windows, as we can't read that data */
7821 gdk_region_offset (new_native_child_region, dx, dy);
7822 gdk_region_subtract (copy_area, new_native_child_region);
7823 gdk_region_offset (new_native_child_region, -dx, -dy);
7826 gdk_region_subtract (new_region, copy_area);
7828 /* Convert old region to impl coords */
7829 gdk_region_offset (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
7831 /* convert from parent coords to impl */
7832 gdk_region_offset (copy_area, private->abs_x - private->x, private->abs_y - private->y);
7834 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
7836 /* Invalidate affected part in the parent window
7837 * (no higher window should be affected)
7838 * We also invalidate any children in that area, which could include
7839 * this window if it still overlaps that area.
7841 if (old_native_child_region)
7843 /* No need to expose the region that the native window move copies */
7844 gdk_region_offset (old_native_child_region, dx, dy);
7845 gdk_region_intersect (old_native_child_region, new_native_child_region);
7846 gdk_region_subtract (new_region, old_native_child_region);
7848 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
7850 gdk_region_destroy (old_region);
7851 gdk_region_destroy (new_region);
7854 if (old_native_child_region)
7856 gdk_region_destroy (old_native_child_region);
7857 gdk_region_destroy (new_native_child_region);
7860 _gdk_synthesize_crossing_events_for_geometry_change (window);
7867 * @window: a #GdkWindow
7868 * @x: X coordinate relative to window's parent
7869 * @y: Y coordinate relative to window's parent
7871 * Repositions a window relative to its parent window.
7872 * For toplevel windows, window managers may ignore or modify the move;
7873 * you should probably use gtk_window_move() on a #GtkWindow widget
7874 * anyway, instead of using GDK functions. For child windows,
7875 * the move will reliably succeed.
7877 * If you're also planning to resize the window, use gdk_window_move_resize()
7878 * to both move and resize simultaneously, for a nicer visual effect.
7881 gdk_window_move (GdkWindow *window,
7885 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
7889 * gdk_window_resize:
7890 * @window: a #GdkWindow
7891 * @width: new width of the window
7892 * @height: new height of the window
7894 * Resizes @window; for toplevel windows, asks the window manager to resize
7895 * the window. The window manager may not allow the resize. When using GTK+,
7896 * use gtk_window_resize() instead of this low-level GDK function.
7898 * Windows may not be resized below 1x1.
7900 * If you're also planning to move the window, use gdk_window_move_resize()
7901 * to both move and resize simultaneously, for a nicer visual effect.
7904 gdk_window_resize (GdkWindow *window,
7908 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
7913 * gdk_window_move_resize:
7914 * @window: a #GdkWindow
7915 * @x: new X position relative to window's parent
7916 * @y: new Y position relative to window's parent
7918 * @height: new height
7920 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
7921 * except that both operations are performed at once, avoiding strange
7922 * visual effects. (i.e. the user may be able to see the window first
7923 * move, then resize, if you don't use gdk_window_move_resize().)
7926 gdk_window_move_resize (GdkWindow *window,
7932 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
7937 * gdk_window_scroll:
7938 * @window: a #GdkWindow
7939 * @dx: Amount to scroll in the X direction
7940 * @dy: Amount to scroll in the Y direction
7942 * Scroll the contents of @window, both pixels and children, by the
7943 * given amount. @window itself does not move. Portions of the window
7944 * that the scroll operation brings in from offscreen areas are
7945 * invalidated. The invalidated region may be bigger than what would
7946 * strictly be necessary.
7948 * For X11, a minimum area will be invalidated if the window has no
7949 * subwindows, or if the edges of the window's parent do not extend
7950 * beyond the edges of the window. In other cases, a multi-step process
7951 * is used to scroll the window which may produce temporary visual
7952 * artifacts and unnecessary invalidations.
7955 gdk_window_scroll (GdkWindow *window,
7959 GdkWindowObject *private = (GdkWindowObject *) window;
7960 GdkWindowObject *impl_window;
7961 GdkRegion *copy_area, *noncopy_area;
7962 GdkRegion *old_native_child_region, *new_native_child_region;
7965 g_return_if_fail (GDK_IS_WINDOW (window));
7967 if (dx == 0 && dy == 0)
7970 if (private->destroyed)
7973 gdk_window_flush_if_exposing (window);
7975 old_native_child_region = collect_native_child_region (private, FALSE);
7976 if (old_native_child_region)
7978 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
7979 * source or destination for a delayed GdkWindowRegionMove. So, we need
7980 * to flush those here for the window and all overlapped subwindows
7981 * of it. And we need to do this before setting the new clips as those will be
7984 gdk_window_flush_recursive (private);
7988 /* First move all child windows, without causing invalidation */
7990 tmp_list = private->children;
7993 GdkWindow *child = GDK_WINDOW (tmp_list->data);
7994 GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
7996 /* Just update the positions, the bits will move with the copy */
8000 tmp_list = tmp_list->next;
8003 recompute_visible_regions (private, FALSE, TRUE);
8005 new_native_child_region = NULL;
8006 if (old_native_child_region)
8007 new_native_child_region = collect_native_child_region (private, FALSE);
8009 move_native_children (private);
8011 /* Then copy the actual bits of the window w/ child windows */
8013 impl_window = gdk_window_get_impl_window (private);
8015 /* Calculate the area that can be gotten by copying the old area */
8016 copy_area = gdk_region_copy (private->clip_region);
8017 if (old_native_child_region)
8019 /* Don't copy from inside native children, as this is copied by
8020 * the native window move.
8022 gdk_region_subtract (copy_area, old_native_child_region);
8024 /* Don't copy any bits that would cause a read from the moved
8025 native windows, as we can't read that data */
8026 gdk_region_subtract (copy_area, new_native_child_region);
8028 gdk_region_offset (copy_area, dx, dy);
8029 gdk_region_intersect (copy_area, private->clip_region);
8031 /* And the rest need to be invalidated */
8032 noncopy_area = gdk_region_copy (private->clip_region);
8033 gdk_region_subtract (noncopy_area, copy_area);
8035 /* convert from window coords to impl */
8036 gdk_region_offset (copy_area, private->abs_x, private->abs_y);
8038 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
8040 /* Invalidate not copied regions */
8041 if (old_native_child_region)
8043 /* No need to expose the region that the native window move copies */
8044 gdk_region_offset (old_native_child_region, dx, dy);
8045 gdk_region_intersect (old_native_child_region, new_native_child_region);
8046 gdk_region_subtract (noncopy_area, old_native_child_region);
8048 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
8050 gdk_region_destroy (noncopy_area);
8052 if (old_native_child_region)
8054 gdk_region_destroy (old_native_child_region);
8055 gdk_region_destroy (new_native_child_region);
8058 _gdk_synthesize_crossing_events_for_geometry_change (window);
8062 * gdk_window_move_region:
8063 * @window: a #GdkWindow
8064 * @region: The #GdkRegion to move
8065 * @dx: Amount to move in the X direction
8066 * @dy: Amount to move in the Y direction
8068 * Move the part of @window indicated by @region by @dy pixels in the Y
8069 * direction and @dx pixels in the X direction. The portions of @region
8070 * that not covered by the new position of @region are invalidated.
8072 * Child windows are not moved.
8077 gdk_window_move_region (GdkWindow *window,
8078 const GdkRegion *region,
8082 GdkWindowObject *private = (GdkWindowObject *) window;
8083 GdkWindowObject *impl_window;
8084 GdkRegion *nocopy_area;
8085 GdkRegion *copy_area;
8087 g_return_if_fail (GDK_IS_WINDOW (window));
8088 g_return_if_fail (region != NULL);
8090 if (dx == 0 && dy == 0)
8093 if (private->destroyed)
8096 impl_window = gdk_window_get_impl_window (private);
8098 /* compute source regions */
8099 copy_area = gdk_region_copy (region);
8100 gdk_region_intersect (copy_area, private->clip_region_with_children);
8102 /* compute destination regions */
8103 gdk_region_offset (copy_area, dx, dy);
8104 gdk_region_intersect (copy_area, private->clip_region_with_children);
8106 /* Invalidate parts of the region (source and dest) not covered
8108 nocopy_area = gdk_region_copy (region);
8109 gdk_region_offset (nocopy_area, dx, dy);
8110 gdk_region_union (nocopy_area, region);
8111 gdk_region_subtract (nocopy_area, copy_area);
8113 /* convert from window coords to impl */
8114 gdk_region_offset (copy_area, private->abs_x, private->abs_y);
8115 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
8117 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
8118 gdk_region_destroy (nocopy_area);
8122 * gdk_window_get_background:
8123 * @window: a #GdkWindow.
8124 * @color: (out): a #GdkColor to be filled in
8126 * Sets @color to equal the current background color of @window.
8131 gdk_window_get_background (GdkWindow *window,
8134 GdkWindowObject *private;
8136 g_return_if_fail (GDK_IS_WINDOW (window));
8137 g_return_if_fail (color != NULL);
8139 private = (GdkWindowObject *) window;
8141 *color = private->bg_color;
8145 * gdk_window_set_background:
8146 * @window: a #GdkWindow
8147 * @color: an allocated #GdkColor
8149 * Sets the background color of @window. (However, when using GTK+,
8150 * set the background of a widget with gtk_widget_modify_bg() - if
8151 * you're an application - or gtk_style_set_background() - if you're
8152 * implementing a custom widget.)
8154 * The @color must be allocated; gdk_rgb_find_color() is the best way
8155 * to allocate a color.
8157 * See also gdk_window_set_background_pixmap().
8160 gdk_window_set_background (GdkWindow *window,
8161 const GdkColor *color)
8163 GdkWindowObject *private;
8164 GdkColormap *colormap = gdk_drawable_get_colormap (window);
8165 GdkWindowImplIface *impl_iface;
8167 g_return_if_fail (GDK_IS_WINDOW (window));
8169 private = (GdkWindowObject *) window;
8171 private->bg_color = *color;
8172 gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
8174 if (private->bg_pixmap &&
8175 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
8176 private->bg_pixmap != GDK_NO_BG)
8177 g_object_unref (private->bg_pixmap);
8179 private->bg_pixmap = NULL;
8181 if (!GDK_WINDOW_DESTROYED (window) &&
8182 gdk_window_has_impl (private) &&
8183 !private->input_only)
8185 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8186 impl_iface->set_background (window, &private->bg_color);
8191 * gdk_window_get_back_pixmap:
8192 * @window: a #GdkWindow.
8193 * @pixmap: (out) (allow-none): a #GdkPixmap to be filled in, or %NULL.
8194 * @parent_relative: (out) (allow-none): a pointer to a #gboolean to be filled in, or %NULL.
8196 * Sets @pixmap to the current background pixmap of @window. You do not
8197 * own the pointer that is returned and this pointer should not be freeed
8198 * or unreferenced. Sets @parent_relative to %TRUE if the tiling is done
8199 * based on the origin of the parent window.
8204 gdk_window_get_back_pixmap (GdkWindow *window,
8206 gboolean *parent_relative)
8208 GdkWindowObject *private;
8210 g_return_if_fail (GDK_IS_WINDOW (window));
8212 private = (GdkWindowObject *) window;
8216 if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG ||
8217 private->bg_pixmap == GDK_NO_BG)
8220 *pixmap = private->bg_pixmap;
8223 if (parent_relative)
8224 *parent_relative = (private->bg_pixmap == GDK_PARENT_RELATIVE_BG);
8228 * gdk_window_set_back_pixmap:
8229 * @window: a #GdkWindow
8230 * @pixmap: (allow-none): a #GdkPixmap, or %NULL
8231 * @parent_relative: whether the tiling origin is at the origin of
8234 * Sets the background pixmap of @window. May also be used to set a
8235 * background of "None" on @window, by setting a background pixmap
8238 * A background pixmap will be tiled, positioning the first tile at
8239 * the origin of @window, or if @parent_relative is %TRUE, the tiling
8240 * will be done based on the origin of the parent window (useful to
8241 * align tiles in a parent with tiles in a child).
8243 * A background pixmap of %NULL means that the window will have no
8244 * background. A window with no background will never have its
8245 * background filled by the windowing system, instead the window will
8246 * contain whatever pixels were already in the corresponding area of
8249 * The windowing system will normally fill a window with its background
8250 * when the window is obscured then exposed, and when you call
8251 * gdk_window_clear().
8254 gdk_window_set_back_pixmap (GdkWindow *window,
8256 gboolean parent_relative)
8258 GdkWindowObject *private;
8259 GdkWindowImplIface *impl_iface;
8261 g_return_if_fail (GDK_IS_WINDOW (window));
8262 g_return_if_fail (pixmap == NULL || !parent_relative);
8263 g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
8265 private = (GdkWindowObject *) window;
8267 if (pixmap && !gdk_drawable_get_colormap (pixmap))
8269 g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
8273 if (private->bg_pixmap &&
8274 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
8275 private->bg_pixmap != GDK_NO_BG)
8276 g_object_unref (private->bg_pixmap);
8278 if (parent_relative)
8279 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
8281 private->bg_pixmap = g_object_ref (pixmap);
8283 private->bg_pixmap = GDK_NO_BG;
8285 if (!GDK_WINDOW_DESTROYED (window) &&
8286 gdk_window_has_impl (private) &&
8287 !private->input_only)
8289 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8290 impl_iface->set_back_pixmap (window, private->bg_pixmap);
8295 update_cursor_foreach (GdkDisplay *display,
8297 GdkPointerWindowInfo *pointer_info,
8300 GdkWindow *window = user_data;
8301 GdkWindowObject *private = (GdkWindowObject *) window;
8303 if (_gdk_native_windows ||
8304 private->window_type == GDK_WINDOW_ROOT ||
8305 private->window_type == GDK_WINDOW_FOREIGN)
8306 GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_device_cursor (window, device, private->cursor);
8307 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
8308 update_cursor (display, device);
8312 * gdk_window_get_cursor:
8313 * @window: a #GdkWindow
8315 * Retrieves a #GdkCursor pointer for the cursor currently set on the
8316 * specified #GdkWindow, or %NULL. If the return value is %NULL then
8317 * there is no custom cursor set on the specified window, and it is
8318 * using the cursor for its parent window.
8320 * Return value: a #GdkCursor, or %NULL. The returned object is owned
8321 * by the #GdkWindow and should not be unreferenced directly. Use
8322 * gdk_window_set_cursor() to unset the cursor of the window
8327 gdk_window_get_cursor (GdkWindow *window)
8329 GdkWindowObject *private;
8331 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
8333 private = (GdkWindowObject *) window;
8335 return private->cursor;
8339 * gdk_window_set_cursor:
8340 * @window: a #GdkWindow
8341 * @cursor: (allow-none): a cursor
8343 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
8344 * or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor
8345 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
8346 * to gdk_window_set_cursor() means that @window will use the cursor of its
8347 * parent window. Most windows should use this default.
8350 gdk_window_set_cursor (GdkWindow *window,
8353 GdkWindowObject *private;
8354 GdkDisplay *display;
8356 g_return_if_fail (GDK_IS_WINDOW (window));
8358 private = (GdkWindowObject *) window;
8359 display = gdk_drawable_get_display (window);
8361 if (private->cursor)
8363 gdk_cursor_unref (private->cursor);
8364 private->cursor = NULL;
8367 if (!GDK_WINDOW_DESTROYED (window))
8370 private->cursor = gdk_cursor_ref (cursor);
8372 _gdk_display_pointer_info_foreach (display,
8373 update_cursor_foreach,
8376 g_object_notify (G_OBJECT (window), "cursor");
8381 * gdk_window_get_device_cursor:
8382 * @window: a #GdkWindow.
8383 * @device: a #GdkDevice.
8385 * Retrieves a #GdkCursor pointer for the @device currently set on the
8386 * specified #GdkWindow, or %NULL. If the return value is %NULL then
8387 * there is no custom cursor set on the specified window, and it is
8388 * using the cursor for its parent window.
8390 * Returns: a #GdkCursor, or %NULL. The returned object is owned
8391 * by the #GdkWindow and should not be unreferenced directly. Use
8392 * gdk_window_set_cursor() to unset the cursor of the window
8397 gdk_window_get_device_cursor (GdkWindow *window,
8400 GdkWindowObject *private;
8402 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
8403 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
8405 private = (GdkWindowObject *) window;
8407 return g_hash_table_lookup (private->device_cursor, device);
8411 * gdk_window_set_device_cursor:
8412 * @window: a #Gdkwindow
8413 * @device: a #GdkDevice
8414 * @cursor: a #GdkCursor
8416 * Sets a specific #GdkCursor for a given device when it gets inside @window.
8417 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixmap() to create
8418 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
8419 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
8420 * @window will use the cursor of its parent window. Most windows should
8426 gdk_window_set_device_cursor (GdkWindow *window,
8430 GdkWindowObject *private;
8431 GdkDisplay *display;
8433 g_return_if_fail (GDK_IS_WINDOW (window));
8434 g_return_if_fail (GDK_IS_DEVICE (device));
8436 private = (GdkWindowObject *) window;
8437 display = gdk_drawable_get_display (window);
8440 g_hash_table_remove (private->device_cursor, device);
8442 g_hash_table_replace (private->device_cursor, device, cursor);
8444 if (!GDK_WINDOW_DESTROYED (window))
8446 GdkPointerWindowInfo *pointer_info;
8448 pointer_info = _gdk_display_get_pointer_info (display, device);
8450 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
8451 update_cursor (display, device);
8456 * gdk_window_get_geometry:
8457 * @window: a #GdkWindow
8458 * @x: return location for X coordinate of window (relative to its parent)
8459 * @y: return location for Y coordinate of window (relative to its parent)
8460 * @width: return location for width of window
8461 * @height: return location for height of window
8462 * @depth: return location for bit depth of window
8464 * Any of the return location arguments to this function may be %NULL,
8465 * if you aren't interested in getting the value of that field.
8467 * The X and Y coordinates returned are relative to the parent window
8468 * of @window, which for toplevels usually means relative to the
8469 * window decorations (titlebar, etc.) rather than relative to the
8470 * root window (screen-size background window).
8472 * On the X11 platform, the geometry is obtained from the X server,
8473 * so reflects the latest position of @window; this may be out-of-sync
8474 * with the position of @window delivered in the most-recently-processed
8475 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
8476 * position from the most recent configure event.
8479 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
8480 * to call gdk_window_get_position() and gdk_drawable_get_size() instead,
8481 * because it avoids the roundtrip to the X server and because
8482 * gdk_drawable_get_size() supports the full 32-bit coordinate space,
8483 * whereas gdk_window_get_geometry() is restricted to the 16-bit
8484 * coordinates of X11.
8488 gdk_window_get_geometry (GdkWindow *window,
8495 GdkWindowObject *private, *parent;
8496 GdkWindowImplIface *impl_iface;
8500 GDK_NOTE (MULTIHEAD,
8501 g_message ("gdk_window_get_geometry(): Window needs "
8502 "to be non-NULL to be multi head safe"));
8503 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
8506 g_return_if_fail (GDK_IS_WINDOW (window));
8508 private = (GdkWindowObject *) window;
8510 if (!GDK_WINDOW_DESTROYED (window))
8512 if (gdk_window_has_impl (private))
8514 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8515 impl_iface->get_geometry (window, x, y,
8518 /* This reports the position wrt to the native parent, we need to convert
8519 it to be relative to the client side parent */
8520 parent = private->parent;
8521 if (parent && !gdk_window_has_impl (parent))
8524 *x -= parent->abs_x;
8526 *y -= parent->abs_y;
8536 *width = private->width;
8538 *height = private->height;
8540 *depth = private->depth;
8546 * gdk_window_get_origin:
8547 * @window: a #GdkWindow
8548 * @x: return location for X coordinate
8549 * @y: return location for Y coordinate
8551 * Obtains the position of a window in root window coordinates.
8552 * (Compare with gdk_window_get_position() and
8553 * gdk_window_get_geometry() which return the position of a window
8554 * relative to its parent window.)
8556 * Return value: not meaningful, ignore
8559 gdk_window_get_origin (GdkWindow *window,
8563 GdkWindowObject *private;
8564 GdkWindowImplIface *impl_iface;
8566 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8568 if (GDK_WINDOW_DESTROYED (window))
8577 private = (GdkWindowObject *) window;
8579 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8580 impl_iface->get_root_coords (window,
8589 * gdk_window_get_root_coords:
8590 * @window: a #GdkWindow
8591 * @x: X coordinate in window
8592 * @y: Y coordinate in window
8593 * @root_x: return location for X coordinate
8594 * @root_y: return location for Y coordinate
8596 * Obtains the position of a window position in root
8597 * window coordinates. This is similar to
8598 * gdk_window_get_origin() but allows you go pass
8599 * in any position in the window, not just the origin.
8604 gdk_window_get_root_coords (GdkWindow *window,
8610 GdkWindowObject *private;
8611 GdkWindowImplIface *impl_iface;
8613 g_return_if_fail (GDK_IS_WINDOW (window));
8615 private = (GdkWindowObject *) window;
8617 if (GDK_WINDOW_DESTROYED (window))
8626 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8627 impl_iface->get_root_coords (window,
8634 * gdk_window_coords_to_parent:
8635 * @window: a child window
8636 * @x: X coordinate in child's coordinate system
8637 * @y: Y coordinate in child's coordinate system
8638 * @parent_x: (out) (allow-none): return location for X coordinate
8639 * in parent's coordinate system, or %NULL
8640 * @parent_y: (out) (allow-none): return location for Y coordinate
8641 * in parent's coordinate system, or %NULL
8643 * Transforms window coordinates from a child window to its parent
8644 * window, where the parent window is the normal parent as returned by
8645 * gdk_window_get_parent() for normal windows, and the window's
8646 * embedder as returned by gdk_offscreen_window_get_embedder() for
8647 * offscreen windows.
8649 * For normal windows, calling this function is equivalent to adding
8650 * the return values of gdk_window_get_position() to the child coordinates.
8651 * For offscreen windows however (which can be arbitrarily transformed),
8652 * this function calls the GdkWindow::to-embedder: signal to translate
8655 * You should always use this function when writing generic code that
8656 * walks up a window hierarchy.
8658 * See also: gdk_window_coords_from_parent()
8663 gdk_window_coords_to_parent (GdkWindow *window,
8669 GdkWindowObject *obj;
8671 g_return_if_fail (GDK_IS_WINDOW (window));
8673 obj = (GdkWindowObject *) window;
8675 if (gdk_window_is_offscreen (obj))
8679 to_embedder (obj, x, y, &px, &py);
8690 *parent_x = x + obj->x;
8693 *parent_y = y + obj->y;
8698 * gdk_window_coords_from_parent:
8699 * @window: a child window
8700 * @parent_x: X coordinate in parent's coordinate system
8701 * @parent_y: Y coordinate in parent's coordinate system
8702 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
8703 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
8705 * Transforms window coordinates from a parent window to a child
8706 * window, where the parent window is the normal parent as returned by
8707 * gdk_window_get_parent() for normal windows, and the window's
8708 * embedder as returned by gdk_offscreen_window_get_embedder() for
8709 * offscreen windows.
8711 * For normal windows, calling this function is equivalent to subtracting
8712 * the return values of gdk_window_get_position() from the parent coordinates.
8713 * For offscreen windows however (which can be arbitrarily transformed),
8714 * this function calls the GdkWindow::from-embedder: signal to translate
8717 * You should always use this function when writing generic code that
8718 * walks down a window hierarchy.
8720 * See also: gdk_window_coords_to_parent()
8725 gdk_window_coords_from_parent (GdkWindow *window,
8731 GdkWindowObject *obj;
8733 g_return_if_fail (GDK_IS_WINDOW (window));
8735 obj = (GdkWindowObject *) window;
8737 if (gdk_window_is_offscreen (obj))
8741 from_embedder (obj, parent_x, parent_y, &cx, &cy);
8752 *x = parent_x - obj->x;
8755 *y = parent_y - obj->y;
8760 * gdk_window_get_deskrelative_origin:
8761 * @window: a toplevel #GdkWindow
8762 * @x: return location for X coordinate
8763 * @y: return location for Y coordinate
8765 * This gets the origin of a #GdkWindow relative to
8766 * an Enlightenment-window-manager desktop. As long as you don't
8767 * assume that the user's desktop/workspace covers the entire
8768 * root window (i.e. you don't assume that the desktop begins
8769 * at root window coordinate 0,0) this function is not necessary.
8770 * It's deprecated for that reason.
8772 * Return value: not meaningful
8775 gdk_window_get_deskrelative_origin (GdkWindow *window,
8779 GdkWindowObject *private;
8780 GdkWindowImplIface *impl_iface;
8781 gboolean return_val = FALSE;
8785 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8787 private = (GdkWindowObject *) window;
8789 if (!GDK_WINDOW_DESTROYED (window))
8791 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8792 return_val = impl_iface->get_deskrelative_origin (window, &tx, &ty);
8795 *x = tx + private->abs_x;
8797 *y = ty + private->abs_y;
8804 * gdk_window_shape_combine_mask:
8805 * @window: a #GdkWindow
8807 * @x: X position of shape mask with respect to @window
8808 * @y: Y position of shape mask with respect to @window
8810 * Applies a shape mask to @window. Pixels in @window corresponding to
8811 * set bits in the @mask will be visible; pixels in @window
8812 * corresponding to unset bits in the @mask will be transparent. This
8813 * gives a non-rectangular window.
8815 * If @mask is %NULL, the shape mask will be unset, and the @x/@y
8816 * parameters are not used.
8818 * On the X11 platform, this uses an X server extension which is
8819 * widely available on most common platforms, but not available on
8820 * very old X servers, and occasionally the implementation will be
8821 * buggy. On servers without the shape extension, this function
8824 * This function works on both toplevel and child windows.
8827 gdk_window_shape_combine_mask (GdkWindow *window,
8832 GdkWindowObject *private;
8835 g_return_if_fail (GDK_IS_WINDOW (window));
8837 private = (GdkWindowObject *) window;
8840 region = _gdk_windowing_get_shape_for_mask (mask);
8844 gdk_window_shape_combine_region (window,
8849 gdk_region_destroy (region);
8853 * gdk_window_shape_combine_region:
8854 * @window: a #GdkWindow
8855 * @shape_region: region of window to be non-transparent
8856 * @offset_x: X position of @shape_region in @window coordinates
8857 * @offset_y: Y position of @shape_region in @window coordinates
8859 * Makes pixels in @window outside @shape_region be transparent,
8860 * so that the window may be nonrectangular. See also
8861 * gdk_window_shape_combine_mask() to use a bitmap as the mask.
8863 * If @shape_region is %NULL, the shape will be unset, so the whole
8864 * window will be opaque again. @offset_x and @offset_y are ignored
8865 * if @shape_region is %NULL.
8867 * On the X11 platform, this uses an X server extension which is
8868 * widely available on most common platforms, but not available on
8869 * very old X servers, and occasionally the implementation will be
8870 * buggy. On servers without the shape extension, this function
8873 * This function works on both toplevel and child windows.
8876 gdk_window_shape_combine_region (GdkWindow *window,
8877 const GdkRegion *shape_region,
8881 GdkWindowObject *private;
8882 GdkRegion *old_region, *new_region, *diff;
8884 g_return_if_fail (GDK_IS_WINDOW (window));
8886 private = (GdkWindowObject *) window;
8888 if (GDK_WINDOW_DESTROYED (window))
8891 private->shaped = (shape_region != NULL);
8894 gdk_region_destroy (private->shape);
8897 if (GDK_WINDOW_IS_MAPPED (window))
8898 old_region = gdk_region_copy (private->clip_region);
8902 private->shape = gdk_region_copy (shape_region);
8903 gdk_region_offset (private->shape, offset_x, offset_y);
8906 private->shape = NULL;
8908 recompute_visible_regions (private, TRUE, FALSE);
8910 if (gdk_window_has_impl (private) &&
8911 !should_apply_clip_as_shape (private))
8912 apply_shape (private, private->shape);
8916 new_region = gdk_region_copy (private->clip_region);
8918 /* New area in the window, needs invalidation */
8919 diff = gdk_region_copy (new_region);
8920 gdk_region_subtract (diff, old_region);
8922 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
8924 gdk_region_destroy (diff);
8926 if (!gdk_window_is_toplevel (private))
8928 /* New area in the non-root parent window, needs invalidation */
8929 diff = gdk_region_copy (old_region);
8930 gdk_region_subtract (diff, new_region);
8932 /* Adjust region to parent window coords */
8933 gdk_region_offset (diff, private->x, private->y);
8935 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
8937 gdk_region_destroy (diff);
8940 gdk_region_destroy (new_region);
8941 gdk_region_destroy (old_region);
8946 do_child_shapes (GdkWindow *window,
8949 GdkWindowObject *private;
8953 private = (GdkWindowObject *) window;
8957 r.width = private->width;
8958 r.height = private->height;
8960 region = gdk_region_rectangle (&r);
8961 remove_child_area (private, NULL, FALSE, region);
8963 if (merge && private->shape)
8964 gdk_region_subtract (region, private->shape);
8966 gdk_window_shape_combine_region (window, region, 0, 0);
8970 * gdk_window_set_child_shapes:
8971 * @window: a #GdkWindow
8973 * Sets the shape mask of @window to the union of shape masks
8974 * for all children of @window, ignoring the shape mask of @window
8975 * itself. Contrast with gdk_window_merge_child_shapes() which includes
8976 * the shape mask of @window in the masks to be merged.
8979 gdk_window_set_child_shapes (GdkWindow *window)
8981 g_return_if_fail (GDK_IS_WINDOW (window));
8983 do_child_shapes (window, FALSE);
8987 * gdk_window_merge_child_shapes:
8988 * @window: a #GdkWindow
8990 * Merges the shape masks for any child windows into the
8991 * shape mask for @window. i.e. the union of all masks
8992 * for @window and its children will become the new mask
8993 * for @window. See gdk_window_shape_combine_mask().
8995 * This function is distinct from gdk_window_set_child_shapes()
8996 * because it includes @window's shape mask in the set of shapes to
9000 gdk_window_merge_child_shapes (GdkWindow *window)
9002 g_return_if_fail (GDK_IS_WINDOW (window));
9004 do_child_shapes (window, TRUE);
9008 * gdk_window_input_shape_combine_mask:
9009 * @window: a #GdkWindow
9010 * @mask: (allow-none): shape mask, or %NULL
9011 * @x: X position of shape mask with respect to @window
9012 * @y: Y position of shape mask with respect to @window
9014 * Like gdk_window_shape_combine_mask(), but the shape applies
9015 * only to event handling. Mouse events which happen while
9016 * the pointer position corresponds to an unset bit in the
9017 * mask will be passed on the window below @window.
9019 * An input shape is typically used with RGBA windows.
9020 * The alpha channel of the window defines which pixels are
9021 * invisible and allows for nicely antialiased borders,
9022 * and the input shape controls where the window is
9025 * On the X11 platform, this requires version 1.1 of the
9028 * On the Win32 platform, this functionality is not present and the
9029 * function does nothing.
9034 gdk_window_input_shape_combine_mask (GdkWindow *window,
9039 GdkWindowObject *private;
9042 g_return_if_fail (GDK_IS_WINDOW (window));
9044 private = (GdkWindowObject *) window;
9047 region = _gdk_windowing_get_shape_for_mask (mask);
9051 gdk_window_input_shape_combine_region (window,
9056 gdk_region_destroy (region);
9060 * gdk_window_input_shape_combine_region:
9061 * @window: a #GdkWindow
9062 * @shape_region: region of window to be non-transparent
9063 * @offset_x: X position of @shape_region in @window coordinates
9064 * @offset_y: Y position of @shape_region in @window coordinates
9066 * Like gdk_window_shape_combine_region(), but the shape applies
9067 * only to event handling. Mouse events which happen while
9068 * the pointer position corresponds to an unset bit in the
9069 * mask will be passed on the window below @window.
9071 * An input shape is typically used with RGBA windows.
9072 * The alpha channel of the window defines which pixels are
9073 * invisible and allows for nicely antialiased borders,
9074 * and the input shape controls where the window is
9077 * On the X11 platform, this requires version 1.1 of the
9080 * On the Win32 platform, this functionality is not present and the
9081 * function does nothing.
9086 gdk_window_input_shape_combine_region (GdkWindow *window,
9087 const GdkRegion *shape_region,
9091 GdkWindowObject *private;
9092 GdkWindowImplIface *impl_iface;
9094 g_return_if_fail (GDK_IS_WINDOW (window));
9096 private = (GdkWindowObject *) window;
9098 if (GDK_WINDOW_DESTROYED (window))
9101 if (private->input_shape)
9102 gdk_region_destroy (private->input_shape);
9106 private->input_shape = gdk_region_copy (shape_region);
9107 gdk_region_offset (private->input_shape, offset_x, offset_y);
9110 private->input_shape = NULL;
9112 if (gdk_window_has_impl (private))
9114 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
9115 impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
9118 /* Pointer may have e.g. moved outside window due to the input mask change */
9119 _gdk_synthesize_crossing_events_for_geometry_change (window);
9123 do_child_input_shapes (GdkWindow *window,
9126 GdkWindowObject *private;
9130 private = (GdkWindowObject *) window;
9134 r.width = private->width;
9135 r.height = private->height;
9137 region = gdk_region_rectangle (&r);
9138 remove_child_area (private, NULL, TRUE, region);
9140 if (merge && private->shape)
9141 gdk_region_subtract (region, private->shape);
9142 if (merge && private->input_shape)
9143 gdk_region_subtract (region, private->input_shape);
9145 gdk_window_input_shape_combine_region (window, region, 0, 0);
9150 * gdk_window_set_child_input_shapes:
9151 * @window: a #GdkWindow
9153 * Sets the input shape mask of @window to the union of input shape masks
9154 * for all children of @window, ignoring the input shape mask of @window
9155 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
9156 * the input shape mask of @window in the masks to be merged.
9161 gdk_window_set_child_input_shapes (GdkWindow *window)
9163 g_return_if_fail (GDK_IS_WINDOW (window));
9165 do_child_input_shapes (window, FALSE);
9169 * gdk_window_merge_child_input_shapes:
9170 * @window: a #GdkWindow
9172 * Merges the input shape masks for any child windows into the
9173 * input shape mask for @window. i.e. the union of all input masks
9174 * for @window and its children will become the new input mask
9175 * for @window. See gdk_window_input_shape_combine_mask().
9177 * This function is distinct from gdk_window_set_child_input_shapes()
9178 * because it includes @window's input shape mask in the set of
9179 * shapes to be merged.
9184 gdk_window_merge_child_input_shapes (GdkWindow *window)
9186 g_return_if_fail (GDK_IS_WINDOW (window));
9188 do_child_input_shapes (window, TRUE);
9193 * gdk_window_set_static_gravities:
9194 * @window: a #GdkWindow
9195 * @use_static: %TRUE to turn on static gravity
9197 * Set the bit gravity of the given window to static, and flag it so
9198 * all children get static subwindow gravity. This is used if you are
9199 * implementing scary features that involve deep knowledge of the
9200 * windowing system. Don't worry about it unless you have to.
9202 * Return value: %TRUE if the server supports static gravity
9205 gdk_window_set_static_gravities (GdkWindow *window,
9206 gboolean use_static)
9208 GdkWindowObject *private;
9209 GdkWindowImplIface *impl_iface;
9211 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9213 private = (GdkWindowObject *) window;
9215 if (gdk_window_has_impl (private))
9217 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
9218 return impl_iface->set_static_gravities (window, use_static);
9225 * gdk_window_get_composited:
9226 * @window: a #GdkWindow
9228 * Determines whether @window is composited.
9230 * See gdk_window_set_composited().
9232 * Returns: %TRUE if the window is composited.
9237 gdk_window_get_composited (GdkWindow *window)
9239 GdkWindowObject *private;
9241 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9243 private = (GdkWindowObject *)window;
9245 return private->composited;
9249 * gdk_window_set_composited:
9250 * @window: a #GdkWindow
9251 * @composited: %TRUE to set the window as composited
9253 * Sets a #GdkWindow as composited, or unsets it. Composited
9254 * windows do not automatically have their contents drawn to
9255 * the screen. Drawing is redirected to an offscreen buffer
9256 * and an expose event is emitted on the parent of the composited
9257 * window. It is the responsibility of the parent's expose handler
9258 * to manually merge the off-screen content onto the screen in
9259 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
9262 * It only makes sense for child windows to be composited; see
9263 * gdk_window_set_opacity() if you need translucent toplevel
9266 * An additional effect of this call is that the area of this
9267 * window is no longer clipped from regions marked for
9268 * invalidation on its parent. Draws done on the parent
9269 * window are also no longer clipped by the child.
9271 * This call is only supported on some systems (currently,
9272 * only X11 with new enough Xcomposite and Xdamage extensions).
9273 * You must call gdk_display_supports_composite() to check if
9274 * setting a window as composited is supported before
9275 * attempting to do so.
9280 gdk_window_set_composited (GdkWindow *window,
9281 gboolean composited)
9283 GdkWindowObject *private = (GdkWindowObject *)window;
9284 GdkDisplay *display;
9286 g_return_if_fail (GDK_IS_WINDOW (window));
9288 composited = composited != FALSE;
9290 if (private->composited == composited)
9294 gdk_window_ensure_native (window);
9296 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
9298 if (!gdk_display_supports_composite (display) && composited)
9300 g_warning ("gdk_window_set_composited called but "
9301 "compositing is not supported");
9305 _gdk_windowing_window_set_composited (window, composited);
9307 recompute_visible_regions (private, TRUE, FALSE);
9309 if (GDK_WINDOW_IS_MAPPED (window))
9310 gdk_window_invalidate_in_parent (private);
9312 private->composited = composited;
9317 remove_redirect_from_children (GdkWindowObject *private,
9318 GdkWindowRedirect *redirect)
9321 GdkWindowObject *child;
9323 for (l = private->children; l != NULL; l = l->next)
9327 /* Don't redirect this child if it already has another redirect */
9328 if (child->redirect == redirect)
9330 child->redirect = NULL;
9331 remove_redirect_from_children (child, redirect);
9337 * gdk_window_remove_redirection:
9338 * @window: a #GdkWindow
9340 * Removes any active redirection started by
9341 * gdk_window_redirect_to_drawable().
9346 gdk_window_remove_redirection (GdkWindow *window)
9348 GdkWindowObject *private;
9350 g_return_if_fail (GDK_IS_WINDOW (window));
9352 private = (GdkWindowObject *) window;
9354 if (private->redirect &&
9355 private->redirect->redirected == private)
9357 remove_redirect_from_children (private, private->redirect);
9358 gdk_window_redirect_free (private->redirect);
9359 private->redirect = NULL;
9364 * gdk_window_get_modal_hint:
9365 * @window: A toplevel #GdkWindow.
9367 * Determines whether or not the window manager is hinted that @window
9368 * has modal behaviour.
9370 * Return value: whether or not the window has the modal hint set.
9375 gdk_window_get_modal_hint (GdkWindow *window)
9377 GdkWindowObject *private;
9379 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9381 private = (GdkWindowObject*) window;
9383 return private->modal_hint;
9387 * gdk_window_get_accept_focus:
9388 * @window: a toplevel #GdkWindow.
9390 * Determines whether or not the desktop environment shuld be hinted that
9391 * the window does not want to receive input focus.
9393 * Return value: whether or not the window should receive input focus.
9398 gdk_window_get_accept_focus (GdkWindow *window)
9400 GdkWindowObject *private;
9402 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9404 private = (GdkWindowObject *)window;
9406 return private->accept_focus;
9410 * gdk_window_get_focus_on_map:
9411 * @window: a toplevel #GdkWindow.
9413 * Determines whether or not the desktop environment should be hinted that the
9414 * window does not want to receive input focus when it is mapped.
9416 * Return value: whether or not the window wants to receive input focus when
9422 gdk_window_get_focus_on_map (GdkWindow *window)
9424 GdkWindowObject *private;
9426 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9428 private = (GdkWindowObject *)window;
9430 return private->focus_on_map;
9434 * gdk_window_is_input_only:
9435 * @window: a toplevel #GdkWindow
9437 * Determines whether or not the window is an input only window.
9439 * Return value: %TRUE if @window is input only
9444 gdk_window_is_input_only (GdkWindow *window)
9446 GdkWindowObject *private;
9448 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9450 private = (GdkWindowObject *)window;
9452 return private->input_only;
9456 * gdk_window_is_shaped:
9457 * @window: a toplevel #GdkWindow
9459 * Determines whether or not the window is shaped.
9461 * Return value: %TRUE if @window is shaped
9466 gdk_window_is_shaped (GdkWindow *window)
9468 GdkWindowObject *private;
9470 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9472 private = (GdkWindowObject *)window;
9474 return private->shaped;
9478 apply_redirect_to_children (GdkWindowObject *private,
9479 GdkWindowRedirect *redirect)
9482 GdkWindowObject *child;
9484 for (l = private->children; l != NULL; l = l->next)
9488 /* Don't redirect this child if it already has another redirect */
9489 if (!child->redirect)
9491 child->redirect = redirect;
9492 apply_redirect_to_children (child, redirect);
9498 * gdk_window_redirect_to_drawable:
9499 * @window: a #GdkWindow
9500 * @drawable: a #GdkDrawable
9501 * @src_x: x position in @window
9502 * @src_y: y position in @window
9503 * @dest_x: x position in @drawable
9504 * @dest_y: y position in @drawable
9505 * @width: width of redirection, or -1 to use the width of @window
9506 * @height: height of redirection or -1 to use the height of @window
9508 * Redirects drawing into @window so that drawing to the
9509 * window in the rectangle specified by @src_x, @src_y,
9510 * @width and @height is also drawn into @drawable at
9513 * Only drawing between gdk_window_begin_paint_region() or
9514 * gdk_window_begin_paint_rect() and gdk_window_end_paint() is
9517 * Redirection is active until gdk_window_remove_redirection()
9523 gdk_window_redirect_to_drawable (GdkWindow *window,
9524 GdkDrawable *drawable,
9532 GdkWindowObject *private;
9534 g_return_if_fail (GDK_IS_WINDOW (window));
9535 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
9536 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
9538 private = (GdkWindowObject *) window;
9540 if (private->redirect)
9541 gdk_window_remove_redirection (window);
9543 if (width == -1 || height == -1)
9546 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
9553 private->redirect = g_new0 (GdkWindowRedirect, 1);
9554 private->redirect->redirected = private;
9555 private->redirect->pixmap = g_object_ref (drawable);
9556 private->redirect->src_x = src_x;
9557 private->redirect->src_y = src_y;
9558 private->redirect->dest_x = dest_x;
9559 private->redirect->dest_y = dest_y;
9560 private->redirect->width = width;
9561 private->redirect->height = height;
9563 apply_redirect_to_children (private, private->redirect);
9567 window_get_size_rectangle (GdkWindow *window,
9570 GdkWindowObject *private = (GdkWindowObject *) window;
9572 rect->x = rect->y = 0;
9573 rect->width = private->width;
9574 rect->height = private->height;
9577 /* Calculates the real clipping region for a window, in window coordinates,
9578 * taking into account other windows, gc clip region and gc clip mask.
9581 _gdk_window_calculate_full_clip_region (GdkWindow *window,
9582 GdkWindow *base_window,
9583 gboolean do_children,
9584 gint *base_x_offset,
9585 gint *base_y_offset)
9587 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
9588 GdkRectangle visible_rect;
9589 GdkRegion *real_clip_region, *tmpreg;
9590 gint x_offset, y_offset;
9591 GdkWindowObject *parentwin, *lastwin;
9598 if (!private->viewable || private->input_only)
9599 return gdk_region_new ();
9601 window_get_size_rectangle (window, &visible_rect);
9603 /* real_clip_region is in window coordinates */
9604 real_clip_region = gdk_region_rectangle (&visible_rect);
9606 x_offset = y_offset = 0;
9610 parentwin = lastwin;
9612 parentwin = lastwin->parent;
9614 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
9615 for (; parentwin != NULL &&
9616 (parentwin == private || lastwin != (GdkWindowObject*) base_window);
9617 lastwin = parentwin, parentwin = lastwin->parent)
9620 GdkRectangle real_clip_rect;
9622 if (parentwin != private)
9624 x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
9625 y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
9628 /* children is ordered in reverse stack order */
9629 for (cur = parentwin->children;
9630 cur && cur->data != lastwin;
9633 GdkWindow *child = cur->data;
9634 GdkWindowObject *child_private = (GdkWindowObject *)child;
9636 if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
9639 /* Ignore offscreen children, as they don't draw in their parent and
9640 * don't take part in the clipping */
9641 if (gdk_window_is_offscreen (child_private))
9644 window_get_size_rectangle (child, &visible_rect);
9646 /* Convert rect to "window" coords */
9647 visible_rect.x += child_private->x - x_offset;
9648 visible_rect.y += child_private->y - y_offset;
9650 /* This shortcut is really necessary for performance when there are a lot of windows */
9651 gdk_region_get_clipbox (real_clip_region, &real_clip_rect);
9652 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
9653 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
9654 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
9655 visible_rect.y + visible_rect.height <= real_clip_rect.y)
9658 tmpreg = gdk_region_rectangle (&visible_rect);
9659 gdk_region_subtract (real_clip_region, tmpreg);
9660 gdk_region_destroy (tmpreg);
9663 /* Clip to the parent */
9664 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
9665 /* Convert rect to "window" coords */
9666 visible_rect.x += - x_offset;
9667 visible_rect.y += - y_offset;
9669 tmpreg = gdk_region_rectangle (&visible_rect);
9670 gdk_region_intersect (real_clip_region, tmpreg);
9671 gdk_region_destroy (tmpreg);
9675 *base_x_offset = x_offset;
9677 *base_y_offset = y_offset;
9679 return real_clip_region;
9683 _gdk_window_add_damage (GdkWindow *toplevel,
9684 GdkRegion *damaged_region)
9686 GdkDisplay *display;
9687 GdkEvent event = { 0, };
9688 event.expose.type = GDK_DAMAGE;
9689 event.expose.window = toplevel;
9690 event.expose.send_event = FALSE;
9691 event.expose.region = damaged_region;
9692 gdk_region_get_clipbox (event.expose.region, &event.expose.area);
9693 display = gdk_drawable_get_display (event.expose.window);
9694 _gdk_event_queue_append (display, gdk_event_copy (&event));
9698 gdk_window_redirect_free (GdkWindowRedirect *redirect)
9700 g_object_unref (redirect->pixmap);
9704 /* Gets the toplevel for a window as used for events,
9705 i.e. including offscreen parents */
9706 static GdkWindowObject *
9707 get_event_parent (GdkWindowObject *window)
9709 if (gdk_window_is_offscreen (window))
9710 return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
9712 return window->parent;
9715 /* Gets the toplevel for a window as used for events,
9716 i.e. including offscreen parents going up to the native
9719 get_event_toplevel (GdkWindow *w)
9721 GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
9722 GdkWindowObject *parent;
9724 while ((parent = get_event_parent (private)) != NULL &&
9725 (parent->window_type != GDK_WINDOW_ROOT))
9728 return GDK_WINDOW (private);
9732 _gdk_window_event_parent_of (GdkWindow *parent,
9743 w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
9750 update_cursor (GdkDisplay *display,
9753 GdkWindowObject *cursor_window, *parent, *toplevel;
9754 GdkWindow *pointer_window;
9755 GdkWindowImplIface *impl_iface;
9756 GdkPointerWindowInfo *pointer_info;
9757 GdkDeviceGrabInfo *grab;
9759 pointer_info = _gdk_display_get_pointer_info (display, device);
9760 pointer_window = pointer_info->window_under_pointer;
9762 /* We ignore the serials here and just pick the last grab
9763 we've sent, as that would shortly be used anyway. */
9764 grab = _gdk_display_get_last_device_grab (display, device);
9767 /* the pointer is not in a descendant of the grab window */
9768 !_gdk_window_event_parent_of (grab->window, pointer_window))
9770 /* use the cursor from the grab window */
9771 cursor_window = (GdkWindowObject *) grab->window;
9775 /* otherwise use the cursor from the pointer window */
9776 cursor_window = (GdkWindowObject *) pointer_window;
9779 /* Find the first window with the cursor actually set, as
9780 the cursor is inherited from the parent */
9781 while (cursor_window->cursor == NULL &&
9782 (parent = get_event_parent (cursor_window)) != NULL &&
9783 parent->window_type != GDK_WINDOW_ROOT)
9784 cursor_window = parent;
9786 /* Set all cursors on toplevel, otherwise its tricky to keep track of
9787 * which native window has what cursor set. */
9788 toplevel = (GdkWindowObject *) get_event_toplevel (pointer_window);
9789 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
9790 impl_iface->set_device_cursor ((GdkWindow *) toplevel, device,
9791 cursor_window->cursor);
9795 point_in_window (GdkWindowObject *window,
9800 x >= 0 && x < window->width &&
9801 y >= 0 && y < window->height &&
9802 (window->shape == NULL ||
9803 gdk_region_point_in (window->shape,
9805 (window->input_shape == NULL ||
9806 gdk_region_point_in (window->input_shape,
9811 convert_native_coords_to_toplevel (GdkWindow *window,
9814 gdouble *toplevel_x,
9815 gdouble *toplevel_y)
9817 GdkWindowObject *private = (GdkWindowObject *)window;
9823 while (!gdk_window_is_toplevel (private))
9827 private = private->parent;
9833 return (GdkWindow *)private;
9837 convert_toplevel_coords_to_window (GdkWindow *window,
9843 GdkWindowObject *private;
9844 GdkWindowObject *parent;
9846 GList *children, *l;
9848 private = GDK_WINDOW_OBJECT (window);
9854 while ((parent = get_event_parent (private)) != NULL &&
9855 (parent->window_type != GDK_WINDOW_ROOT))
9857 children = g_list_prepend (children, private);
9861 for (l = children; l != NULL; l = l->next)
9862 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
9864 g_list_free (children);
9870 static GdkWindowObject *
9871 pick_embedded_child (GdkWindowObject *window,
9875 GdkWindowObject *res;
9878 g_signal_emit (window,
9879 signals[PICK_EMBEDDED_CHILD], 0,
9886 _gdk_window_find_child_at (GdkWindow *window,
9890 GdkWindowObject *private, *sub;
9891 double child_x, child_y;
9894 private = (GdkWindowObject *)window;
9896 if (point_in_window (private, x, y))
9898 /* Children is ordered in reverse stack order, i.e. first is topmost */
9899 for (l = private->children; l != NULL; l = l->next)
9903 if (!GDK_WINDOW_IS_MAPPED (sub))
9906 gdk_window_coords_from_parent ((GdkWindow *)sub,
9908 &child_x, &child_y);
9909 if (point_in_window (sub, child_x, child_y))
9910 return (GdkWindow *)sub;
9913 if (private->num_offscreen_children > 0)
9915 sub = pick_embedded_child (private,
9918 return (GdkWindow *)sub;
9926 _gdk_window_find_descendant_at (GdkWindow *toplevel,
9932 GdkWindowObject *private, *sub;
9933 gdouble child_x, child_y;
9937 private = (GdkWindowObject *)toplevel;
9939 if (point_in_window (private, x, y))
9944 /* Children is ordered in reverse stack order, i.e. first is topmost */
9945 for (l = private->children; l != NULL; l = l->next)
9949 if (!GDK_WINDOW_IS_MAPPED (sub))
9952 gdk_window_coords_from_parent ((GdkWindow *)sub,
9954 &child_x, &child_y);
9955 if (point_in_window (sub, child_x, child_y))
9965 private->num_offscreen_children > 0)
9967 sub = pick_embedded_child (private,
9973 from_embedder (sub, x, y, &x, &y);
9981 /* Not in window at all */
9990 return (GdkWindow *)private;
9995 * @window: a toplevel #GdkWindow
9997 * Emits a short beep associated to @window in the appropriate
9998 * display, if supported. Otherwise, emits a short beep on
9999 * the display just as gdk_display_beep().
10004 gdk_window_beep (GdkWindow *window)
10006 GdkDisplay *display;
10007 GdkWindow *toplevel;
10009 g_return_if_fail (GDK_IS_WINDOW (window));
10011 if (GDK_WINDOW_DESTROYED (window))
10014 toplevel = get_event_toplevel (window);
10015 display = gdk_drawable_get_display (GDK_DRAWABLE (window));
10017 if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
10018 _gdk_windowing_window_beep (toplevel);
10020 gdk_display_beep (display);
10024 * gdk_window_set_support_multidevice:
10025 * @window: a #GdkWindow.
10026 * @support_multidevice: %TRUE to enable multidevice support in @window.
10028 * This function will enable multidevice features in @window.
10030 * Multidevice aware windows will need to handle properly multiple,
10031 * per device enter/leave events, device grabs and grab ownerships.
10036 gdk_window_set_support_multidevice (GdkWindow *window,
10037 gboolean support_multidevice)
10039 GdkWindowObject *private = (GdkWindowObject *) window;
10041 g_return_if_fail (GDK_IS_WINDOW (window));
10043 if (GDK_WINDOW_DESTROYED (window))
10046 if (private->support_multidevice == support_multidevice)
10049 private->support_multidevice = support_multidevice;
10051 /* FIXME: What to do if called when some pointers are inside the window ? */
10055 * gdk_window_get_support_multidevice:
10056 * @window: a #GdkWindow.
10058 * Returns %TRUE if the window is aware of the existence of multiple
10061 * Returns: %TRUE if the window handles multidevice features.
10066 gdk_window_get_support_multidevice (GdkWindow *window)
10068 GdkWindowObject *private = (GdkWindowObject *) window;
10070 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
10072 if (GDK_WINDOW_DESTROYED (window))
10075 return private->support_multidevice;
10078 static const guint type_masks[] = {
10079 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
10080 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
10081 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
10082 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
10083 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
10084 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
10085 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
10086 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
10087 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
10088 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
10089 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
10090 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
10091 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
10092 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
10093 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
10094 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
10095 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
10096 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
10097 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
10098 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
10099 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
10100 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
10101 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
10102 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
10103 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
10104 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
10105 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
10106 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
10107 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
10108 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
10109 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
10110 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
10111 0, /* GDK_WINDOW_STATE = 32 */
10112 0, /* GDK_SETTING = 33 */
10113 0, /* GDK_OWNER_CHANGE = 34 */
10114 0, /* GDK_GRAB_BROKEN = 35 */
10115 0, /* GDK_DAMAGE = 36 */
10117 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
10119 /* send motion events if the right buttons are down */
10121 update_evmask_for_button_motion (guint evmask,
10122 GdkModifierType mask)
10124 if (evmask & GDK_BUTTON_MOTION_MASK &&
10125 mask & (GDK_BUTTON1_MASK |
10130 evmask |= GDK_POINTER_MOTION_MASK;
10132 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
10133 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
10134 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
10135 evmask |= GDK_POINTER_MOTION_MASK;
10141 is_button_type (GdkEventType type)
10143 return type == GDK_BUTTON_PRESS ||
10144 type == GDK_2BUTTON_PRESS ||
10145 type == GDK_3BUTTON_PRESS ||
10146 type == GDK_BUTTON_RELEASE ||
10147 type == GDK_SCROLL;
10151 is_motion_type (GdkEventType type)
10153 return type == GDK_MOTION_NOTIFY ||
10154 type == GDK_ENTER_NOTIFY ||
10155 type == GDK_LEAVE_NOTIFY;
10158 static GdkWindowObject *
10159 find_common_ancestor (GdkWindowObject *win1,
10160 GdkWindowObject *win2)
10162 GdkWindowObject *tmp;
10163 GList *path1 = NULL, *path2 = NULL;
10164 GList *list1, *list2;
10167 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
10169 path1 = g_list_prepend (path1, tmp);
10170 tmp = get_event_parent (tmp);
10174 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
10176 path2 = g_list_prepend (path2, tmp);
10177 tmp = get_event_parent (tmp);
10183 while (list1 && list2 && (list1->data == list2->data))
10185 tmp = (GdkWindowObject *)list1->data;
10186 list1 = g_list_next (list1);
10187 list2 = g_list_next (list2);
10189 g_list_free (path1);
10190 g_list_free (path2);
10196 _gdk_make_event (GdkWindow *window,
10198 GdkEvent *event_in_queue,
10199 gboolean before_event)
10201 GdkEvent *event = gdk_event_new (type);
10203 GdkModifierType the_state;
10205 the_time = gdk_event_get_time (event_in_queue);
10206 gdk_event_get_state (event_in_queue, &the_state);
10208 event->any.window = g_object_ref (window);
10209 event->any.send_event = FALSE;
10210 if (event_in_queue && event_in_queue->any.send_event)
10211 event->any.send_event = TRUE;
10215 case GDK_MOTION_NOTIFY:
10216 event->motion.time = the_time;
10217 event->motion.axes = NULL;
10218 event->motion.state = the_state;
10221 case GDK_BUTTON_PRESS:
10222 case GDK_2BUTTON_PRESS:
10223 case GDK_3BUTTON_PRESS:
10224 case GDK_BUTTON_RELEASE:
10225 event->button.time = the_time;
10226 event->button.axes = NULL;
10227 event->button.state = the_state;
10231 event->scroll.time = the_time;
10232 event->scroll.state = the_state;
10235 case GDK_KEY_PRESS:
10236 case GDK_KEY_RELEASE:
10237 event->key.time = the_time;
10238 event->key.state = the_state;
10241 case GDK_ENTER_NOTIFY:
10242 case GDK_LEAVE_NOTIFY:
10243 event->crossing.time = the_time;
10244 event->crossing.state = the_state;
10247 case GDK_PROPERTY_NOTIFY:
10248 event->property.time = the_time;
10249 event->property.state = the_state;
10252 case GDK_SELECTION_CLEAR:
10253 case GDK_SELECTION_REQUEST:
10254 case GDK_SELECTION_NOTIFY:
10255 event->selection.time = the_time;
10258 case GDK_PROXIMITY_IN:
10259 case GDK_PROXIMITY_OUT:
10260 event->proximity.time = the_time;
10263 case GDK_DRAG_ENTER:
10264 case GDK_DRAG_LEAVE:
10265 case GDK_DRAG_MOTION:
10266 case GDK_DRAG_STATUS:
10267 case GDK_DROP_START:
10268 case GDK_DROP_FINISHED:
10269 event->dnd.time = the_time;
10272 case GDK_FOCUS_CHANGE:
10273 case GDK_CONFIGURE:
10276 case GDK_CLIENT_EVENT:
10277 case GDK_VISIBILITY_NOTIFY:
10278 case GDK_NO_EXPOSE:
10286 if (event_in_queue)
10289 _gdk_event_queue_insert_before (gdk_drawable_get_display (window), event_in_queue, event);
10291 _gdk_event_queue_insert_after (gdk_drawable_get_display (window), event_in_queue, event);
10294 _gdk_event_queue_append (gdk_drawable_get_display (window), event);
10300 send_crossing_event (GdkDisplay *display,
10301 GdkWindowObject *toplevel,
10302 GdkWindowObject *window,
10304 GdkCrossingMode mode,
10305 GdkNotifyType notify_type,
10306 GdkWindow *subwindow,
10310 GdkModifierType mask,
10312 GdkEvent *event_in_queue,
10316 guint32 window_event_mask, type_event_mask;
10317 GdkDeviceGrabInfo *grab;
10318 gboolean block_event = FALSE;
10320 grab = _gdk_display_has_device_grab (display, device, serial);
10322 if (grab != NULL &&
10323 !grab->owner_events)
10325 /* !owner_event => only report events wrt grab window, ignore rest */
10326 if ((GdkWindow *)window != grab->window)
10328 window_event_mask = grab->event_mask;
10331 window_event_mask = window->event_mask;
10333 if (type == GDK_LEAVE_NOTIFY)
10335 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
10336 window->devices_inside = g_list_remove (window->devices_inside, device);
10338 if (!window->support_multidevice && window->devices_inside)
10340 /* Block leave events unless it's the last pointer */
10341 block_event = TRUE;
10346 type_event_mask = GDK_ENTER_NOTIFY_MASK;
10348 if (!window->support_multidevice && window->devices_inside)
10350 /* Only emit enter events for the first device */
10351 block_event = TRUE;
10354 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
10355 device->mode != GDK_MODE_DISABLED &&
10356 !g_list_find (window->devices_inside, device))
10357 window->devices_inside = g_list_prepend (window->devices_inside, device);
10363 if (window_event_mask & type_event_mask)
10365 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
10366 gdk_event_set_device (event, device);
10367 event->crossing.time = time_;
10368 event->crossing.subwindow = subwindow;
10370 g_object_ref (subwindow);
10371 convert_toplevel_coords_to_window ((GdkWindow *)window,
10372 toplevel_x, toplevel_y,
10373 &event->crossing.x, &event->crossing.y);
10374 event->crossing.x_root = toplevel_x + toplevel->x;
10375 event->crossing.y_root = toplevel_y + toplevel->y;
10376 event->crossing.mode = mode;
10377 event->crossing.detail = notify_type;
10378 event->crossing.focus = FALSE;
10379 event->crossing.state = mask;
10384 /* The coordinates are in the toplevel window that src/dest are in.
10385 * src and dest are always (if != NULL) in the same toplevel, as
10386 * we get a leave-notify and set the window_under_pointer to null
10387 * before crossing to another toplevel.
10390 _gdk_synthesize_crossing_events (GdkDisplay *display,
10394 GdkCrossingMode mode,
10397 GdkModifierType mask,
10399 GdkEvent *event_in_queue,
10401 gboolean non_linear)
10403 GdkWindowObject *c;
10404 GdkWindowObject *win, *last, *next;
10405 GList *path, *list;
10406 GdkWindowObject *a;
10407 GdkWindowObject *b;
10408 GdkWindowObject *toplevel;
10409 GdkNotifyType notify_type;
10411 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
10413 a = (GdkWindowObject *)src;
10414 b = (GdkWindowObject *)dest;
10416 return; /* No crossings generated between src and dest */
10418 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
10420 if (a && gdk_window_get_device_events (src, device) == 0)
10423 if (b && gdk_window_get_device_events (dest, device) == 0)
10430 c = find_common_ancestor (a, b);
10432 non_linear |= (c != a) && (c != b);
10434 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
10436 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
10438 /* Traverse up from a to (excluding) c sending leave events */
10440 notify_type = GDK_NOTIFY_NONLINEAR;
10442 notify_type = GDK_NOTIFY_INFERIOR;
10444 notify_type = GDK_NOTIFY_ANCESTOR;
10445 send_crossing_event (display, toplevel,
10446 a, GDK_LEAVE_NOTIFY,
10450 toplevel_x, toplevel_y,
10458 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
10460 notify_type = GDK_NOTIFY_VIRTUAL;
10463 win = get_event_parent (a);
10464 while (win != c && win->window_type != GDK_WINDOW_ROOT)
10466 send_crossing_event (display, toplevel,
10467 win, GDK_LEAVE_NOTIFY,
10472 toplevel_x, toplevel_y,
10478 win = get_event_parent (win);
10483 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
10485 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
10487 /* Traverse down from c to b */
10491 win = get_event_parent (b);
10492 while (win != c && win->window_type != GDK_WINDOW_ROOT)
10494 path = g_list_prepend (path, win);
10495 win = get_event_parent (win);
10499 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
10501 notify_type = GDK_NOTIFY_VIRTUAL;
10506 win = (GdkWindowObject *)list->data;
10507 list = g_list_next (list);
10509 next = (GdkWindowObject *)list->data;
10513 send_crossing_event (display, toplevel,
10514 win, GDK_ENTER_NOTIFY,
10519 toplevel_x, toplevel_y,
10524 g_list_free (path);
10529 notify_type = GDK_NOTIFY_NONLINEAR;
10531 notify_type = GDK_NOTIFY_ANCESTOR;
10533 notify_type = GDK_NOTIFY_INFERIOR;
10535 send_crossing_event (display, toplevel,
10536 b, GDK_ENTER_NOTIFY,
10541 toplevel_x, toplevel_y,
10548 /* Returns the window inside the event window with the pointer in it
10549 * at the specified coordinates, or NULL if its not in any child of
10550 * the toplevel. It also takes into account !owner_events grabs.
10553 get_pointer_window (GdkDisplay *display,
10554 GdkWindow *event_window,
10556 gdouble toplevel_x,
10557 gdouble toplevel_y,
10560 GdkWindow *pointer_window;
10561 GdkDeviceGrabInfo *grab;
10562 GdkPointerWindowInfo *pointer_info;
10564 pointer_info = _gdk_display_get_pointer_info (display, device);
10566 if (event_window == pointer_info->toplevel_under_pointer)
10568 _gdk_window_find_descendant_at (event_window,
10569 toplevel_x, toplevel_y,
10572 pointer_window = NULL;
10574 grab = _gdk_display_has_device_grab (display, device, serial);
10575 if (grab != NULL &&
10576 !grab->owner_events &&
10577 pointer_window != grab->window)
10578 pointer_window = NULL;
10580 return pointer_window;
10584 _gdk_display_set_window_under_pointer (GdkDisplay *display,
10588 GdkPointerWindowInfo *device_info;
10590 /* We don't track this if all native, and it can cause issues
10591 with the update_cursor call below */
10592 if (_gdk_native_windows)
10595 device_info = _gdk_display_get_pointer_info (display, device);
10597 if (device_info->window_under_pointer)
10598 g_object_unref (device_info->window_under_pointer);
10599 device_info->window_under_pointer = window;
10603 g_object_ref (window);
10604 update_cursor (display, device);
10607 _gdk_display_enable_motion_hints (display, device);
10611 * gdk_pointer_grab:
10612 * @window: the #GdkWindow which will own the grab (the grab window).
10613 * @owner_events: if %FALSE then all pointer events are reported with respect to
10614 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
10615 * events for this application are reported as normal, but pointer events outside
10616 * this application are reported with respect to @window and only if selected by
10617 * @event_mask. In either mode, unreported events are discarded.
10618 * @event_mask: specifies the event mask, which is used in accordance with
10619 * @owner_events. Note that only pointer events (i.e. button and motion events)
10621 * @confine_to: If non-%NULL, the pointer will be confined to this
10622 * window during the grab. If the pointer is outside @confine_to, it will
10623 * automatically be moved to the closest edge of @confine_to and enter
10624 * and leave events will be generated as necessary.
10625 * @cursor: the cursor to display while the grab is active. If this is %NULL then
10626 * the normal cursors are used for @window and its descendants, and the cursor
10627 * for @window is used for all other windows.
10628 * @time_: the timestamp of the event which led to this pointer grab. This usually
10629 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
10630 * the time isn't known.
10632 * Grabs the pointer (usually a mouse) so that all events are passed to this
10633 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
10634 * the grab window becomes unviewable.
10635 * This overrides any previous pointer grab by this client.
10637 * Pointer grabs are used for operations which need complete control over mouse
10638 * events, even if the mouse leaves the application.
10639 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
10640 * the #GtkHPaned and #GtkVPaned widgets, and for resizing columns in #GtkCList
10643 * Note that if the event mask of an X window has selected both button press and
10644 * button release events, then a button press event will cause an automatic
10645 * pointer grab until the button is released.
10646 * X does this automatically since most applications expect to receive button
10647 * press and release events in pairs.
10648 * It is equivalent to a pointer grab on the window with @owner_events set to
10651 * If you set up anything at the time you take the grab that needs to be cleaned
10652 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
10653 * are emitted when the grab ends unvoluntarily.
10655 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
10657 * Deprecated: 3.0: Use gdk_device_grab() instead.
10660 gdk_pointer_grab (GdkWindow * window,
10661 gboolean owner_events,
10662 GdkEventMask event_mask,
10663 GdkWindow * confine_to,
10664 GdkCursor * cursor,
10668 GdkDisplay *display;
10669 GdkDeviceManager *device_manager;
10671 GdkGrabStatus res = 0;
10673 GList *devices, *dev;
10675 g_return_val_if_fail (window != NULL, 0);
10676 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
10677 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
10679 /* We need a native window for confine to to work, ensure we have one */
10682 if (!gdk_window_ensure_native (confine_to))
10684 g_warning ("Can't confine to grabbed window, not native");
10689 /* Non-viewable client side window => fail */
10690 if (!_gdk_window_has_impl (window) &&
10691 !gdk_window_is_viewable (window))
10692 return GDK_GRAB_NOT_VIEWABLE;
10694 if (_gdk_native_windows)
10697 native = gdk_window_get_toplevel (window);
10698 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
10700 native = gdk_offscreen_window_get_embedder (native);
10702 if (native == NULL ||
10703 (!_gdk_window_has_impl (native) &&
10704 !gdk_window_is_viewable (native)))
10705 return GDK_GRAB_NOT_VIEWABLE;
10707 native = gdk_window_get_toplevel (native);
10710 display = gdk_drawable_get_display (window);
10712 serial = _gdk_windowing_window_get_next_serial (display);
10713 device_manager = gdk_display_get_device_manager (display);
10714 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
10716 /* FIXME: Should this be generic to all backends? */
10717 /* FIXME: What happens with extended devices? */
10718 for (dev = devices; dev; dev = dev->next)
10720 device = dev->data;
10722 if (device->source != GDK_SOURCE_MOUSE)
10725 res = _gdk_windowing_device_grab (device,
10729 get_native_grab_event_mask (event_mask),
10734 if (res == GDK_GRAB_SUCCESS)
10735 _gdk_display_add_device_grab (display,
10739 GDK_OWNERSHIP_NONE,
10747 /* FIXME: handle errors when grabbing */
10749 g_list_free (devices);
10755 * gdk_keyboard_grab:
10756 * @window: the #GdkWindow which will own the grab (the grab window).
10757 * @owner_events: if %FALSE then all keyboard events are reported with respect to
10758 * @window. If %TRUE then keyboard events for this application are
10759 * reported as normal, but keyboard events outside this application
10760 * are reported with respect to @window. Both key press and key
10761 * release events are always reported, independant of the event mask
10762 * set by the application.
10763 * @time: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
10766 * Grabs the keyboard so that all events are passed to this
10767 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
10768 * This overrides any previous keyboard grab by this client.
10770 * If you set up anything at the time you take the grab that needs to be cleaned
10771 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
10772 * are emitted when the grab ends unvoluntarily.
10774 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
10776 * Deprecated: 3.0: Use gdk_device_grab() instead.
10779 gdk_keyboard_grab (GdkWindow *window,
10780 gboolean owner_events,
10784 GdkDisplay *display;
10785 GdkDeviceManager *device_manager;
10787 GdkGrabStatus res = 0;
10789 GList *devices, *dev;
10791 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
10793 /* Non-viewable client side window => fail */
10794 if (!_gdk_window_has_impl (window) &&
10795 !gdk_window_is_viewable (window))
10796 return GDK_GRAB_NOT_VIEWABLE;
10798 if (_gdk_native_windows)
10801 native = gdk_window_get_toplevel (window);
10803 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
10805 native = gdk_offscreen_window_get_embedder (native);
10807 if (native == NULL ||
10808 (!_gdk_window_has_impl (native) &&
10809 !gdk_window_is_viewable (native)))
10810 return GDK_GRAB_NOT_VIEWABLE;
10812 native = gdk_window_get_toplevel (native);
10815 display = gdk_drawable_get_display (window);
10817 serial = _gdk_windowing_window_get_next_serial (display);
10818 device_manager = gdk_display_get_device_manager (display);
10819 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
10821 /* FIXME: Should this be generic to all backends? */
10822 /* FIXME: What happens with extended devices? */
10823 for (dev = devices; dev; dev = dev->next)
10825 device = dev->data;
10827 if (device->source != GDK_SOURCE_KEYBOARD)
10830 res = _gdk_windowing_device_grab (device,
10834 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
10839 if (res == GDK_GRAB_SUCCESS)
10840 _gdk_display_add_device_grab (display,
10844 GDK_OWNERSHIP_NONE,
10851 /* FIXME: handle errors when grabbing */
10853 g_list_free (devices);
10859 * gdk_window_geometry_changed:
10860 * @window: an embedded offscreen #GdkWindow
10862 * This function informs GDK that the geometry of an embedded
10863 * offscreen window has changed. This is necessary for GDK to keep
10864 * track of which offscreen window the pointer is in.
10869 gdk_window_geometry_changed (GdkWindow *window)
10871 _gdk_synthesize_crossing_events_for_geometry_change (window);
10875 do_synthesize_crossing_event (gpointer data)
10877 GdkDisplay *display;
10878 GdkWindow *changed_toplevel;
10879 GdkWindowObject *changed_toplevel_priv;
10880 GHashTableIter iter;
10881 gpointer key, value;
10884 changed_toplevel = data;
10885 changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
10887 changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
10889 if (GDK_WINDOW_DESTROYED (changed_toplevel))
10892 display = gdk_drawable_get_display (changed_toplevel);
10893 serial = _gdk_windowing_window_get_next_serial (display);
10894 g_hash_table_iter_init (&iter, display->pointers_info);
10896 while (g_hash_table_iter_next (&iter, &key, &value))
10898 GdkWindow *new_window_under_pointer;
10899 GdkPointerWindowInfo *pointer_info = value;
10900 GdkDevice *device = key;
10902 if (changed_toplevel == pointer_info->toplevel_under_pointer)
10904 new_window_under_pointer =
10905 get_pointer_window (display, changed_toplevel,
10907 pointer_info->toplevel_x,
10908 pointer_info->toplevel_y,
10910 if (new_window_under_pointer != pointer_info->window_under_pointer)
10912 _gdk_synthesize_crossing_events (display,
10913 pointer_info->window_under_pointer,
10914 new_window_under_pointer,
10916 GDK_CROSSING_NORMAL,
10917 pointer_info->toplevel_x,
10918 pointer_info->toplevel_y,
10919 pointer_info->state,
10924 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
10933 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
10935 GdkDisplay *display;
10936 GdkWindow *toplevel;
10937 GdkWindowObject *toplevel_priv;
10939 if (_gdk_native_windows)
10940 return; /* We use the native crossing events if all native */
10942 display = gdk_drawable_get_display (changed_window);
10944 toplevel = get_event_toplevel (changed_window);
10945 toplevel_priv = (GdkWindowObject *) toplevel;
10947 if (!toplevel_priv->synthesize_crossing_event_queued)
10949 toplevel_priv->synthesize_crossing_event_queued = TRUE;
10951 g_idle_add_full (GDK_PRIORITY_EVENTS - 1,
10952 do_synthesize_crossing_event,
10953 g_object_ref (toplevel),
10958 /* Don't use for crossing events */
10960 get_event_window (GdkDisplay *display,
10962 GdkWindow *pointer_window,
10964 GdkModifierType mask,
10969 GdkWindow *grab_window;
10970 GdkWindowObject *w;
10971 GdkDeviceGrabInfo *grab;
10973 grab = _gdk_display_has_device_grab (display, device, serial);
10975 if (grab != NULL && !grab->owner_events)
10977 evmask = grab->event_mask;
10978 evmask = update_evmask_for_button_motion (evmask, mask);
10980 grab_window = grab->window;
10982 if (evmask & type_masks[type])
10985 *evmask_out = evmask;
10986 return grab_window;
10992 w = (GdkWindowObject *)pointer_window;
10995 evmask = w->event_mask;
10996 evmask = update_evmask_for_button_motion (evmask, mask);
10998 if (evmask & type_masks[type])
11001 *evmask_out = evmask;
11002 return (GdkWindow *)w;
11005 w = get_event_parent (w);
11008 if (grab != NULL &&
11009 grab->owner_events)
11011 evmask = grab->event_mask;
11012 evmask = update_evmask_for_button_motion (evmask, mask);
11014 if (evmask & type_masks[type])
11017 *evmask_out = evmask;
11018 return grab->window;
11028 proxy_pointer_event (GdkDisplay *display,
11029 GdkEvent *source_event,
11032 GdkWindow *toplevel_window, *event_window;
11033 GdkWindow *pointer_window;
11034 GdkPointerWindowInfo *pointer_info;
11038 gdouble toplevel_x, toplevel_y;
11040 gboolean non_linear;
11042 event_window = source_event->any.window;
11043 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
11044 gdk_event_get_state (source_event, &state);
11045 time_ = gdk_event_get_time (source_event);
11046 device = gdk_event_get_device (source_event);
11047 pointer_info = _gdk_display_get_pointer_info (display, device);
11048 toplevel_window = convert_native_coords_to_toplevel (event_window,
11049 toplevel_x, toplevel_y,
11050 &toplevel_x, &toplevel_y);
11052 non_linear = FALSE;
11053 if ((source_event->type == GDK_LEAVE_NOTIFY ||
11054 source_event->type == GDK_ENTER_NOTIFY) &&
11055 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
11056 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
11059 /* If we get crossing events with subwindow unexpectedly being NULL
11060 that means there is a native subwindow that gdk doesn't know about.
11061 We track these and forward them, with the correct virtual window
11063 This is important to get right, as metacity uses gdk for the frame
11064 windows, but gdk doesn't know about the client windows reparented
11066 if (((source_event->type == GDK_LEAVE_NOTIFY &&
11067 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
11068 (source_event->type == GDK_ENTER_NOTIFY &&
11069 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
11070 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
11071 source_event->crossing.subwindow == NULL)
11073 /* Left for an unknown (to gdk) subwindow */
11075 /* Send leave events from window under pointer to event window
11076 that will get the subwindow == NULL window */
11077 _gdk_synthesize_crossing_events (display,
11078 pointer_info->window_under_pointer,
11081 source_event->crossing.mode,
11082 toplevel_x, toplevel_y,
11088 /* Send subwindow == NULL event */
11089 send_crossing_event (display,
11090 (GdkWindowObject *)toplevel_window,
11091 (GdkWindowObject *)event_window,
11092 source_event->type,
11093 source_event->crossing.mode,
11094 source_event->crossing.detail,
11097 toplevel_x, toplevel_y,
11102 _gdk_display_set_window_under_pointer (display, device, NULL);
11106 pointer_window = get_pointer_window (display, toplevel_window, device,
11107 toplevel_x, toplevel_y, serial);
11109 if (((source_event->type == GDK_ENTER_NOTIFY &&
11110 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
11111 (source_event->type == GDK_LEAVE_NOTIFY &&
11112 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
11113 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
11114 source_event->crossing.subwindow == NULL)
11116 /* Entered from an unknown (to gdk) subwindow */
11118 /* Send subwindow == NULL event */
11119 send_crossing_event (display,
11120 (GdkWindowObject *)toplevel_window,
11121 (GdkWindowObject *)event_window,
11122 source_event->type,
11123 source_event->crossing.mode,
11124 source_event->crossing.detail,
11127 toplevel_x, toplevel_y,
11132 /* Send enter events from event window to pointer_window */
11133 _gdk_synthesize_crossing_events (display,
11137 source_event->crossing.mode,
11138 toplevel_x, toplevel_y,
11141 serial, non_linear);
11142 _gdk_display_set_window_under_pointer (display, device, pointer_window);
11146 if (pointer_info->window_under_pointer != pointer_window)
11148 /* Either a toplevel crossing notify that ended up inside a child window,
11149 or a motion notify that got into another child window */
11151 /* Different than last time, send crossing events */
11152 _gdk_synthesize_crossing_events (display,
11153 pointer_info->window_under_pointer,
11156 GDK_CROSSING_NORMAL,
11157 toplevel_x, toplevel_y,
11160 serial, non_linear);
11161 _gdk_display_set_window_under_pointer (display, device, pointer_window);
11163 else if (source_event->type == GDK_MOTION_NOTIFY)
11165 GdkWindow *event_win;
11169 event_win = get_event_window (display,
11172 source_event->type,
11178 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
11179 gdk_window_get_device_events (event_win, device) == 0)
11185 (evmask & GDK_POINTER_MOTION_HINT_MASK))
11187 gulong *device_serial;
11189 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
11191 if (!device_serial ||
11192 (*device_serial != 0 &&
11193 serial < *device_serial))
11194 event_win = NULL; /* Ignore event */
11198 *device_serial = G_MAXULONG;
11202 if (event_win && !display->ignore_core_events)
11204 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
11205 event->motion.time = time_;
11206 convert_toplevel_coords_to_window (event_win,
11207 toplevel_x, toplevel_y,
11208 &event->motion.x, &event->motion.y);
11209 event->motion.x_root = source_event->motion.x_root;
11210 event->motion.y_root = source_event->motion.y_root;
11211 event->motion.state = state;
11212 event->motion.is_hint = is_hint;
11213 event->motion.device = source_event->motion.device;
11214 event->motion.axes = g_memdup (source_event->motion.axes,
11215 sizeof (gdouble) * source_event->motion.device->num_axes);
11219 /* unlink all move events from queue.
11220 We handle our own, including our emulated masks. */
11224 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
11225 GDK_BUTTON2_MASK | \
11226 GDK_BUTTON3_MASK | \
11227 GDK_BUTTON4_MASK | \
11231 proxy_button_event (GdkEvent *source_event,
11234 GdkWindow *toplevel_window, *event_window;
11235 GdkWindow *event_win;
11236 GdkWindow *pointer_window;
11237 GdkWindowObject *parent;
11242 gdouble toplevel_x, toplevel_y;
11243 GdkDisplay *display;
11244 GdkWindowObject *w;
11247 type = source_event->any.type;
11248 event_window = source_event->any.window;
11249 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
11250 gdk_event_get_state (source_event, &state);
11251 time_ = gdk_event_get_time (source_event);
11252 device = gdk_event_get_device (source_event);
11253 display = gdk_drawable_get_display (source_event->any.window);
11254 toplevel_window = convert_native_coords_to_toplevel (event_window,
11255 toplevel_x, toplevel_y,
11256 &toplevel_x, &toplevel_y);
11258 if (type == GDK_BUTTON_PRESS &&
11259 !source_event->any.send_event &&
11260 _gdk_display_has_device_grab (display, device, serial) == NULL)
11263 _gdk_window_find_descendant_at (toplevel_window,
11264 toplevel_x, toplevel_y,
11267 /* Find the event window, that gets the grab */
11268 w = (GdkWindowObject *)pointer_window;
11269 while (w != NULL &&
11270 (parent = get_event_parent (w)) != NULL &&
11271 parent->window_type != GDK_WINDOW_ROOT)
11273 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
11277 pointer_window = (GdkWindow *)w;
11279 _gdk_display_add_device_grab (display,
11283 GDK_OWNERSHIP_NONE,
11285 gdk_window_get_events (pointer_window),
11289 _gdk_display_device_grab_update (display, device, serial);
11292 pointer_window = get_pointer_window (display, toplevel_window, device,
11293 toplevel_x, toplevel_y,
11296 event_win = get_event_window (display,
11302 if (event_win == NULL || display->ignore_core_events)
11305 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
11306 gdk_window_get_device_events (event_win, device) == 0)
11309 event = _gdk_make_event (event_win, type, source_event, FALSE);
11313 case GDK_BUTTON_PRESS:
11314 case GDK_BUTTON_RELEASE:
11315 event->button.button = source_event->button.button;
11316 convert_toplevel_coords_to_window (event_win,
11317 toplevel_x, toplevel_y,
11318 &event->button.x, &event->button.y);
11319 event->button.x_root = source_event->button.x_root;
11320 event->button.y_root = source_event->button.y_root;
11321 event->button.state = state;
11322 event->button.device = source_event->button.device;
11323 event->button.axes = g_memdup (source_event->button.axes,
11324 sizeof (gdouble) * source_event->button.device->num_axes);
11326 if (type == GDK_BUTTON_PRESS)
11327 _gdk_event_button_generate (display, event);
11331 event->scroll.direction = source_event->scroll.direction;
11332 convert_toplevel_coords_to_window (event_win,
11333 toplevel_x, toplevel_y,
11334 &event->scroll.x, &event->scroll.y);
11335 event->scroll.x_root = source_event->scroll.x_root;
11336 event->scroll.y_root = source_event->scroll.y_root;
11337 event->scroll.state = state;
11338 event->scroll.device = source_event->scroll.device;
11345 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
11348 #ifdef DEBUG_WINDOW_PRINTING
11350 gdk_window_print (GdkWindowObject *window,
11354 const char *window_types[] = {
11364 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
11365 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
11366 window->x, window->y,
11367 window->width, window->height
11370 if (gdk_window_has_impl (window))
11372 #ifdef GDK_WINDOWING_X11
11373 g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
11377 if (window->window_type != GDK_WINDOW_CHILD)
11378 g_print (" %s", window_types[window->window_type]);
11380 if (window->input_only)
11381 g_print (" input-only");
11383 if (window->shaped)
11384 g_print (" shaped");
11386 if (!gdk_window_is_visible ((GdkWindow *)window))
11387 g_print (" hidden");
11389 g_print (" abs[%d,%d]",
11390 window->abs_x, window->abs_y);
11392 gdk_region_get_clipbox (window->clip_region, &r);
11393 if (gdk_region_empty (window->clip_region))
11394 g_print (" clipbox[empty]");
11396 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
11403 gdk_window_print_tree (GdkWindow *window,
11405 gboolean include_input_only)
11407 GdkWindowObject *private;
11410 private = (GdkWindowObject *)window;
11412 if (private->input_only && !include_input_only)
11415 gdk_window_print (private, indent);
11417 for (l = private->children; l != NULL; l = l->next)
11418 gdk_window_print_tree (l->data, indent + 4, include_input_only);
11421 #endif /* DEBUG_WINDOW_PRINTING */
11424 _gdk_windowing_got_event (GdkDisplay *display,
11429 GdkWindow *event_window;
11430 GdkWindowObject *event_private;
11432 gboolean unlink_event;
11433 guint old_state, old_button;
11434 GdkDeviceGrabInfo *button_release_grab;
11435 GdkPointerWindowInfo *pointer_info;
11437 gboolean is_toplevel;
11439 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
11440 display->last_event_time = gdk_event_get_time (event);
11442 device = gdk_event_get_device (event);
11448 g_object_get (device, "input-mode", &mode, NULL);
11449 _gdk_display_device_grab_update (display, device, serial);
11451 if (mode == GDK_MODE_DISABLED ||
11452 !_gdk_display_check_grab_ownership (display, device, serial))
11454 /* Device events are blocked by another
11455 * device grab, or the device is disabled
11457 unlink_event = TRUE;
11462 event_window = event->any.window;
11466 pointer_info = _gdk_display_get_pointer_info (display, device);
11467 event_private = GDK_WINDOW_OBJECT (event_window);
11469 #ifdef DEBUG_WINDOW_PRINTING
11470 if (event->type == GDK_KEY_PRESS &&
11471 (event->key.keyval == 0xa7 ||
11472 event->key.keyval == 0xbd))
11474 gdk_window_print_tree (event_window, 0,
11475 event->key.keyval == 0xbd);
11479 if (_gdk_native_windows)
11481 if (event->type == GDK_BUTTON_PRESS &&
11482 !event->any.send_event &&
11483 _gdk_display_has_device_grab (display, device, serial) == NULL)
11485 _gdk_display_add_device_grab (display,
11489 GDK_OWNERSHIP_NONE,
11491 gdk_window_get_events (event_window),
11493 gdk_event_get_time (event),
11495 _gdk_display_device_grab_update (display, device, serial);
11497 if (event->type == GDK_BUTTON_RELEASE &&
11498 !event->any.send_event)
11500 button_release_grab =
11501 _gdk_display_has_device_grab (display, device, serial);
11502 if (button_release_grab &&
11503 button_release_grab->implicit &&
11504 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
11506 button_release_grab->serial_end = serial;
11507 button_release_grab->implicit_ungrab = FALSE;
11508 _gdk_display_device_grab_update (display, device, serial);
11512 if (event->type == GDK_BUTTON_PRESS)
11513 _gdk_event_button_generate (display, event);
11518 if (event->type == GDK_VISIBILITY_NOTIFY)
11520 event_private->native_visibility = event->visibility.state;
11521 gdk_window_update_visibility_recursively (event_private,
11526 if (!(is_button_type (event->type) ||
11527 is_motion_type (event->type)) ||
11528 event_private->window_type == GDK_WINDOW_ROOT)
11531 is_toplevel = gdk_window_is_toplevel (event_private);
11533 if ((event->type == GDK_ENTER_NOTIFY ||
11534 event->type == GDK_LEAVE_NOTIFY) &&
11535 (event->crossing.mode == GDK_CROSSING_GRAB ||
11536 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
11537 (_gdk_display_has_device_grab (display, device, serial) ||
11538 event->crossing.detail == GDK_NOTIFY_INFERIOR))
11540 /* We synthesize all crossing events due to grabs ourselves,
11541 * so we ignore the native ones caused by our native pointer_grab
11542 * calls. Otherwise we would proxy these crossing event and cause
11543 * multiple copies of crossing events for grabs.
11545 * We do want to handle grabs from other clients though, as for
11546 * instance alt-tab in metacity causes grabs like these and
11547 * we want to handle those. Thus the has_pointer_grab check.
11549 * Implicit grabs on child windows create some grabbing events
11550 * that are sent before the button press. This means we can't
11551 * detect these with the has_pointer_grab check (as the implicit
11552 * grab is only noticed when we get button press event), so we
11553 * detect these events by checking for INFERIOR enter or leave
11554 * events. These should never be a problem to filter out.
11557 /* We ended up in this window after some (perhaps other clients)
11558 grab, so update the toplevel_under_window state */
11560 event->type == GDK_ENTER_NOTIFY &&
11561 event->crossing.mode == GDK_CROSSING_UNGRAB)
11563 if (pointer_info->toplevel_under_pointer)
11564 g_object_unref (pointer_info->toplevel_under_pointer);
11565 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
11568 unlink_event = TRUE;
11572 /* Track toplevel_under_pointer */
11575 if (event->type == GDK_ENTER_NOTIFY &&
11576 event->crossing.detail != GDK_NOTIFY_INFERIOR)
11578 if (pointer_info->toplevel_under_pointer)
11579 g_object_unref (pointer_info->toplevel_under_pointer);
11580 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
11582 else if (event->type == GDK_LEAVE_NOTIFY &&
11583 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
11584 pointer_info->toplevel_under_pointer == event_window)
11586 if (pointer_info->toplevel_under_pointer)
11587 g_object_unref (pointer_info->toplevel_under_pointer);
11588 pointer_info->toplevel_under_pointer = NULL;
11592 /* Store last pointer window and position/state */
11593 old_state = pointer_info->state;
11594 old_button = pointer_info->button;
11596 gdk_event_get_coords (event, &x, &y);
11597 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
11598 pointer_info->toplevel_x = x;
11599 pointer_info->toplevel_y = y;
11600 gdk_event_get_state (event, &pointer_info->state);
11601 if (event->type == GDK_BUTTON_PRESS ||
11602 event->type == GDK_BUTTON_RELEASE)
11603 pointer_info->button = event->button.button;
11606 (pointer_info->state != old_state ||
11607 pointer_info->button != old_button))
11608 _gdk_display_enable_motion_hints (display, device);
11610 unlink_event = FALSE;
11611 if (is_motion_type (event->type))
11612 unlink_event = proxy_pointer_event (display,
11615 else if (is_button_type (event->type))
11616 unlink_event = proxy_button_event (event,
11619 if (event->type == GDK_BUTTON_RELEASE &&
11620 !event->any.send_event)
11622 button_release_grab =
11623 _gdk_display_has_device_grab (display, device, serial);
11624 if (button_release_grab &&
11625 button_release_grab->implicit &&
11626 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
11628 button_release_grab->serial_end = serial;
11629 button_release_grab->implicit_ungrab = FALSE;
11630 _gdk_display_device_grab_update (display, device, serial);
11637 _gdk_event_queue_remove_link (display, event_link);
11638 g_list_free_1 (event_link);
11639 gdk_event_free (event);
11645 get_extension_event_window (GdkDisplay *display,
11646 GdkWindow *pointer_window,
11651 GdkWindow *grab_window;
11652 GdkWindowObject *w;
11653 GdkDeviceGrabInfo *grab;
11655 /* FIXME: which device? */
11656 grab = _gdk_display_has_device_grab (display, display->core_pointer, serial);
11658 if (grab != NULL && !grab->owner_events)
11660 evmask = grab->event_mask;
11662 grab_window = grab->window;
11664 if (evmask & type_masks[type])
11665 return grab_window;
11670 w = (GdkWindowObject *)pointer_window;
11673 evmask = w->extension_events;
11675 if (evmask & type_masks[type])
11676 return (GdkWindow *)w;
11678 w = get_event_parent (w);
11681 if (grab != NULL &&
11682 grab->owner_events)
11684 evmask = grab->event_mask;
11686 if (evmask & type_masks[type])
11687 return grab->window;
11697 _gdk_window_get_input_window_for_event (GdkWindow *native_window,
11698 GdkEventType event_type,
11702 GdkDisplay *display;
11703 GdkWindow *toplevel_window;
11704 GdkWindow *pointer_window;
11705 GdkWindow *event_win;
11706 gdouble toplevel_x, toplevel_y;
11711 display = gdk_drawable_get_display (native_window);
11712 toplevel_window = convert_native_coords_to_toplevel (native_window,
11713 toplevel_x, toplevel_y,
11714 &toplevel_x, &toplevel_y);
11715 /* FIXME: which device? */
11716 pointer_window = get_pointer_window (display, toplevel_window, NULL,
11717 toplevel_x, toplevel_y, serial);
11718 event_win = get_extension_event_window (display,
11727 #define __GDK_WINDOW_C__
11728 #include "gdkaliasdef.c"