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/.
29
#include "gdkwindow.h"
30
#include "gdkwindowimpl.h"
31
#include "gdkinternals.h"
32
#include "gdk.h" /* For gdk_rectangle_union() */
33
#include "gdkpixmap.h"
34
#include "gdkdrawable.h"
36
#include "gdkscreen.h"
37
#include "gdkmarshalers.h"
40
#undef DEBUG_WINDOW_PRINTING
42
#ifdef GDK_WINDOWING_X11
43
#include "x11/gdkx.h" /* For workaround */
48
/* Historically a GdkWindow always matches a platform native window,
49
* be it a toplevel window or a child window. In this setup the
50
* GdkWindow (and other GdkDrawables) were platform independent classes,
51
* and the actual platform specific implementation was in a delegate
52
* object availible as "impl" in the window object.
54
* With the addition of client side windows and offscreen windows this
55
* changes a bit. The application-visible GdkWindow object behaves as
56
* it did before, but not all such windows now have a corresponding native
57
* window. Instead windows that are "client side" are emulated by the gdk
58
* code such that clipping, drawing, moving, events etc work as expected.
60
* For GdkWindows that have a native window the "impl" object is the
61
* same as before. However, for all client side windows the impl object
62
* is shared with its parent (i.e. all client windows descendants of one
63
* native window has the same impl.
65
* Additionally there is a new type of platform independent impl object,
66
* GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
67
* of this type (while their children are generally GDK_WINDOW_CHILD virtual
68
* windows). Such windows work by allocating a GdkPixmap as the backing store
69
* for drawing operations, which is resized with the window.
71
* GdkWindows have a pointer to the "impl window" they are in, i.e.
72
* the topmost GdkWindow which have the same "impl" value. This is stored
73
* in impl_window, which is different from the window itself only for client
75
* All GdkWindows (native or not) track the position of the window in the parent
76
* (x, y), the size of the window (width, height), the position of the window
77
* with respect to the impl window (abs_x, abs_y). We also track the clip
78
* region of the window wrt parent windows and siblings, in window-relative
79
* coordinates with and without child windows included (clip_region,
80
* clip_region_with_children).
82
* All toplevel windows are native windows, but also child windows can be
83
* native (although not children of offscreens). We always listen to
84
* a basic set of events (see get_native_event_mask) for these windows
85
* so that we can emulate events for any client side children.
87
* For native windows we apply the calculated clip region as a window shape
88
* so that eg. client side siblings that overlap the native child properly
89
* draws over the native child window.
91
* In order to minimize flicker and for performance we use a couple of cacheing
92
* tricks. First of all, every time we do a window to window copy area, for instance
93
* when moving a client side window or when scrolling/moving a region in a window
94
* we store this in outstanding_moves instead of applying immediately. We then
95
* delay this move until we really need it (because something depends on being
96
* able to read it), or until we're handing a redraw from an expose/invalidation
97
* (actually we delay it past redraw, but before blitting the double buffer pixmap
98
* to the window). This gives us two advantages. First of all it minimizes the time
99
* from the window is moved to the exposes related to that move, secondly it allows
100
* us to be smart about how to do the copy. We combine multiple moves into one (when
101
* possible) and we don't actually do copies to anything that is or will be
102
* invalidated and exposed anyway.
104
* Secondly, we use something called a "implicit paint" during repaint handling.
105
* An implicit paint is similar to a regular paint for the paint stack, but it is
106
* not put on the stack. Instead, it is set on the impl window, and later when
107
* regular gdk_window_begin_paint_region() happen on a window of this impl window
108
* we reuse the pixmap from the implicit paint. During repaint we create and at the
109
* end flush an implicit paint, which means we can collect all the paints on
110
* multiple client side windows in the same backing store pixmap.
112
* All drawing to windows are wrapped with macros that set up the GC such that
113
* the offsets and clip region is right for drawing to the paint object or
114
* directly to the emulated window. It also automatically handles any flushing
115
* needed when drawing directly to a window. Adding window/paint clipping is
116
* done using _gdk_gc_add_drawable_clip which lets us efficiently add and then
117
* remove a custom clip region.
120
#define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
122
/* This adds a local value to the GdkVisibilityState enum */
123
#define GDK_VISIBILITY_NOT_VIEWABLE 3
126
PICK_EMBEDDED_CHILD, /* only called if children are embedded */
139
CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
143
struct _GdkWindowPaint
149
cairo_surface_t *surface;
150
guint uses_implicit : 1;
156
GdkRegion *dest_region; /* The destination region */
157
int dx, dy; /* The amount that the source was moved to reach dest_region */
158
} GdkWindowRegionMove;
163
static GdkGC *gdk_window_create_gc (GdkDrawable *drawable,
165
GdkGCValuesMask mask);
166
static void gdk_window_draw_rectangle (GdkDrawable *drawable,
173
static void gdk_window_draw_arc (GdkDrawable *drawable,
182
static void gdk_window_draw_polygon (GdkDrawable *drawable,
187
static void gdk_window_draw_text (GdkDrawable *drawable,
194
static void gdk_window_draw_text_wc (GdkDrawable *drawable,
199
const GdkWChar *text,
201
static void gdk_window_draw_drawable (GdkDrawable *drawable,
210
GdkDrawable *original_src);
211
static void gdk_window_draw_points (GdkDrawable *drawable,
215
static void gdk_window_draw_segments (GdkDrawable *drawable,
219
static void gdk_window_draw_lines (GdkDrawable *drawable,
224
static void gdk_window_draw_glyphs (GdkDrawable *drawable,
229
PangoGlyphString *glyphs);
230
static void gdk_window_draw_glyphs_transformed (GdkDrawable *drawable,
236
PangoGlyphString *glyphs);
238
static void gdk_window_draw_image (GdkDrawable *drawable,
248
static void gdk_window_draw_pixbuf (GdkDrawable *drawable,
261
static void gdk_window_draw_trapezoids (GdkDrawable *drawable,
263
GdkTrapezoid *trapezoids,
266
static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
275
static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
276
static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
279
static void gdk_window_drop_cairo_surface (GdkWindowObject *private);
280
static void gdk_window_set_cairo_clip (GdkDrawable *drawable,
283
static void gdk_window_real_get_size (GdkDrawable *drawable,
287
static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable);
288
static gint gdk_window_real_get_depth (GdkDrawable *drawable);
289
static GdkScreen* gdk_window_real_get_screen (GdkDrawable *drawable);
290
static void gdk_window_real_set_colormap (GdkDrawable *drawable,
292
static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
294
static GdkDrawable* gdk_window_get_source_drawable (GdkDrawable *drawable);
295
static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable,
300
gint *composite_x_offset,
301
gint *composite_y_offset);
302
static GdkRegion* gdk_window_get_clip_region (GdkDrawable *drawable);
303
static GdkRegion* gdk_window_get_visible_region (GdkDrawable *drawable);
305
static void gdk_window_free_paint_stack (GdkWindow *window);
307
static void gdk_window_init (GdkWindowObject *window);
308
static void gdk_window_class_init (GdkWindowObjectClass *klass);
309
static void gdk_window_finalize (GObject *object);
311
static void gdk_window_set_property (GObject *object,
315
static void gdk_window_get_property (GObject *object,
320
static void gdk_window_clear_backing_region (GdkWindow *window,
322
static void gdk_window_redirect_free (GdkWindowRedirect *redirect);
323
static void apply_redirect_to_children (GdkWindowObject *private,
324
GdkWindowRedirect *redirect);
325
static void remove_redirect_from_children (GdkWindowObject *private,
326
GdkWindowRedirect *redirect);
328
static void recompute_visible_regions (GdkWindowObject *private,
329
gboolean recalculate_siblings,
330
gboolean recalculate_children);
331
static void gdk_window_flush_outstanding_moves (GdkWindow *window);
332
static void gdk_window_flush_recursive (GdkWindowObject *window);
333
static void do_move_region_bits_on_impl (GdkWindowObject *private,
334
GdkRegion *region, /* In impl window coords */
336
static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
337
static void move_native_children (GdkWindowObject *private);
338
static void update_cursor (GdkDisplay *display);
339
static void impl_window_add_update_area (GdkWindowObject *impl_window,
341
static void gdk_window_region_move_free (GdkWindowRegionMove *move);
342
static void gdk_window_invalidate_region_full (GdkWindow *window,
343
const GdkRegion *region,
344
gboolean invalidate_children,
346
static void gdk_window_invalidate_rect_full (GdkWindow *window,
347
const GdkRectangle *rect,
348
gboolean invalidate_children,
351
static guint signals[LAST_SIGNAL] = { 0 };
353
static gpointer parent_class = NULL;
355
static const cairo_user_data_key_t gdk_window_cairo_key;
358
new_region_tag (void)
360
static guint32 tag = 0;
366
gdk_window_object_get_type (void)
368
static GType object_type = 0;
371
object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
373
sizeof (GdkWindowObjectClass),
374
(GClassInitFunc) gdk_window_class_init,
375
sizeof (GdkWindowObject),
376
(GInstanceInitFunc) gdk_window_init,
383
_gdk_paintable_get_type (void)
385
static GType paintable_type = 0;
389
const GTypeInfo paintable_info =
391
sizeof (GdkPaintableIface), /* class_size */
392
NULL, /* base_init */
393
NULL, /* base_finalize */
396
paintable_type = g_type_register_static (G_TYPE_INTERFACE,
397
g_intern_static_string ("GdkPaintable"),
400
g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
403
return paintable_type;
407
gdk_window_init (GdkWindowObject *window)
409
/* 0-initialization is good for all other fields. */
411
window->window_type = GDK_WINDOW_CHILD;
413
window->state = GDK_WINDOW_STATE_WITHDRAWN;
416
window->toplevel_window_type = -1;
418
window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
419
window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
420
/* Default to unobscured since some backends don't send visibility events */
421
window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
424
/* Stop and return on the first non-NULL parent */
426
accumulate_get_window (GSignalInvocationHint *ihint,
428
const GValue *handler_return,
431
g_value_copy (handler_return, return_accu);
432
/* Continue while returning NULL */
433
return g_value_get_object (handler_return) == NULL;
436
static GQuark quark_pointer_window = 0;
439
gdk_window_class_init (GdkWindowObjectClass *klass)
441
GObjectClass *object_class = G_OBJECT_CLASS (klass);
442
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
444
parent_class = g_type_class_peek_parent (klass);
446
object_class->finalize = gdk_window_finalize;
447
object_class->set_property = gdk_window_set_property;
448
object_class->get_property = gdk_window_get_property;
450
drawable_class->create_gc = gdk_window_create_gc;
451
drawable_class->draw_rectangle = gdk_window_draw_rectangle;
452
drawable_class->draw_arc = gdk_window_draw_arc;
453
drawable_class->draw_polygon = gdk_window_draw_polygon;
454
drawable_class->draw_text = gdk_window_draw_text;
455
drawable_class->draw_text_wc = gdk_window_draw_text_wc;
456
drawable_class->draw_drawable_with_src = gdk_window_draw_drawable;
457
drawable_class->draw_points = gdk_window_draw_points;
458
drawable_class->draw_segments = gdk_window_draw_segments;
459
drawable_class->draw_lines = gdk_window_draw_lines;
460
drawable_class->draw_glyphs = gdk_window_draw_glyphs;
461
drawable_class->draw_glyphs_transformed = gdk_window_draw_glyphs_transformed;
462
drawable_class->draw_image = gdk_window_draw_image;
463
drawable_class->draw_pixbuf = gdk_window_draw_pixbuf;
464
drawable_class->draw_trapezoids = gdk_window_draw_trapezoids;
465
drawable_class->get_depth = gdk_window_real_get_depth;
466
drawable_class->get_screen = gdk_window_real_get_screen;
467
drawable_class->get_size = gdk_window_real_get_size;
468
drawable_class->set_colormap = gdk_window_real_set_colormap;
469
drawable_class->get_colormap = gdk_window_real_get_colormap;
470
drawable_class->get_visual = gdk_window_real_get_visual;
471
drawable_class->_copy_to_image = gdk_window_copy_to_image;
472
drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
473
drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
474
drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
475
drawable_class->get_clip_region = gdk_window_get_clip_region;
476
drawable_class->get_visible_region = gdk_window_get_visible_region;
477
drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
478
drawable_class->get_source_drawable = gdk_window_get_source_drawable;
480
quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
488
* The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
489
* gdk_window_get_cursor() for details.
493
g_object_class_install_property (object_class,
495
g_param_spec_boxed ("cursor",
502
* GdkWindow::pick-embedded-child:
503
* @window: the window on which the signal is emitted
504
* @x: x coordinate in the window
505
* @y: y coordinate in the window
507
* The ::pick-embedded-child signal is emitted to find an embedded
508
* child at the given position.
510
* Returns: (transfer none): the #GdkWindow of the embedded child at
515
signals[PICK_EMBEDDED_CHILD] =
516
g_signal_new (g_intern_static_string ("pick-embedded-child"),
517
G_OBJECT_CLASS_TYPE (object_class),
520
accumulate_get_window, NULL,
521
_gdk_marshal_OBJECT__DOUBLE_DOUBLE,
528
* GdkWindow::to-embedder:
529
* @window: the offscreen window on which the signal is emitted
530
* @offscreen-x: x coordinate in the offscreen window
531
* @offscreen-y: y coordinate in the offscreen window
532
* @embedder-x: (out) (type double): return location for the x
533
* coordinate in the embedder window
534
* @embedder-y: (out) (type double): return location for the y
535
* coordinate in the embedder window
537
* The ::to-embedder signal is emitted to translate coordinates
538
* in an offscreen window to its embedder.
540
* See also #GtkWindow::from-embedder.
544
signals[TO_EMBEDDER] =
545
g_signal_new (g_intern_static_string ("to-embedder"),
546
G_OBJECT_CLASS_TYPE (object_class),
550
_gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
559
* GdkWindow::from-embedder:
560
* @window: the offscreen window on which the signal is emitted
561
* @embedder-x: x coordinate in the embedder window
562
* @embedder-y: y coordinate in the embedder window
563
* @offscreen-x: (out) (type double): return location for the x
564
* coordinate in the offscreen window
565
* @offscreen-y: (out) (type double): return location for the y
566
* coordinate in the offscreen window
568
* The ::from-embedder signal is emitted to translate coordinates
569
* in the embedder of an offscreen window to the offscreen window.
571
* See also #GtkWindow::to-embedder.
575
signals[FROM_EMBEDDER] =
576
g_signal_new (g_intern_static_string ("from-embedder"),
577
G_OBJECT_CLASS_TYPE (object_class),
581
_gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
591
gdk_window_finalize (GObject *object)
593
GdkWindow *window = GDK_WINDOW (object);
594
GdkWindowObject *obj = (GdkWindowObject *) object;
596
if (!GDK_WINDOW_DESTROYED (window))
598
if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
600
g_warning ("losing last reference to undestroyed window\n");
601
_gdk_window_destroy (window, FALSE);
604
/* We use TRUE here, to keep us from actually calling
605
* XDestroyWindow() on the window
607
_gdk_window_destroy (window, TRUE);
612
g_object_unref (obj->impl);
616
if (obj->impl_window != obj)
618
g_object_unref (obj->impl_window);
619
obj->impl_window = NULL;
623
gdk_region_destroy (obj->shape);
625
if (obj->input_shape)
626
gdk_region_destroy (obj->input_shape);
629
gdk_cursor_unref (obj->cursor);
631
G_OBJECT_CLASS (parent_class)->finalize (object);
635
gdk_window_set_property (GObject *object,
640
GdkWindow *window = (GdkWindow *)object;
645
gdk_window_set_cursor (window, g_value_get_boxed (value));
649
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
655
gdk_window_get_property (GObject *object,
660
GdkWindow *window = (GdkWindow *) object;
665
g_value_set_boxed (value, gdk_window_get_cursor (window));
669
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
675
gdk_window_is_offscreen (GdkWindowObject *window)
677
return window->window_type == GDK_WINDOW_OFFSCREEN;
680
static GdkWindowObject *
681
gdk_window_get_impl_window (GdkWindowObject *window)
683
return window->impl_window;
687
_gdk_window_get_impl_window (GdkWindow *window)
689
return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
693
gdk_window_has_impl (GdkWindowObject *window)
695
return window->impl_window == window;
699
gdk_window_is_toplevel (GdkWindowObject *window)
702
window->parent == NULL ||
703
window->parent->window_type == GDK_WINDOW_ROOT;
707
_gdk_window_has_impl (GdkWindow *window)
709
return gdk_window_has_impl ((GdkWindowObject *)window);
713
gdk_window_has_no_impl (GdkWindowObject *window)
715
return window->impl_window != window;
719
remove_child_area (GdkWindowObject *private,
720
GdkWindowObject *until,
724
GdkWindowObject *child;
725
GdkRegion *child_region;
730
for (l = private->children; l; l = l->next)
737
/* If region is empty already, no need to do
738
anything potentially costly */
739
if (gdk_region_empty (region))
742
if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
745
/* Ignore offscreen children, as they don't draw in their parent and
746
* don't take part in the clipping */
747
if (gdk_window_is_offscreen (child))
752
r.width = child->width;
753
r.height = child->height;
755
/* Bail early if child totally outside region */
756
if (gdk_region_rect_in (region, &r) == GDK_OVERLAP_RECTANGLE_OUT)
759
child_region = gdk_region_rectangle (&r);
763
/* Adjust shape region to parent window coords */
764
gdk_region_offset (child->shape, child->x, child->y);
765
gdk_region_intersect (child_region, child->shape);
766
gdk_region_offset (child->shape, -child->x, -child->y);
768
else if (private->window_type == GDK_WINDOW_FOREIGN)
770
shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
773
gdk_region_intersect (child_region, shape);
774
gdk_region_destroy (shape);
780
if (child->input_shape)
781
gdk_region_intersect (child_region, child->input_shape);
782
else if (private->window_type == GDK_WINDOW_FOREIGN)
784
shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
787
gdk_region_intersect (child_region, shape);
788
gdk_region_destroy (shape);
793
gdk_region_subtract (region, child_region);
794
gdk_region_destroy (child_region);
799
static GdkVisibilityState
800
effective_visibility (GdkWindowObject *private)
802
GdkVisibilityState native;
804
if (!gdk_window_is_viewable ((GdkWindow *)private))
805
return GDK_VISIBILITY_NOT_VIEWABLE;
807
native = private->impl_window->native_visibility;
809
if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
810
private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
811
return GDK_VISIBILITY_FULLY_OBSCURED;
812
else if (native == GDK_VISIBILITY_UNOBSCURED)
813
return private->visibility;
814
else /* native PARTIAL, private partial or unobscured */
815
return GDK_VISIBILITY_PARTIAL;
819
gdk_window_update_visibility (GdkWindowObject *private)
821
GdkVisibilityState new_visibility;
824
new_visibility = effective_visibility (private);
826
if (new_visibility != private->effective_visibility)
828
private->effective_visibility = new_visibility;
830
if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
831
private->event_mask & GDK_VISIBILITY_NOTIFY)
833
event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
835
event->visibility.state = new_visibility;
841
gdk_window_update_visibility_recursively (GdkWindowObject *private,
842
GdkWindowObject *only_for_impl)
844
GdkWindowObject *child;
847
gdk_window_update_visibility (private);
848
for (l = private->children; l != NULL; l = l->next)
851
if ((only_for_impl == NULL) ||
852
(only_for_impl == child->impl_window))
853
gdk_window_update_visibility_recursively (child, only_for_impl);
858
should_apply_clip_as_shape (GdkWindowObject *private)
861
gdk_window_has_impl (private) &&
862
/* Not for offscreens */
863
!gdk_window_is_offscreen (private) &&
864
/* or for toplevels */
865
!gdk_window_is_toplevel (private) &&
866
/* or for foreign windows */
867
private->window_type != GDK_WINDOW_FOREIGN &&
868
/* or for the root window */
869
private->window_type != GDK_WINDOW_ROOT;
873
apply_shape (GdkWindowObject *private,
876
GdkWindowImplIface *impl_iface;
878
/* We trash whether we applied a shape so that
879
we can avoid unsetting it many times, which
880
could happen in e.g. apply_clip_as_shape as
881
windows get resized */
882
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
884
impl_iface->shape_combine_region ((GdkWindow *)private,
886
else if (private->applied_shape)
887
impl_iface->shape_combine_region ((GdkWindow *)private,
890
private->applied_shape = region != NULL;
894
apply_clip_as_shape (GdkWindowObject *private)
899
r.width = private->width;
900
r.height = private->height;
902
/* We only apply the clip region if would differ
903
from the actual clip region implied by the size
904
of the window. This is to avoid unneccessarily
905
adding meaningless shapes to all native subwindows */
906
if (!gdk_region_rect_equal (private->clip_region, &r))
907
apply_shape (private, private->clip_region);
909
apply_shape (private, NULL);
913
recompute_visible_regions_internal (GdkWindowObject *private,
914
gboolean recalculate_clip,
915
gboolean recalculate_siblings,
916
gboolean recalculate_children)
920
GdkWindowObject *child;
921
GdkRegion *new_clip, *old_clip_region_with_children;
922
gboolean clip_region_changed;
923
gboolean abs_pos_changed;
924
int old_abs_x, old_abs_y;
926
old_abs_x = private->abs_x;
927
old_abs_y = private->abs_y;
929
/* Update absolute position */
930
if (gdk_window_has_impl (private))
932
/* Native window starts here */
938
private->abs_x = private->parent->abs_x + private->x;
939
private->abs_y = private->parent->abs_y + private->y;
943
private->abs_x != old_abs_x ||
944
private->abs_y != old_abs_y;
946
/* Update clip region based on:
949
* siblings in parents above window
951
clip_region_changed = FALSE;
952
if (recalculate_clip)
954
if (private->viewable)
956
/* Calculate visible region (sans children) in parent window coords */
959
r.width = private->width;
960
r.height = private->height;
961
new_clip = gdk_region_rectangle (&r);
963
if (!gdk_window_is_toplevel (private))
965
gdk_region_intersect (new_clip, private->parent->clip_region);
967
/* Remove all overlapping children from parent.
968
* Unless we're all native, because then we don't need to take
969
* siblings into account since X does that clipping for us.
970
* This makes things like SWT that modify the raw X stacking
971
* order without GDKs knowledge work.
973
if (!_gdk_native_windows)
974
remove_child_area (private->parent, private, FALSE, new_clip);
977
/* Convert from parent coords to window coords */
978
gdk_region_offset (new_clip, -private->x, -private->y);
981
gdk_region_intersect (new_clip, private->shape);
984
new_clip = gdk_region_new ();
986
if (private->clip_region == NULL ||
987
!gdk_region_equal (private->clip_region, new_clip))
988
clip_region_changed = TRUE;
990
if (private->clip_region)
991
gdk_region_destroy (private->clip_region);
992
private->clip_region = new_clip;
994
old_clip_region_with_children = private->clip_region_with_children;
995
private->clip_region_with_children = gdk_region_copy (private->clip_region);
996
if (private->window_type != GDK_WINDOW_ROOT)
997
remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
999
if (clip_region_changed ||
1000
!gdk_region_equal (private->clip_region_with_children, old_clip_region_with_children))
1001
private->clip_tag = new_region_tag ();
1003
if (old_clip_region_with_children)
1004
gdk_region_destroy (old_clip_region_with_children);
1007
if (clip_region_changed)
1009
GdkVisibilityState visibility;
1010
gboolean fully_visible;
1012
if (gdk_region_empty (private->clip_region))
1013
visibility = GDK_VISIBILITY_FULLY_OBSCURED;
1018
fully_visible = gdk_region_equal (private->clip_region,
1025
r.width = private->width;
1026
r.height = private->height;
1027
fully_visible = gdk_region_rect_equal (private->clip_region, &r);
1031
visibility = GDK_VISIBILITY_UNOBSCURED;
1033
visibility = GDK_VISIBILITY_PARTIAL;
1036
if (private->visibility != visibility)
1038
private->visibility = visibility;
1039
gdk_window_update_visibility (private);
1043
/* Update all children, recursively (except for root, where children are not exact). */
1044
if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1045
private->window_type != GDK_WINDOW_ROOT)
1047
for (l = private->children; l; l = l->next)
1050
/* Only recalculate clip if the the clip region changed, otherwise
1051
* there is no way the child clip region could change (its has not e.g. moved)
1052
* Except if recalculate_children is set to force child updates
1054
recompute_visible_regions_internal (child,
1055
recalculate_clip && (clip_region_changed || recalculate_children),
1060
if (clip_region_changed &&
1061
should_apply_clip_as_shape (private))
1062
apply_clip_as_shape (private);
1064
if (recalculate_siblings &&
1065
!gdk_window_is_toplevel (private))
1067
/* If we moved a child window in parent or changed the stacking order, then we
1068
* need to recompute the visible area of all the other children in the parent
1070
for (l = private->parent->children; l; l = l->next)
1074
if (child != private)
1075
recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1078
/* We also need to recompute the _with_children clip for the parent */
1079
recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1082
if (private->cairo_surface)
1086
/* It would be nice if we had some cairo support here so we
1087
could set the clip rect on the cairo surface */
1088
width = private->abs_x + private->width;
1089
height = private->abs_y + private->height;
1091
_gdk_windowing_set_cairo_surface_size (private->cairo_surface,
1093
cairo_surface_set_device_offset (private->cairo_surface,
1099
/* Call this when private has changed in one or more of these ways:
1103
* stacking order of window changed
1106
* It will recalculate abs_x/y and the clip regions
1108
* Unless the window didn't change stacking order or size/pos, pass in TRUE
1109
* for recalculate_siblings. (Mostly used internally for the recursion)
1111
* If a child window was removed (and you can't use that child for
1112
* recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1115
recompute_visible_regions (GdkWindowObject *private,
1116
gboolean recalculate_siblings,
1117
gboolean recalculate_children)
1119
recompute_visible_regions_internal (private,
1121
recalculate_siblings,
1122
recalculate_children);
1126
_gdk_window_update_size (GdkWindow *window)
1128
recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1131
/* Find the native window that would be just above "child"
1132
* in the native stacking order if "child" was a native window
1133
* (it doesn't have to be native). If there is no such native
1134
* window inside this native parent then NULL is returned.
1135
* If child is NULL, find lowest native window in parent.
1137
static GdkWindowObject *
1138
find_native_sibling_above_helper (GdkWindowObject *parent,
1139
GdkWindowObject *child)
1146
l = g_list_find (parent->children, child);
1147
g_assert (l != NULL); /* Better be a child of its parent... */
1148
l = l->prev; /* Start looking at the one above the child */
1151
l = g_list_last (parent->children);
1153
for (; l != NULL; l = l->prev)
1157
if (gdk_window_has_impl (w))
1160
g_assert (parent != w);
1161
w = find_native_sibling_above_helper (w, NULL);
1170
static GdkWindowObject *
1171
find_native_sibling_above (GdkWindowObject *parent,
1172
GdkWindowObject *child)
1176
w = find_native_sibling_above_helper (parent, child);
1180
if (gdk_window_has_impl (parent))
1183
return find_native_sibling_above (parent->parent, parent);
1187
get_native_event_mask (GdkWindowObject *private)
1189
if (_gdk_native_windows ||
1190
private->window_type == GDK_WINDOW_ROOT ||
1191
private->window_type == GDK_WINDOW_FOREIGN)
1192
return private->event_mask;
1197
/* Do whatever the app asks to, since the app
1198
* may be asking for weird things for native windows,
1199
* but don't use motion hints as that may affect non-native
1200
* child windows that don't want it. Also, we need to
1201
* set all the app-specified masks since they will be picked
1202
* up by any implicit grabs (i.e. if they were not set as
1203
* native we would not get the events we need). */
1204
mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1206
/* We need thse for all native windows so we can
1207
emulate events on children: */
1210
GDK_VISIBILITY_NOTIFY_MASK |
1211
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1213
/* Additionally we select for pointer and button events
1214
* for toplevels as we need to get these to emulate
1215
* them for non-native subwindows. Even though we don't
1216
* select on them for all native windows we will get them
1217
* as the events are propagated out to the first window
1218
* that select for them.
1219
* Not selecting for button press on all windows is an
1220
* important thing, because in X only one client can do
1221
* so, and we don't want to unexpectedly prevent another
1222
* client from doing it.
1224
* We also need to do the same if the app selects for button presses
1225
* because then we will get implicit grabs for this window, and the
1226
* event mask used for that grab is based on the rest of the mask
1227
* for the window, but we might need more events than this window
1228
* lists due to some non-native child window.
1230
if (gdk_window_is_toplevel (private) ||
1231
mask & GDK_BUTTON_PRESS_MASK)
1233
GDK_POINTER_MOTION_MASK |
1234
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1242
get_native_grab_event_mask (GdkEventMask grab_mask)
1244
/* Similar to the above but for pointer events only */
1246
GDK_POINTER_MOTION_MASK |
1247
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1248
GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1251
~GDK_POINTER_MOTION_HINT_MASK);
1254
/* Puts the native window in the right order wrt the other native windows
1255
* in the hierarchy, given the position it has in the client side data.
1256
* This is useful if some operation changed the stacking order.
1257
* This calls assumes the native window is now topmost in its native parent.
1260
sync_native_window_stack_position (GdkWindow *window)
1262
GdkWindowObject *above;
1263
GdkWindowObject *private;
1264
GdkWindowImplIface *impl_iface;
1265
GList listhead = {0};
1267
private = (GdkWindowObject *) window;
1268
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1270
above = find_native_sibling_above (private->parent, private);
1273
listhead.data = window;
1274
impl_iface->restack_under ((GdkWindow *)above,
1281
* @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1282
* the default root window for the default display.
1283
* @attributes: attributes of the new window
1284
* @attributes_mask: mask indicating which fields in @attributes are valid
1286
* Creates a new #GdkWindow using the attributes from
1287
* @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1288
* more details. Note: to use this on displays other than the default
1289
* display, @parent must be specified.
1291
* Return value: (transfer none): the new #GdkWindow
1294
gdk_window_new (GdkWindow *parent,
1295
GdkWindowAttr *attributes,
1296
gint attributes_mask)
1299
GdkWindowObject *private;
1304
GdkEventMask event_mask;
1305
GdkWindow *real_parent;
1307
g_return_val_if_fail (attributes != NULL, NULL);
1311
GDK_NOTE (MULTIHEAD,
1312
g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1314
screen = gdk_screen_get_default ();
1315
parent = gdk_screen_get_root_window (screen);
1318
screen = gdk_drawable_get_screen (parent);
1320
g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1322
if (GDK_WINDOW_DESTROYED (parent))
1324
g_warning ("gdk_window_new(): parent is destroyed\n");
1328
if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1329
_gdk_native_windows)
1331
g_warning ("Offscreen windows not supported with native-windows gdk");
1335
window = g_object_new (GDK_TYPE_WINDOW, NULL);
1336
private = (GdkWindowObject *) window;
1338
/* Windows with a foreign parent are treated as if they are children
1339
* of the root window, except for actual creation.
1341
real_parent = parent;
1342
if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1343
parent = gdk_screen_get_root_window (screen);
1345
private->parent = (GdkWindowObject *)parent;
1347
private->accept_focus = TRUE;
1348
private->focus_on_map = TRUE;
1350
if (attributes_mask & GDK_WA_X)
1355
if (attributes_mask & GDK_WA_Y)
1362
private->width = (attributes->width > 1) ? (attributes->width) : (1);
1363
private->height = (attributes->height > 1) ? (attributes->height) : (1);
1365
#ifdef GDK_WINDOWING_X11
1366
/* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1367
* from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1369
if (attributes->wclass == GDK_INPUT_ONLY &&
1370
private->parent->window_type == GDK_WINDOW_ROOT &&
1371
!G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1373
g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1374
attributes->wclass = GDK_INPUT_OUTPUT;
1378
if (attributes->wclass == GDK_INPUT_ONLY)
1380
/* Backwards compatiblity - we've always ignored
1381
* attributes->window_type for input-only windows
1384
if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1385
private->window_type = GDK_WINDOW_TEMP;
1387
private->window_type = GDK_WINDOW_CHILD;
1390
private->window_type = attributes->window_type;
1393
switch (private->window_type)
1395
case GDK_WINDOW_TOPLEVEL:
1396
case GDK_WINDOW_DIALOG:
1397
case GDK_WINDOW_TEMP:
1398
case GDK_WINDOW_OFFSCREEN:
1399
if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1400
g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1401
"of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1402
case GDK_WINDOW_CHILD:
1406
g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1410
if (attributes_mask & GDK_WA_VISUAL)
1411
visual = attributes->visual;
1413
visual = gdk_screen_get_system_visual (screen);
1415
private->event_mask = attributes->event_mask;
1417
if (attributes->wclass == GDK_INPUT_OUTPUT)
1419
private->input_only = FALSE;
1420
private->depth = visual->depth;
1422
private->bg_color.pixel = 0; /* TODO: BlackPixel (xdisplay, screen_x11->screen_num); */
1423
private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
1425
private->bg_pixmap = NULL;
1430
private->input_only = TRUE;
1433
if (private->parent)
1434
private->parent->children = g_list_prepend (private->parent->children, window);
1436
native = _gdk_native_windows; /* Default */
1437
if (private->parent->window_type == GDK_WINDOW_ROOT)
1438
native = TRUE; /* Always use native windows for toplevels */
1439
else if (!private->input_only &&
1440
((attributes_mask & GDK_WA_COLORMAP &&
1441
attributes->colormap != gdk_drawable_get_colormap ((GdkDrawable *)private->parent)) ||
1442
(attributes_mask & GDK_WA_VISUAL &&
1443
attributes->visual != gdk_drawable_get_visual ((GdkDrawable *)private->parent))))
1444
native = TRUE; /* InputOutput window with different colormap or visual than parent, needs native window */
1446
if (gdk_window_is_offscreen (private))
1448
_gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask);
1449
private->impl_window = private;
1453
event_mask = get_native_event_mask (private);
1455
/* Create the impl */
1456
_gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask);
1457
private->impl_window = private;
1459
/* This will put the native window topmost in the native parent, which may
1460
* be wrong wrt other native windows in the non-native hierarchy, so restack */
1461
if (!_gdk_window_has_impl (real_parent))
1462
sync_native_window_stack_position (window);
1466
private->impl_window = g_object_ref (private->parent->impl_window);
1467
private->impl = g_object_ref (private->impl_window->impl);
1470
recompute_visible_regions (private, TRUE, FALSE);
1472
if (private->parent->window_type != GDK_WINDOW_ROOT)
1474
/* Inherit redirection from parent */
1475
private->redirect = private->parent->redirect;
1478
gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1479
(attributes->cursor) :
1486
is_parent_of (GdkWindow *parent,
1497
w = gdk_window_get_parent (w);
1504
change_impl (GdkWindowObject *private,
1505
GdkWindowObject *impl_window,
1509
GdkWindowObject *child;
1510
GdkDrawable *old_impl;
1511
GdkWindowObject *old_impl_window;
1513
old_impl = private->impl;
1514
old_impl_window = private->impl_window;
1515
if (private != impl_window)
1516
private->impl_window = g_object_ref (impl_window);
1518
private->impl_window = private;
1519
private->impl = g_object_ref (new);
1520
if (old_impl_window != private)
1521
g_object_unref (old_impl_window);
1522
g_object_unref (old_impl);
1524
for (l = private->children; l != NULL; l = l->next)
1528
if (child->impl == old_impl)
1529
change_impl (child, impl_window, new);
1534
reparent_to_impl (GdkWindowObject *private)
1537
GdkWindowObject *child;
1539
GdkWindowImplIface *impl_iface;
1541
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1543
/* Enumerate in reverse order so we get the right order for the native
1544
windows (first in childrens list is topmost, and reparent places on top) */
1545
for (l = g_list_last (private->children); l != NULL; l = l->prev)
1549
if (child->impl == private->impl)
1550
reparent_to_impl (child);
1553
show = impl_iface->reparent ((GdkWindow *)child,
1554
(GdkWindow *)private,
1555
child->x, child->y);
1557
gdk_window_show_unraised ((GdkWindow *)child);
1564
* gdk_window_reparent:
1565
* @window: a #GdkWindow
1566
* @new_parent: new parent to move @window into
1567
* @x: X location inside the new parent
1568
* @y: Y location inside the new parent
1570
* Reparents @window into the given @new_parent. The window being
1571
* reparented will be unmapped as a side effect.
1575
gdk_window_reparent (GdkWindow *window,
1576
GdkWindow *new_parent,
1580
GdkWindowObject *private;
1581
GdkWindowObject *new_parent_private;
1582
GdkWindowObject *old_parent;
1584
gboolean show, was_mapped, applied_clip_as_shape;
1585
gboolean do_reparent_to_impl;
1586
GdkEventMask old_native_event_mask;
1587
GdkWindowImplIface *impl_iface;
1589
g_return_if_fail (GDK_IS_WINDOW (window));
1590
g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1591
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1593
if (GDK_WINDOW_DESTROYED (window) ||
1594
(new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1597
screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
1599
new_parent = gdk_screen_get_root_window (screen);
1601
private = (GdkWindowObject *) window;
1602
new_parent_private = (GdkWindowObject *)new_parent;
1604
/* No input-output children of input-only windows */
1605
if (new_parent_private->input_only && !private->input_only)
1608
/* Don't create loops in hierarchy */
1609
if (is_parent_of (window, new_parent))
1612
/* This might be wrong in the new parent, e.g. for non-native surfaces.
1613
To make sure we're ok, just wipe it. */
1614
gdk_window_drop_cairo_surface (private);
1616
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1617
old_parent = private->parent;
1619
/* Break up redirection if inherited */
1620
if (private->redirect && private->redirect->redirected != private)
1622
remove_redirect_from_children (private, private->redirect);
1623
private->redirect = NULL;
1626
was_mapped = GDK_WINDOW_IS_MAPPED (window);
1629
/* Reparenting to toplevel. Ensure we have a native window so this can work */
1630
if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1631
new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1632
gdk_window_ensure_native (window);
1634
applied_clip_as_shape = should_apply_clip_as_shape (private);
1636
old_native_event_mask = 0;
1637
do_reparent_to_impl = FALSE;
1638
if (gdk_window_has_impl (private))
1640
old_native_event_mask = get_native_event_mask (private);
1642
show = impl_iface->reparent (window, new_parent, x, y);
1646
/* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1647
g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1648
new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1651
gdk_window_hide (window);
1653
do_reparent_to_impl = TRUE;
1654
change_impl (private,
1655
new_parent_private->impl_window,
1656
new_parent_private->impl);
1659
/* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1662
if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1664
new_parent = gdk_screen_get_root_window (screen);
1665
new_parent_private = (GdkWindowObject *)new_parent;
1669
old_parent->children = g_list_remove (old_parent->children, window);
1671
private->parent = new_parent_private;
1675
new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1677
/* Switch the window type as appropriate */
1679
switch (GDK_WINDOW_TYPE (new_parent))
1681
case GDK_WINDOW_ROOT:
1682
case GDK_WINDOW_FOREIGN:
1683
if (private->toplevel_window_type != -1)
1684
GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1685
else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1686
GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1688
case GDK_WINDOW_OFFSCREEN:
1689
case GDK_WINDOW_TOPLEVEL:
1690
case GDK_WINDOW_CHILD:
1691
case GDK_WINDOW_DIALOG:
1692
case GDK_WINDOW_TEMP:
1693
if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1694
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1696
/* Save the original window type so we can restore it if the
1697
* window is reparented back to be a toplevel
1699
private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1700
GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1704
/* We might have changed window type for a native windows, so we
1705
need to change the event mask too. */
1706
if (gdk_window_has_impl (private))
1708
GdkEventMask native_event_mask = get_native_event_mask (private);
1710
if (native_event_mask != old_native_event_mask)
1711
impl_iface->set_events (window, native_event_mask);
1714
/* Inherit parent redirect if we don't have our own */
1715
if (private->parent && private->redirect == NULL)
1717
private->redirect = private->parent->redirect;
1718
apply_redirect_to_children (private, private->redirect);
1721
_gdk_window_update_viewable (window);
1723
recompute_visible_regions (private, TRUE, FALSE);
1724
if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1725
recompute_visible_regions (old_parent, FALSE, TRUE);
1727
/* We used to apply the clip as the shape, but no more.
1728
Reset this to the real shape */
1729
if (gdk_window_has_impl (private) &&
1730
applied_clip_as_shape &&
1731
!should_apply_clip_as_shape (private))
1732
apply_shape (private, private->shape);
1734
if (do_reparent_to_impl)
1735
reparent_to_impl (private);
1738
/* The reparent will have put the native window topmost in the native parent,
1739
* which may be wrong wrt other native windows in the non-native hierarchy,
1741
if (!gdk_window_has_impl (new_parent_private))
1742
sync_native_window_stack_position (window);
1746
gdk_window_show_unraised (window);
1748
_gdk_synthesize_crossing_events_for_geometry_change (window);
1752
temporary_disable_extension_events (GdkWindowObject *window)
1754
GdkWindowObject *child;
1758
if (window->extension_events != 0)
1760
g_object_set_data (G_OBJECT (window),
1761
"gdk-window-extension-events",
1762
GINT_TO_POINTER (window->extension_events));
1763
gdk_input_set_extension_events ((GdkWindow *)window, 0,
1764
GDK_EXTENSION_EVENTS_NONE);
1769
for (l = window->children; l != NULL; l = l->next)
1773
if (window->impl_window == child->impl_window)
1774
res |= temporary_disable_extension_events (child);
1781
reenable_extension_events (GdkWindowObject *window)
1783
GdkWindowObject *child;
1787
mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1788
"gdk-window-extension-events"));
1792
/* We don't have the mode here, so we pass in cursor.
1793
This works with the current code since mode is not
1794
stored except as part of the mask, and cursor doesn't
1796
gdk_input_set_extension_events ((GdkWindow *)window, mask,
1797
GDK_EXTENSION_EVENTS_CURSOR);
1798
g_object_set_data (G_OBJECT (window),
1799
"gdk-window-extension-events",
1803
for (l = window->children; l != NULL; l = l->next)
1807
if (window->impl_window == child->impl_window)
1808
reenable_extension_events (window);
1813
* gdk_window_ensure_native:
1814
* @window: a #GdkWindow
1816
* Tries to ensure that there is a window-system native window for this
1817
* GdkWindow. This may fail in some situations, returning %FALSE.
1819
* Offscreen window and children of them can never have native windows.
1821
* Some backends may not support native child windows.
1823
* Returns: %TRUE if the window has a native window, %FALSE otherwise
1828
gdk_window_ensure_native (GdkWindow *window)
1830
GdkWindowObject *private;
1831
GdkWindowObject *impl_window;
1832
GdkDrawable *new_impl, *old_impl;
1835
GdkWindowAttr attributes;
1836
GdkWindowObject *above;
1838
GdkWindowImplIface *impl_iface;
1839
gboolean disabled_extension_events;
1841
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1843
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1844
GDK_WINDOW_DESTROYED (window))
1847
private = (GdkWindowObject *) window;
1849
impl_window = gdk_window_get_impl_window (private);
1851
if (gdk_window_is_offscreen (impl_window))
1852
return FALSE; /* native in offscreens not supported */
1854
if (impl_window == private)
1855
/* Already has an impl, and its not offscreen . */
1858
/* Need to create a native window */
1860
/* First we disable any extension events on the window or its
1861
descendants to handle the native input window moving */
1862
disabled_extension_events = FALSE;
1863
if (impl_window->input_window)
1864
disabled_extension_events = temporary_disable_extension_events (private);
1866
gdk_window_drop_cairo_surface (private);
1868
screen = gdk_drawable_get_screen (window);
1869
visual = gdk_drawable_get_visual (window);
1871
/* These fields are required in the attributes struct so we can't
1872
ignore them by clearing a flag in the attributes mask */
1873
attributes.wclass = private->input_only ? GDK_INPUT_ONLY : GDK_INPUT_OUTPUT;
1874
attributes.width = private->width;
1875
attributes.height = private->height;
1876
attributes.window_type = private->window_type;
1878
attributes.colormap = gdk_drawable_get_colormap (window);
1880
old_impl = private->impl;
1881
_gdk_window_impl_new (window, (GdkWindow *)private->parent,
1883
get_native_event_mask (private),
1884
&attributes, GDK_WA_COLORMAP);
1885
new_impl = private->impl;
1887
private->impl = old_impl;
1888
change_impl (private, private, new_impl);
1890
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1892
/* Native window creation will put the native window topmost in the
1893
* native parent, which may be wrong wrt the position of the previous
1894
* non-native window wrt to the other non-native children, so correct this.
1896
above = find_native_sibling_above (private->parent, private);
1899
listhead.data = window;
1900
listhead.prev = NULL;
1901
listhead.next = NULL;
1902
impl_iface->restack_under ((GdkWindow *)above, &listhead);
1905
recompute_visible_regions (private, FALSE, FALSE);
1907
/* The shape may not have been set, as the clip region doesn't actually
1908
change, so do it here manually */
1909
if (should_apply_clip_as_shape (private))
1910
apply_clip_as_shape (private);
1912
reparent_to_impl (private);
1914
if (!private->input_only)
1916
impl_iface->set_background (window, &private->bg_color);
1917
if (private->bg_pixmap != NULL)
1918
impl_iface->set_back_pixmap (window, private->bg_pixmap);
1921
impl_iface->input_shape_combine_region (window,
1922
private->input_shape,
1925
if (gdk_window_is_viewable (window))
1926
impl_iface->show (window, FALSE);
1928
if (disabled_extension_events)
1929
reenable_extension_events (private);
1935
* _gdk_event_filter_unref:
1936
* @window: (allow-none): A #GdkWindow, or %NULL to be the global window
1937
* @filter: A window filter
1939
* Release a reference to @filter. Note this function may
1940
* mutate the list storage, so you need to handle this
1941
* if iterating over a list of filters.
1944
_gdk_event_filter_unref (GdkWindow *window,
1945
GdkEventFilter *filter)
1951
filters = &_gdk_default_filters;
1954
GdkWindowObject *private;
1955
private = (GdkWindowObject *) window;
1956
filters = &private->filters;
1959
for (tmp_list = *filters; tmp_list; tmp_list = tmp_list->next)
1961
GdkEventFilter *iter_filter = tmp_list->data;
1964
if (iter_filter != filter)
1967
g_assert (iter_filter->ref_count > 0);
1969
filter->ref_count--;
1970
if (filter->ref_count != 0)
1974
tmp_list = tmp_list->next;
1976
*filters = g_list_remove_link (*filters, node);
1978
g_list_free_1 (node);
1983
window_remove_filters (GdkWindow *window)
1985
GdkWindowObject *obj = (GdkWindowObject*) window;
1986
while (obj->filters)
1987
_gdk_event_filter_unref (window, obj->filters->data);
1991
* _gdk_window_destroy_hierarchy:
1992
* @window: a #GdkWindow
1993
* @recursing: If TRUE, then this is being called because a parent
1995
* @recursing_native: If TRUE, then this is being called because a native parent
1996
* was destroyed. This generally means that the call to the
1997
* windowing system to destroy the window can be omitted, since
1998
* it will be destroyed as a result of the parent being destroyed.
1999
* Unless @foreign_destroy.
2000
* @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2001
* external agency. The window has already been destroyed and no
2002
* windowing system calls should be made. (This may never happen
2003
* for some windowing systems.)
2005
* Internal function to destroy a window. Like gdk_window_destroy(),
2006
* but does not drop the reference count created by gdk_window_new().
2009
_gdk_window_destroy_hierarchy (GdkWindow *window,
2011
gboolean recursing_native,
2012
gboolean foreign_destroy)
2014
GdkWindowObject *private;
2015
GdkWindowObject *temp_private;
2016
GdkWindowImplIface *impl_iface;
2017
GdkWindow *temp_window;
2019
GdkDisplay *display;
2023
g_return_if_fail (GDK_IS_WINDOW (window));
2025
private = (GdkWindowObject*) window;
2027
if (GDK_WINDOW_DESTROYED (window))
2030
display = gdk_drawable_get_display (GDK_DRAWABLE (window));
2031
screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
2032
temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
2033
if (temp_window == window)
2034
g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
2037
switch (private->window_type)
2039
case GDK_WINDOW_ROOT:
2040
if (!screen->closed)
2042
g_error ("attempted to destroy root window");
2045
/* else fall thru */
2046
case GDK_WINDOW_TOPLEVEL:
2047
case GDK_WINDOW_CHILD:
2048
case GDK_WINDOW_DIALOG:
2049
case GDK_WINDOW_TEMP:
2050
case GDK_WINDOW_FOREIGN:
2051
case GDK_WINDOW_OFFSCREEN:
2052
if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
2054
/* Logically, it probably makes more sense to send
2055
* a "destroy yourself" message to the foreign window
2056
* whether or not it's in our hierarchy; but for historical
2057
* reasons, we only send "destroy yourself" messages to
2058
* foreign windows in our hierarchy.
2060
if (private->parent)
2061
_gdk_windowing_window_destroy_foreign (window);
2063
/* Also for historical reasons, we remove any filters
2064
* on a foreign window when it or a parent is destroyed;
2065
* this likely causes problems if two separate portions
2066
* of code are maintaining filter lists on a foreign window.
2068
window_remove_filters (window);
2072
if (private->parent)
2074
GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
2076
if (parent_private->children)
2077
parent_private->children = g_list_remove (parent_private->children, window);
2080
GDK_WINDOW_IS_MAPPED (window))
2082
recompute_visible_regions (private, TRUE, FALSE);
2083
gdk_window_invalidate_in_parent (private);
2087
gdk_window_free_paint_stack (window);
2089
if (private->bg_pixmap &&
2090
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2091
private->bg_pixmap != GDK_NO_BG)
2093
g_object_unref (private->bg_pixmap);
2094
private->bg_pixmap = NULL;
2097
if (private->background)
2099
cairo_pattern_destroy (private->background);
2100
private->background = NULL;
2103
if (private->window_type == GDK_WINDOW_FOREIGN)
2104
g_assert (private->children == NULL);
2107
children = tmp = private->children;
2108
private->children = NULL;
2112
temp_window = tmp->data;
2115
temp_private = (GdkWindowObject*) temp_window;
2117
_gdk_window_destroy_hierarchy (temp_window,
2119
recursing_native || gdk_window_has_impl (private),
2123
g_list_free (children);
2126
_gdk_window_clear_update_area (window);
2128
gdk_window_drop_cairo_surface (private);
2130
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2132
if (private->extension_events)
2133
impl_iface->input_window_destroy (window);
2135
if (gdk_window_has_impl (private))
2136
impl_iface->destroy (window, recursing_native,
2140
/* hide to make sure we repaint and break grabs */
2141
gdk_window_hide (window);
2144
private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2145
private->parent = NULL;
2146
private->destroyed = TRUE;
2148
window_remove_filters (window);
2150
gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
2152
/* If we own the redirect, free it */
2153
if (private->redirect && private->redirect->redirected == private)
2154
gdk_window_redirect_free (private->redirect);
2156
private->redirect = NULL;
2158
if (display->pointer_info.toplevel_under_pointer == window)
2160
g_object_unref (display->pointer_info.toplevel_under_pointer);
2161
display->pointer_info.toplevel_under_pointer = NULL;
2164
if (private->clip_region)
2166
gdk_region_destroy (private->clip_region);
2167
private->clip_region = NULL;
2170
if (private->clip_region_with_children)
2172
gdk_region_destroy (private->clip_region_with_children);
2173
private->clip_region_with_children = NULL;
2176
if (private->outstanding_moves)
2178
g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2179
g_list_free (private->outstanding_moves);
2180
private->outstanding_moves = NULL;
2188
* _gdk_window_destroy:
2189
* @window: a #GdkWindow
2190
* @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2191
* external agency. The window has already been destroyed and no
2192
* windowing system calls should be made. (This may never happen
2193
* for some windowing systems.)
2195
* Internal function to destroy a window. Like gdk_window_destroy(),
2196
* but does not drop the reference count created by gdk_window_new().
2199
_gdk_window_destroy (GdkWindow *window,
2200
gboolean foreign_destroy)
2202
_gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2206
* gdk_window_destroy:
2207
* @window: a #GdkWindow
2209
* Destroys the window system resources associated with @window and decrements @window's
2210
* reference count. The window system resources for all children of @window are also
2211
* destroyed, but the children's reference counts are not decremented.
2213
* Note that a window will not be destroyed automatically when its reference count
2214
* reaches zero. You must call this function yourself before that happens.
2218
gdk_window_destroy (GdkWindow *window)
2220
_gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2221
g_object_unref (window);
2225
* gdk_window_set_user_data:
2226
* @window: a #GdkWindow
2227
* @user_data: user data
2229
* For most purposes this function is deprecated in favor of
2230
* g_object_set_data(). However, for historical reasons GTK+ stores
2231
* the #GtkWidget that owns a #GdkWindow as user data on the
2232
* #GdkWindow. So, custom widget implementations should use
2233
* this function for that. If GTK+ receives an event for a #GdkWindow,
2234
* and the user data for the window is non-%NULL, GTK+ will assume the
2235
* user data is a #GtkWidget, and forward the event to that widget.
2239
gdk_window_set_user_data (GdkWindow *window,
2242
g_return_if_fail (GDK_IS_WINDOW (window));
2244
((GdkWindowObject*)window)->user_data = user_data;
2248
* gdk_window_get_user_data:
2249
* @window: a #GdkWindow
2250
* @data: (out): return location for user data
2252
* Retrieves the user data for @window, which is normally the widget
2253
* that @window belongs to. See gdk_window_set_user_data().
2257
gdk_window_get_user_data (GdkWindow *window,
2260
g_return_if_fail (GDK_IS_WINDOW (window));
2262
*data = ((GdkWindowObject*)window)->user_data;
2266
* gdk_window_get_window_type:
2267
* @window: a #GdkWindow
2269
* Gets the type of the window. See #GdkWindowType.
2271
* Return value: type of window
2274
gdk_window_get_window_type (GdkWindow *window)
2276
g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2278
return GDK_WINDOW_TYPE (window);
2282
* gdk_window_is_destroyed:
2283
* @window: a #GdkWindow
2285
* Check to see if a window is destroyed..
2287
* Return value: %TRUE if the window is destroyed
2292
gdk_window_is_destroyed (GdkWindow *window)
2294
return GDK_WINDOW_DESTROYED (window);
2298
to_embedder (GdkWindowObject *window,
2299
gdouble offscreen_x,
2300
gdouble offscreen_y,
2301
gdouble *embedder_x,
2302
gdouble *embedder_y)
2304
g_signal_emit (window, signals[TO_EMBEDDER], 0,
2305
offscreen_x, offscreen_y,
2306
embedder_x, embedder_y);
2310
from_embedder (GdkWindowObject *window,
2313
gdouble *offscreen_x,
2314
gdouble *offscreen_y)
2316
g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2317
embedder_x, embedder_y,
2318
offscreen_x, offscreen_y);
2322
* gdk_window_has_native:
2323
* @window: a #GdkWindow
2325
* Checks whether the window has a native window or not. Note that
2326
* you can use gdk_window_ensure_native() if a native window is needed.
2328
* Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2333
gdk_window_has_native (GdkWindow *window)
2337
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2339
w = GDK_WINDOW_OBJECT (window);
2341
return w->parent == NULL || w->parent->impl != w->impl;
2345
* gdk_window_get_position:
2346
* @window: a #GdkWindow
2347
* @x: (out) (allow-none): X coordinate of window
2348
* @y: (out) (allow-none): Y coordinate of window
2350
* Obtains the position of the window as reported in the
2351
* most-recently-processed #GdkEventConfigure. Contrast with
2352
* gdk_window_get_geometry() which queries the X server for the
2353
* current window position, regardless of which events have been
2354
* received or processed.
2356
* The position coordinates are relative to the window's parent window.
2360
gdk_window_get_position (GdkWindow *window,
2364
GdkWindowObject *obj;
2366
g_return_if_fail (GDK_IS_WINDOW (window));
2368
obj = (GdkWindowObject*) window;
2377
* gdk_window_get_parent:
2378
* @window: a #GdkWindow
2380
* Obtains the parent of @window, as known to GDK. Does not query the
2381
* X server; thus this returns the parent as passed to gdk_window_new(),
2382
* not the actual parent. This should never matter unless you're using
2383
* Xlib calls mixed with GDK calls on the X11 platform. It may also
2384
* matter for toplevel windows, because the window manager may choose
2387
* Note that you should use gdk_window_get_effective_parent() when
2388
* writing generic code that walks up a window hierarchy, because
2389
* gdk_window_get_parent() will most likely not do what you expect if
2390
* there are offscreen windows in the hierarchy.
2392
* Return value: parent of @window
2395
gdk_window_get_parent (GdkWindow *window)
2397
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2399
return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2403
* gdk_window_get_effective_parent:
2404
* @window: a #GdkWindow
2406
* Obtains the parent of @window, as known to GDK. Works like
2407
* gdk_window_get_parent() for normal windows, but returns the
2408
* window's embedder for offscreen windows.
2410
* See also: gdk_offscreen_window_get_embedder()
2412
* Return value: effective parent of @window
2417
gdk_window_get_effective_parent (GdkWindow *window)
2419
GdkWindowObject *obj;
2421
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2423
obj = (GdkWindowObject *)window;
2425
if (gdk_window_is_offscreen (obj))
2426
return gdk_offscreen_window_get_embedder (window);
2428
return (GdkWindow *) obj->parent;
2432
* gdk_window_get_toplevel:
2433
* @window: a #GdkWindow
2435
* Gets the toplevel window that's an ancestor of @window.
2437
* Any window type but %GDK_WINDOW_CHILD is considered a
2438
* toplevel window, as is a %GDK_WINDOW_CHILD window that
2439
* has a root window as parent.
2441
* Note that you should use gdk_window_get_effective_toplevel() when
2442
* you want to get to a window's toplevel as seen on screen, because
2443
* gdk_window_get_toplevel() will most likely not do what you expect
2444
* if there are offscreen windows in the hierarchy.
2446
* Return value: the toplevel window containing @window
2449
gdk_window_get_toplevel (GdkWindow *window)
2451
GdkWindowObject *obj;
2453
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2455
obj = (GdkWindowObject *)window;
2457
while (obj->window_type == GDK_WINDOW_CHILD)
2459
if (gdk_window_is_toplevel (obj))
2464
return GDK_WINDOW (obj);
2468
* gdk_window_get_effective_toplevel:
2469
* @window: a #GdkWindow
2471
* Gets the toplevel window that's an ancestor of @window.
2473
* Works like gdk_window_get_toplevel(), but treats an offscreen window's
2474
* embedder as its parent, using gdk_window_get_effective_parent().
2476
* See also: gdk_offscreen_window_get_embedder()
2478
* Return value: the effective toplevel window containing @window
2483
gdk_window_get_effective_toplevel (GdkWindow *window)
2487
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2489
while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2490
(gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2497
* gdk_window_get_children:
2498
* @window: a #GdkWindow
2500
* Gets the list of children of @window known to GDK.
2501
* This function only returns children created via GDK,
2502
* so for example it's useless when used with the root window;
2503
* it only returns windows an application created itself.
2505
* The returned list must be freed, but the elements in the
2508
* Return value: (transfer container) (element-type GdkWindow):
2509
* list of child windows inside @window
2512
gdk_window_get_children (GdkWindow *window)
2514
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2516
if (GDK_WINDOW_DESTROYED (window))
2519
return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2523
* gdk_window_peek_children:
2524
* @window: a #GdkWindow
2526
* Like gdk_window_get_children(), but does not copy the list of
2527
* children, so the list does not need to be freed.
2529
* Return value: (transfer none) (element-type GdkWindow):
2530
* a reference to the list of child windows in @window
2533
gdk_window_peek_children (GdkWindow *window)
2535
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2537
if (GDK_WINDOW_DESTROYED (window))
2540
return GDK_WINDOW_OBJECT (window)->children;
2544
* gdk_window_add_filter:
2545
* @window: a #GdkWindow
2546
* @function: filter callback
2547
* @data: data to pass to filter callback
2549
* Adds an event filter to @window, allowing you to intercept events
2550
* before they reach GDK. This is a low-level operation and makes it
2551
* easy to break GDK and/or GTK+, so you have to know what you're
2552
* doing. Pass %NULL for @window to get all events for all windows,
2553
* instead of events for a specific window.
2555
* See gdk_display_add_client_message_filter() if you are interested
2556
* in X ClientMessage events.
2559
gdk_window_add_filter (GdkWindow *window,
2560
GdkFilterFunc function,
2563
GdkWindowObject *private;
2565
GdkEventFilter *filter;
2567
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2569
private = (GdkWindowObject*) window;
2570
if (private && GDK_WINDOW_DESTROYED (window))
2573
/* Filters are for the native events on the native window, so
2574
ensure there is a native window. */
2576
gdk_window_ensure_native (window);
2579
tmp_list = private->filters;
2581
tmp_list = _gdk_default_filters;
2585
filter = (GdkEventFilter *)tmp_list->data;
2586
if ((filter->function == function) && (filter->data == data))
2588
filter->ref_count++;
2591
tmp_list = tmp_list->next;
2594
filter = g_new (GdkEventFilter, 1);
2595
filter->function = function;
2596
filter->data = data;
2597
filter->ref_count = 1;
2601
private->filters = g_list_append (private->filters, filter);
2603
_gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2607
* gdk_window_remove_filter:
2608
* @window: a #GdkWindow
2609
* @function: previously-added filter function
2610
* @data: user data for previously-added filter function
2612
* Remove a filter previously added with gdk_window_add_filter().
2616
gdk_window_remove_filter (GdkWindow *window,
2617
GdkFilterFunc function,
2620
GdkWindowObject *private;
2621
GList *tmp_list, *node;
2622
GdkEventFilter *filter;
2624
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2626
private = (GdkWindowObject*) window;
2629
tmp_list = private->filters;
2631
tmp_list = _gdk_default_filters;
2635
filter = (GdkEventFilter *)tmp_list->data;
2637
tmp_list = tmp_list->next;
2639
if ((filter->function == function) && (filter->data == data))
2641
filter->flags |= GDK_EVENT_FILTER_REMOVED;
2642
_gdk_event_filter_unref (window, filter);
2650
* gdk_screen_get_toplevel_windows:
2651
* @screen: The #GdkScreen where the toplevels are located.
2653
* Obtains a list of all toplevel windows known to GDK on the screen @screen.
2654
* A toplevel window is a child of the root window (see
2655
* gdk_get_default_root_window()).
2657
* The returned list should be freed with g_list_free(), but
2658
* its elements need not be freed.
2660
* Return value: (transfer container) (element-type GdkWindow):
2661
* list of toplevel windows, free with g_list_free()
2666
gdk_screen_get_toplevel_windows (GdkScreen *screen)
2668
GdkWindow * root_window;
2669
GList *new_list = NULL;
2672
g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2674
root_window = gdk_screen_get_root_window (screen);
2676
tmp_list = ((GdkWindowObject *)root_window)->children;
2679
GdkWindowObject *w = tmp_list->data;
2681
if (w->window_type != GDK_WINDOW_FOREIGN)
2682
new_list = g_list_prepend (new_list, w);
2683
tmp_list = tmp_list->next;
2690
* gdk_window_get_toplevels:
2692
* Obtains a list of all toplevel windows known to GDK on the default
2693
* screen (see gdk_screen_get_toplevel_windows()).
2694
* A toplevel window is a child of the root window (see
2695
* gdk_get_default_root_window()).
2697
* The returned list should be freed with g_list_free(), but
2698
* its elements need not be freed.
2700
* Return value: list of toplevel windows, free with g_list_free()
2702
* Deprecated: 2.16: Use gdk_screen_get_toplevel_windows() instead.
2705
gdk_window_get_toplevels (void)
2707
return gdk_screen_get_toplevel_windows (gdk_screen_get_default ());
2711
* gdk_window_is_visible:
2712
* @window: a #GdkWindow
2714
* Checks whether the window has been mapped (with gdk_window_show() or
2715
* gdk_window_show_unraised()).
2717
* Return value: %TRUE if the window is mapped
2720
gdk_window_is_visible (GdkWindow *window)
2722
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2724
return GDK_WINDOW_IS_MAPPED (window);
2728
* gdk_window_is_viewable:
2729
* @window: a #GdkWindow
2731
* Check if the window and all ancestors of the window are
2732
* mapped. (This is not necessarily "viewable" in the X sense, since
2733
* we only check as far as we have GDK window parents, not to the root
2736
* Return value: %TRUE if the window is viewable
2739
gdk_window_is_viewable (GdkWindow *window)
2741
GdkWindowObject *private = (GdkWindowObject *)window;
2743
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2745
if (private->destroyed)
2748
return private->viewable;
2752
* gdk_window_get_state:
2753
* @window: a #GdkWindow
2755
* Gets the bitwise OR of the currently active window state flags,
2756
* from the #GdkWindowState enumeration.
2758
* Return value: window state bitfield
2761
gdk_window_get_state (GdkWindow *window)
2763
GdkWindowObject *private = (GdkWindowObject *)window;
2765
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2767
return private->state;
2771
/* This creates an empty "implicit" paint region for the impl window.
2772
* By itself this does nothing, but real paints to this window
2773
* or children of it can use this pixmap as backing to avoid allocating
2774
* multiple pixmaps for subwindow rendering. When doing so they
2775
* add to the region of the implicit paint region, which will be
2776
* pushed to the window when the implicit paint region is ended.
2777
* Such paints should not copy anything to the window on paint end, but
2778
* should rely on the implicit paint end.
2779
* The implicit paint will be automatically ended if someone draws
2780
* directly to the window or a child window.
2783
gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2785
GdkWindowObject *private = (GdkWindowObject *)window;
2786
GdkWindowPaint *paint;
2788
g_assert (gdk_window_has_impl (private));
2790
if (_gdk_native_windows)
2791
return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2793
if (GDK_IS_PAINTABLE (private->impl))
2794
return FALSE; /* Implementation does double buffering */
2796
if (private->paint_stack != NULL ||
2797
private->implicit_paint != NULL)
2798
return FALSE; /* Don't stack implicit paints */
2800
if (private->outstanding_surfaces != 0)
2801
return FALSE; /* May conflict with direct drawing to cairo surface */
2803
/* Never do implicit paints for foreign windows, they don't need
2804
* double buffer combination since they have no client side children,
2805
* and creating pixmaps for them is risky since they could disappear
2808
if (private->window_type == GDK_WINDOW_FOREIGN)
2811
paint = g_new (GdkWindowPaint, 1);
2812
paint->region = gdk_region_new (); /* Empty */
2813
paint->x_offset = rect->x;
2814
paint->y_offset = rect->y;
2815
paint->uses_implicit = FALSE;
2816
paint->flushed = FALSE;
2817
paint->surface = NULL;
2819
gdk_pixmap_new (window,
2820
MAX (rect->width, 1), MAX (rect->height, 1), -1);
2822
private->implicit_paint = paint;
2827
/* Ensure that all content related to this (sub)window is pushed to the
2828
native region. If there is an active paint then that area is not
2829
pushed, in order to not show partially finished double buffers. */
2831
gdk_window_flush_implicit_paint (GdkWindow *window)
2833
GdkWindowObject *private = (GdkWindowObject *)window;
2834
GdkWindowObject *impl_window;
2835
GdkWindowPaint *paint;
2840
impl_window = gdk_window_get_impl_window (private);
2841
if (impl_window->implicit_paint == NULL)
2844
paint = impl_window->implicit_paint;
2845
paint->flushed = TRUE;
2846
region = gdk_region_copy (private->clip_region_with_children);
2848
/* Don't flush active double buffers, as that may show partially done
2850
for (list = private->paint_stack; list != NULL; list = list->next)
2852
GdkWindowPaint *tmp_paint = list->data;
2854
gdk_region_subtract (region, tmp_paint->region);
2857
gdk_region_offset (region, private->abs_x, private->abs_y);
2858
gdk_region_intersect (region, paint->region);
2860
if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (region))
2862
/* Remove flushed region from the implicit paint */
2863
gdk_region_subtract (paint->region, region);
2865
/* Some regions are valid, push these to window now */
2866
tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE);
2867
_gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE);
2868
gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
2869
0, 0, paint->x_offset, paint->y_offset, -1, -1);
2870
/* Reset clip region of the cached GdkGC */
2871
gdk_gc_set_clip_region (tmp_gc, NULL);
2874
gdk_region_destroy (region);
2877
/* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2879
gdk_window_end_implicit_paint (GdkWindow *window)
2881
GdkWindowObject *private = (GdkWindowObject *)window;
2882
GdkWindowPaint *paint;
2885
g_assert (gdk_window_has_impl (private));
2887
g_assert (private->implicit_paint != NULL);
2889
paint = private->implicit_paint;
2891
private->implicit_paint = NULL;
2893
if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (paint->region))
2895
/* Some regions are valid, push these to window now */
2896
tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE);
2897
_gdk_gc_set_clip_region_internal (tmp_gc, paint->region, TRUE);
2898
gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
2899
0, 0, paint->x_offset, paint->y_offset, -1, -1);
2900
/* Reset clip region of the cached GdkGC */
2901
gdk_gc_set_clip_region (tmp_gc, NULL);
2904
gdk_region_destroy (paint->region);
2906
g_object_unref (paint->pixmap);
2911
* gdk_window_begin_paint_rect:
2912
* @window: a #GdkWindow
2913
* @rectangle: rectangle you intend to draw to
2915
* A convenience wrapper around gdk_window_begin_paint_region() which
2916
* creates a rectangular region for you. See
2917
* gdk_window_begin_paint_region() for details.
2921
gdk_window_begin_paint_rect (GdkWindow *window,
2922
const GdkRectangle *rectangle)
2926
g_return_if_fail (GDK_IS_WINDOW (window));
2928
region = gdk_region_rectangle (rectangle);
2929
gdk_window_begin_paint_region (window, region);
2930
gdk_region_destroy (region);
2934
* gdk_window_begin_paint_region:
2935
* @window: a #GdkWindow
2936
* @region: region you intend to draw to
2938
* Indicates that you are beginning the process of redrawing @region.
2939
* A backing store (offscreen buffer) large enough to contain @region
2940
* will be created. The backing store will be initialized with the
2941
* background color or background pixmap for @window. Then, all
2942
* drawing operations performed on @window will be diverted to the
2943
* backing store. When you call gdk_window_end_paint(), the backing
2944
* store will be copied to @window, making it visible onscreen. Only
2945
* the part of @window contained in @region will be modified; that is,
2946
* drawing operations are clipped to @region.
2948
* The net result of all this is to remove flicker, because the user
2949
* sees the finished product appear all at once when you call
2950
* gdk_window_end_paint(). If you draw to @window directly without
2951
* calling gdk_window_begin_paint_region(), the user may see flicker
2952
* as individual drawing operations are performed in sequence. The
2953
* clipping and background-initializing features of
2954
* gdk_window_begin_paint_region() are conveniences for the
2955
* programmer, so you can avoid doing that work yourself.
2957
* When using GTK+, the widget system automatically places calls to
2958
* gdk_window_begin_paint_region() and gdk_window_end_paint() around
2959
* emissions of the expose_event signal. That is, if you're writing an
2960
* expose event handler, you can assume that the exposed area in
2961
* #GdkEventExpose has already been cleared to the window background,
2962
* is already set as the clip region, and already has a backing store.
2963
* Therefore in most cases, application code need not call
2964
* gdk_window_begin_paint_region(). (You can disable the automatic
2965
* calls around expose events on a widget-by-widget basis by calling
2966
* gtk_widget_set_double_buffered().)
2968
* If you call this function multiple times before calling the
2969
* matching gdk_window_end_paint(), the backing stores are pushed onto
2970
* a stack. gdk_window_end_paint() copies the topmost backing store
2971
* onscreen, subtracts the topmost region from all other regions in
2972
* the stack, and pops the stack. All drawing operations affect only
2973
* the topmost backing store in the stack. One matching call to
2974
* gdk_window_end_paint() is required for each call to
2975
* gdk_window_begin_paint_region().
2979
gdk_window_begin_paint_region (GdkWindow *window,
2980
const GdkRegion *region)
2982
#ifdef USE_BACKING_STORE
2983
GdkWindowObject *private = (GdkWindowObject *)window;
2984
GdkRectangle clip_box;
2985
GdkWindowPaint *paint, *implicit_paint;
2986
GdkWindowObject *impl_window;
2989
g_return_if_fail (GDK_IS_WINDOW (window));
2991
if (GDK_WINDOW_DESTROYED (window))
2994
if (GDK_IS_PAINTABLE (private->impl))
2996
GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
2998
if (iface->begin_paint_region)
2999
iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
3004
impl_window = gdk_window_get_impl_window (private);
3005
implicit_paint = impl_window->implicit_paint;
3007
paint = g_new (GdkWindowPaint, 1);
3008
paint->region = gdk_region_copy (region);
3009
paint->region_tag = new_region_tag ();
3011
gdk_region_intersect (paint->region, private->clip_region_with_children);
3012
gdk_region_get_clipbox (paint->region, &clip_box);
3014
/* Convert to impl coords */
3015
gdk_region_offset (paint->region, private->abs_x, private->abs_y);
3017
/* Mark the region as valid on the implicit paint */
3020
gdk_region_union (implicit_paint->region, paint->region);
3022
/* Convert back to normal coords */
3023
gdk_region_offset (paint->region, -private->abs_x, -private->abs_y);
3029
paint->uses_implicit = TRUE;
3030
paint->pixmap = g_object_ref (implicit_paint->pixmap);
3031
paint->x_offset = -private->abs_x + implicit_paint->x_offset;
3032
paint->y_offset = -private->abs_y + implicit_paint->y_offset;
3034
gdk_drawable_get_size (paint->pixmap, &width, &height);
3035
paint->surface = _gdk_drawable_create_cairo_surface (paint->pixmap, width, height);
3039
paint->uses_implicit = FALSE;
3040
paint->x_offset = clip_box.x;
3041
paint->y_offset = clip_box.y;
3043
gdk_pixmap_new (window,
3044
MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1);
3045
paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap);
3049
cairo_surface_set_device_offset (paint->surface,
3050
-paint->x_offset, -paint->y_offset);
3052
for (list = private->paint_stack; list != NULL; list = list->next)
3054
GdkWindowPaint *tmp_paint = list->data;
3056
gdk_region_subtract (tmp_paint->region, paint->region);
3059
private->paint_stack = g_slist_prepend (private->paint_stack, paint);
3061
if (!gdk_region_empty (paint->region))
3063
gdk_window_clear_backing_region (window,
3067
#endif /* USE_BACKING_STORE */
3071
setup_redirect_clip (GdkWindow *window,
3076
GdkWindowObject *private = (GdkWindowObject *)window;
3077
GdkRegion *visible_region;
3078
GdkRectangle dest_rect;
3080
GdkWindow *toplevel;
3081
int x_offset, y_offset;
3083
toplevel = GDK_WINDOW (private->redirect->redirected);
3085
/* Get the clip region for gc clip rect + window hierarchy in
3086
window relative coords */
3088
_gdk_window_calculate_full_clip_region (window, toplevel,
3093
/* Compensate for the source pos/size */
3094
x_offset -= private->redirect->src_x;
3095
y_offset -= private->redirect->src_y;
3096
dest_rect.x = -x_offset;
3097
dest_rect.y = -y_offset;
3098
dest_rect.width = private->redirect->width;
3099
dest_rect.height = private->redirect->height;
3100
tmpreg = gdk_region_rectangle (&dest_rect);
3101
gdk_region_intersect (visible_region, tmpreg);
3102
gdk_region_destroy (tmpreg);
3104
/* Compensate for the dest pos */
3105
x_offset += private->redirect->dest_x;
3106
y_offset += private->redirect->dest_y;
3108
gdk_gc_set_clip_region (gc, visible_region); /* This resets clip origin! */
3110
/* offset clip and tiles from window coords to pixmaps coords */
3111
gdk_gc_offset (gc, -x_offset, -y_offset);
3113
gdk_region_destroy (visible_region);
3115
*x_offset_out = x_offset;
3116
*y_offset_out = y_offset;
3120
* gdk_window_end_paint:
3121
* @window: a #GdkWindow
3123
* Indicates that the backing store created by the most recent call to
3124
* gdk_window_begin_paint_region() should be copied onscreen and
3125
* deleted, leaving the next-most-recent backing store or no backing
3126
* store at all as the active paint region. See
3127
* gdk_window_begin_paint_region() for full details. It is an error to
3128
* call this function without a matching
3129
* gdk_window_begin_paint_region() first.
3133
gdk_window_end_paint (GdkWindow *window)
3135
#ifdef USE_BACKING_STORE
3136
GdkWindowObject *private = (GdkWindowObject *)window;
3137
GdkWindowObject *composited;
3138
GdkWindowPaint *paint;
3140
GdkRectangle clip_box;
3141
gint x_offset, y_offset;
3142
GdkRegion *full_clip;
3144
g_return_if_fail (GDK_IS_WINDOW (window));
3146
if (GDK_WINDOW_DESTROYED (window))
3149
if (GDK_IS_PAINTABLE (private->impl))
3151
GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3153
if (iface->end_paint)
3154
iface->end_paint ((GdkPaintable*)private->impl);
3158
if (private->paint_stack == NULL)
3160
g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3164
paint = private->paint_stack->data;
3166
private->paint_stack = g_slist_delete_link (private->paint_stack,
3167
private->paint_stack);
3169
gdk_region_get_clipbox (paint->region, &clip_box);
3171
tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE);
3173
x_offset = -private->abs_x;
3174
y_offset = -private->abs_y;
3176
if (!paint->uses_implicit)
3178
gdk_window_flush_outstanding_moves (window);
3180
full_clip = gdk_region_copy (private->clip_region_with_children);
3181
gdk_region_intersect (full_clip, paint->region);
3182
_gdk_gc_set_clip_region_internal (tmp_gc, full_clip, TRUE); /* Takes ownership of full_clip */
3183
gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset);
3184
gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
3185
clip_box.x - paint->x_offset,
3186
clip_box.y - paint->y_offset,
3187
clip_box.x - x_offset, clip_box.y - y_offset,
3188
clip_box.width, clip_box.height);
3191
if (private->redirect)
3193
int x_offset, y_offset;
3195
/* TODO: Should also use paint->region for clipping */
3196
setup_redirect_clip (window, tmp_gc, &x_offset, &y_offset);
3197
gdk_draw_drawable (private->redirect->pixmap, tmp_gc, paint->pixmap,
3198
clip_box.x - paint->x_offset,
3199
clip_box.y - paint->y_offset,
3200
clip_box.x + x_offset,
3201
clip_box.y + y_offset,
3202
clip_box.width, clip_box.height);
3205
/* Reset clip region of the cached GdkGC */
3206
gdk_gc_set_clip_region (tmp_gc, NULL);
3208
cairo_surface_destroy (paint->surface);
3209
g_object_unref (paint->pixmap);
3210
gdk_region_destroy (paint->region);
3213
/* find a composited window in our hierarchy to signal its
3214
* parent to redraw, calculating the clip box as we go...
3216
* stop if parent becomes NULL since then we'd have nowhere
3217
* to draw (ie: 'composited' will always be non-NULL here).
3219
for (composited = private;
3221
composited = composited->parent)
3225
gdk_drawable_get_size (GDK_DRAWABLE (composited->parent),
3228
clip_box.x += composited->x;
3229
clip_box.y += composited->y;
3230
clip_box.width = MIN (clip_box.width, width - clip_box.x);
3231
clip_box.height = MIN (clip_box.height, height - clip_box.y);
3233
if (composited->composited)
3235
gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3240
#endif /* USE_BACKING_STORE */
3244
gdk_window_free_paint_stack (GdkWindow *window)
3246
GdkWindowObject *private = (GdkWindowObject *)window;
3248
if (private->paint_stack)
3250
GSList *tmp_list = private->paint_stack;
3254
GdkWindowPaint *paint = tmp_list->data;
3256
if (tmp_list == private->paint_stack)
3257
g_object_unref (paint->pixmap);
3259
gdk_region_destroy (paint->region);
3262
tmp_list = tmp_list->next;
3265
g_slist_free (private->paint_stack);
3266
private->paint_stack = NULL;
3271
do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3272
GdkRegion *dest_region, /* In impl window coords */
3276
GdkRectangle copy_rect;
3277
GdkWindowObject *private;
3278
GdkWindowImplIface *impl_iface;
3280
/* We need to get data from subwindows here, because we might have
3281
* shaped a native window over the moving region (with bg none,
3282
* so the pixels are still there). In fact we might need to get data
3283
* from overlapping native window that are not children of this window,
3284
* so we copy from the toplevel with INCLUDE_INFERIORS.
3286
private = impl_window;
3287
while (!gdk_window_is_toplevel (private) &&
3288
!private->composited &&
3289
gdk_drawable_get_visual ((GdkDrawable *) private) == gdk_drawable_get_visual ((GdkDrawable *) private->parent))
3291
dx -= private->parent->abs_x + private->x;
3292
dy -= private->parent->abs_y + private->y;
3293
private = gdk_window_get_impl_window (private->parent);
3295
tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private);
3297
gdk_region_get_clipbox (dest_region, ©_rect);
3298
gdk_gc_set_clip_region (tmp_gc, dest_region);
3300
/* The region area is moved and we queue translations for all expose events
3301
to the source area that were sent prior to the copy */
3302
gdk_region_offset (dest_region, -dx, -dy); /* Move to source region */
3303
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
3305
impl_iface->queue_translation ((GdkWindow *)impl_window,
3307
dest_region, dx, dy);
3309
gdk_draw_drawable (impl_window->impl,
3312
copy_rect.x-dx, copy_rect.y-dy,
3313
copy_rect.x, copy_rect.y,
3314
copy_rect.width, copy_rect.height);
3315
gdk_gc_set_clip_region (tmp_gc, NULL);
3318
static GdkWindowRegionMove *
3319
gdk_window_region_move_new (GdkRegion *region,
3322
GdkWindowRegionMove *move;
3324
move = g_slice_new (GdkWindowRegionMove);
3325
move->dest_region = gdk_region_copy (region);
3333
gdk_window_region_move_free (GdkWindowRegionMove *move)
3335
gdk_region_destroy (move->dest_region);
3336
g_slice_free (GdkWindowRegionMove, move);
3340
append_move_region (GdkWindowObject *impl_window,
3341
GdkRegion *new_dest_region,
3344
GdkWindowRegionMove *move, *old_move;
3345
GdkRegion *new_total_region, *old_total_region;
3346
GdkRegion *source_overlaps_destination;
3347
GdkRegion *non_overwritten;
3348
gboolean added_move;
3351
if (gdk_region_empty (new_dest_region))
3354
/* In principle this could just append the move to the list of outstanding
3355
moves that will be replayed before drawing anything when we're handling
3356
exposes. However, we'd like to do a bit better since its commonly the case
3357
that we get multiple copies where A is copied to B and then B is copied
3358
to C, and we'd like to express this as a simple copy A to C operation. */
3360
/* We approach this by taking the new move and pushing it ahead of moves
3361
starting at the end of the list and stopping when its not safe to do so.
3362
It's not safe to push past a move if either the source of the new move
3363
is in the destination of the old move, or if the destination of the new
3364
move is in the source of the new move, or if the destination of the new
3365
move overlaps the destination of the old move. We simplify this by
3366
just comparing the total regions (src + dest) */
3367
new_total_region = gdk_region_copy (new_dest_region);
3368
gdk_region_offset (new_total_region, -dx, -dy);
3369
gdk_region_union (new_total_region, new_dest_region);
3372
for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3377
old_total_region = gdk_region_copy (old_move->dest_region);
3378
gdk_region_offset (old_total_region, -old_move->dx, -old_move->dy);
3379
gdk_region_union (old_total_region, old_move->dest_region);
3381
gdk_region_intersect (old_total_region, new_total_region);
3382
/* If these regions intersect then its not safe to push the
3383
new region before the old one */
3384
if (!gdk_region_empty (old_total_region))
3386
/* The area where the new moves source overlaps the old ones
3388
source_overlaps_destination = gdk_region_copy (new_dest_region);
3389
gdk_region_offset (source_overlaps_destination, -dx, -dy);
3390
gdk_region_intersect (source_overlaps_destination, old_move->dest_region);
3391
gdk_region_offset (source_overlaps_destination, dx, dy);
3393
/* We can do all sort of optimizations here, but to do things safely it becomes
3394
quite complicated. However, a very common case is that you copy something first,
3395
then copy all that or a subset of it to a new location (i.e. if you scroll twice
3396
in the same direction). We'd like to detect this case and optimize it to one
3398
if (gdk_region_equal (source_overlaps_destination, new_dest_region))
3400
/* This means we might be able to replace the old move and the new one
3401
with the new one read from the old ones source, and a second copy of
3402
the non-overwritten parts of the old move. However, such a split
3403
is only valid if the source in the old move isn't overwritten
3404
by the destination of the new one */
3406
/* the new destination of old move if split is ok: */
3407
non_overwritten = gdk_region_copy (old_move->dest_region);
3408
gdk_region_subtract (non_overwritten, new_dest_region);
3409
/* move to source region */
3410
gdk_region_offset (non_overwritten, -old_move->dx, -old_move->dy);
3412
gdk_region_intersect (non_overwritten, new_dest_region);
3413
if (gdk_region_empty (non_overwritten))
3416
move = gdk_window_region_move_new (new_dest_region,
3420
impl_window->outstanding_moves =
3421
g_list_insert_before (impl_window->outstanding_moves,
3423
gdk_region_subtract (old_move->dest_region, new_dest_region);
3425
gdk_region_destroy (non_overwritten);
3428
gdk_region_destroy (source_overlaps_destination);
3429
gdk_region_destroy (old_total_region);
3432
gdk_region_destroy (old_total_region);
3435
gdk_region_destroy (new_total_region);
3439
move = gdk_window_region_move_new (new_dest_region, dx, dy);
3442
impl_window->outstanding_moves =
3443
g_list_prepend (impl_window->outstanding_moves,
3446
impl_window->outstanding_moves =
3447
g_list_insert_before (impl_window->outstanding_moves,
3452
/* Moves bits and update area by dx/dy in impl window.
3453
Takes ownership of region to avoid copy (because we may change it) */
3455
move_region_on_impl (GdkWindowObject *impl_window,
3456
GdkRegion *region, /* In impl window coords */
3459
if ((dx == 0 && dy == 0) ||
3460
gdk_region_empty (region))
3462
gdk_region_destroy (region);
3466
g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3468
/* Move any old invalid regions in the copy source area by dx/dy */
3469
if (impl_window->update_area)
3471
GdkRegion *update_area;
3473
update_area = gdk_region_copy (region);
3475
/* Convert from target to source */
3476
gdk_region_offset (update_area, -dx, -dy);
3477
gdk_region_intersect (update_area, impl_window->update_area);
3478
/* We only copy the area, so keep the old update area invalid.
3479
It would be safe to remove it too, as code that uses
3480
move_region_on_impl generally also invalidate the source
3481
area. However, it would just use waste cycles. */
3484
gdk_region_offset (update_area, dx, dy);
3485
gdk_region_union (impl_window->update_area, update_area);
3487
/* This area of the destination is now invalid,
3488
so no need to copy to it. */
3489
gdk_region_subtract (region, update_area);
3491
gdk_region_destroy (update_area);
3494
/* If we're currently exposing this window, don't copy to this
3495
destination, as it will be overdrawn when the expose is done,
3496
instead invalidate it and repaint later. */
3497
if (impl_window->implicit_paint)
3499
GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3500
GdkRegion *exposing;
3502
exposing = gdk_region_copy (implicit_paint->region);
3503
gdk_region_intersect (exposing, region);
3504
gdk_region_subtract (region, exposing);
3506
impl_window_add_update_area (impl_window, exposing);
3507
gdk_region_destroy (exposing);
3510
if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3511
append_move_region (impl_window, region, dx, dy);
3513
do_move_region_bits_on_impl (impl_window,
3516
gdk_region_destroy (region);
3519
/* Flushes all outstanding changes to the window, call this
3520
* before drawing directly to the window (i.e. outside a begin/end_paint pair).
3523
gdk_window_flush_outstanding_moves (GdkWindow *window)
3525
GdkWindowObject *private;
3526
GdkWindowObject *impl_window;
3527
GdkWindowRegionMove *move;
3529
private = (GdkWindowObject *) window;
3531
impl_window = gdk_window_get_impl_window (private);
3533
while (impl_window->outstanding_moves)
3535
move = impl_window->outstanding_moves->data;
3536
impl_window->outstanding_moves = g_list_delete_link (impl_window->outstanding_moves,
3537
impl_window->outstanding_moves);
3539
do_move_region_bits_on_impl (impl_window,
3540
move->dest_region, move->dx, move->dy);
3542
gdk_window_region_move_free (move);
3548
* @window: a #GdkWindow
3550
* Flush all outstanding cached operations on a window, leaving the
3551
* window in a state which reflects all that has been drawn before.
3553
* Gdk uses multiple kinds of caching to get better performance and
3554
* nicer drawing. For instance, during exposes all paints to a window
3555
* using double buffered rendering are keep on a pixmap until the last
3556
* window has been exposed. It also delays window moves/scrolls until
3557
* as long as possible until next update to avoid tearing when moving
3560
* Normally this should be completely invisible to applications, as
3561
* we automatically flush the windows when required, but this might
3562
* be needed if you for instance mix direct native drawing with
3563
* gdk drawing. For Gtk widgets that don't use double buffering this
3564
* will be called automatically before sending the expose event.
3569
gdk_window_flush (GdkWindow *window)
3571
gdk_window_flush_outstanding_moves (window);
3572
gdk_window_flush_implicit_paint (window);
3575
/* If we're about to move/resize or otherwise change the
3576
* hierarchy of a client side window in an impl and we're
3577
* called from an expose event handler then we need to
3578
* flush any already painted parts of the implicit paint
3579
* that are not part of the current paint, as these may
3580
* be used when scrolling or may overdraw the changes
3581
* caused by the hierarchy change.
3584
gdk_window_flush_if_exposing (GdkWindow *window)
3586
GdkWindowObject *private;
3587
GdkWindowObject *impl_window;
3589
private = (GdkWindowObject *) window;
3590
impl_window = gdk_window_get_impl_window (private);
3592
/* If we're in an implicit paint (i.e. in an expose handler, flush
3593
all the already finished exposes to get things to an uptodate state. */
3594
if (impl_window->implicit_paint)
3595
gdk_window_flush (window);
3600
gdk_window_flush_recursive_helper (GdkWindowObject *window,
3603
GdkWindowObject *child;
3606
for (l = window->children; l != NULL; l = l->next)
3610
if (child->impl == impl)
3611
/* Same impl, ignore */
3612
gdk_window_flush_recursive_helper (child, impl);
3614
gdk_window_flush_recursive (child);
3619
gdk_window_flush_recursive (GdkWindowObject *window)
3621
gdk_window_flush ((GdkWindow *)window);
3622
gdk_window_flush_recursive_helper (window, window->impl);
3626
gdk_window_get_offsets (GdkWindow *window,
3630
GdkWindowObject *private = (GdkWindowObject *)window;
3632
if (private->paint_stack)
3634
GdkWindowPaint *paint = private->paint_stack->data;
3635
*x_offset = paint->x_offset;
3636
*y_offset = paint->y_offset;
3640
*x_offset = -private->abs_x;
3641
*y_offset = -private->abs_y;
3646
* gdk_window_get_internal_paint_info:
3647
* @window: a #GdkWindow
3648
* @real_drawable: (out): location to store the drawable to which drawing should be
3650
* @x_offset: (out): location to store the X offset between coordinates in @window,
3651
* and the underlying window system primitive coordinates for
3653
* @y_offset: (out): location to store the Y offset between coordinates in @window,
3654
* and the underlying window system primitive coordinates for
3657
* If you bypass the GDK layer and use windowing system primitives to
3658
* draw directly onto a #GdkWindow, then you need to deal with two
3659
* details: there may be an offset between GDK coordinates and windowing
3660
* system coordinates, and GDK may have redirected drawing to a offscreen
3661
* pixmap as the result of a gdk_window_begin_paint_region() calls.
3662
* This function allows retrieving the information you need to compensate
3663
* for these effects.
3665
* This function exposes details of the GDK implementation, and is thus
3666
* likely to change in future releases of GDK.
3669
gdk_window_get_internal_paint_info (GdkWindow *window,
3670
GdkDrawable **real_drawable,
3676
GdkWindowObject *private;
3678
g_return_if_fail (GDK_IS_WINDOW (window));
3680
private = (GdkWindowObject *)window;
3684
if (private->paint_stack)
3686
GdkWindowPaint *paint = private->paint_stack->data;
3687
*real_drawable = paint->pixmap;
3691
/* This means you're probably gonna be doing some weird shit
3692
directly to the window, so we flush all outstanding stuff */
3693
gdk_window_flush (window);
3694
*real_drawable = window;
3698
gdk_window_get_offsets (window, &x_off, &y_off);
3706
static GdkDrawable *
3707
start_draw_helper (GdkDrawable *drawable,
3712
GdkWindowObject *private = (GdkWindowObject *)drawable;
3713
gint x_offset, y_offset;
3715
gint old_clip_x = gc->clip_x_origin;
3716
gint old_clip_y = gc->clip_y_origin;
3718
guint32 clip_region_tag;
3719
GdkWindowPaint *paint;
3722
if (private->paint_stack)
3723
paint = private->paint_stack->data;
3727
x_offset = paint->x_offset;
3728
y_offset = paint->y_offset;
3732
x_offset = -private->abs_x;
3733
y_offset = -private->abs_y;
3736
if (x_offset != 0 || y_offset != 0)
3738
gdk_gc_set_clip_origin (gc,
3739
old_clip_x - x_offset,
3740
old_clip_y - y_offset);
3741
gdk_gc_set_ts_origin (gc,
3742
gc->ts_x_origin - x_offset,
3743
gc->ts_y_origin - y_offset);
3746
*x_offset_out = x_offset;
3747
*y_offset_out = y_offset;
3749
/* Add client side window clip region to gc */
3753
/* Only need clipping if using implicit paint, otherwise
3754
the pixmap is clipped when copying to the window in end_paint */
3755
if (paint->uses_implicit)
3757
/* This includes the window clip */
3758
clip = paint->region;
3760
clip_region_tag = paint->region_tag;
3762
/* After having set up the drawable clip rect on a GC we need to make sure
3763
* that we draw to th the impl, otherwise the pixmap code will reset the
3765
impl = ((GdkPixmapObject *)(paint->pixmap))->impl;
3769
/* Drawing directly to the window, flush anything outstanding to
3770
guarantee ordering. */
3771
gdk_window_flush ((GdkWindow *)drawable);
3773
/* Don't clip when drawing to root or all native */
3774
if (!_gdk_native_windows && private->window_type != GDK_WINDOW_ROOT)
3776
if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
3777
clip = private->clip_region_with_children;
3779
clip = private->clip_region;
3781
clip_region_tag = private->clip_tag;
3782
impl = private->impl;
3786
_gdk_gc_add_drawable_clip (gc,
3787
clip_region_tag, clip,
3788
/* If there was a clip origin set appart from the
3789
* window offset, need to take that into
3791
-old_clip_x, -old_clip_y);
3796
#define BEGIN_DRAW \
3798
GdkDrawable *impl; \
3799
gint x_offset, y_offset; \
3800
gint old_clip_x = gc->clip_x_origin; \
3801
gint old_clip_y = gc->clip_y_origin; \
3802
gint old_ts_x = gc->ts_x_origin; \
3803
gint old_ts_y = gc->ts_y_origin; \
3804
impl = start_draw_helper (drawable, gc, \
3805
&x_offset, &y_offset);
3808
if (x_offset != 0 || y_offset != 0) \
3810
gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \
3811
gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y); \
3815
#define BEGIN_DRAW_MACRO \
3818
#define END_DRAW_MACRO \
3823
GdkDrawable *drawable;
3836
_gdk_drawable_begin_direct_draw (GdkDrawable *drawable,
3838
gpointer *priv_data,
3842
GdkDrawable *out_impl = NULL;
3844
g_return_val_if_fail (priv_data != NULL, NULL);
3848
if (GDK_IS_PIXMAP (drawable))
3850
/* We bypass the GdkPixmap functions, so do this ourself */
3851
_gdk_gc_remove_drawable_clip (gc);
3853
out_impl = drawable;
3860
DirectDrawInfo *priv;
3862
if (GDK_WINDOW_DESTROYED (drawable))
3872
*x_offset_out = x_offset;
3873
*y_offset_out = y_offset;
3875
priv = g_new (DirectDrawInfo, 1);
3877
priv->drawable = impl;
3880
priv->x_offset = x_offset;
3881
priv->y_offset = y_offset;
3882
priv->clip_x = old_clip_x;
3883
priv->clip_y = old_clip_y;
3884
priv->ts_x = old_ts_x;
3885
priv->ts_y = old_ts_y;
3887
*priv_data = (gpointer) priv;
3896
_gdk_drawable_end_direct_draw (gpointer priv_data)
3898
DirectDrawInfo *priv;
3901
/* Its a GdkPixmap or the call to _gdk_drawable_begin_direct_draw failed. */
3902
if (priv_data == NULL)
3908
/* This is only for GdkWindows - if GdkPixmaps need any handling here in
3909
* the future, then we should keep track of what type of drawable it is in
3910
* DirectDrawInfo. */
3914
gint x_offset = priv->x_offset;
3915
gint y_offset = priv->y_offset;
3916
gint old_clip_x = priv->clip_x;
3917
gint old_clip_y = priv->clip_y;
3918
gint old_ts_x = priv->ts_x;
3919
gint old_ts_y = priv->ts_y;
3928
gdk_window_create_gc (GdkDrawable *drawable,
3929
GdkGCValues *values,
3930
GdkGCValuesMask mask)
3932
g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
3934
if (GDK_WINDOW_DESTROYED (drawable))
3937
return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl,
3942
gdk_window_draw_rectangle (GdkDrawable *drawable,
3950
if (GDK_WINDOW_DESTROYED (drawable))
3954
gdk_draw_rectangle (impl, gc, filled,
3955
x - x_offset, y - y_offset, width, height);
3960
gdk_window_draw_arc (GdkDrawable *drawable,
3970
if (GDK_WINDOW_DESTROYED (drawable))
3974
gdk_draw_arc (impl, gc, filled,
3975
x - x_offset, y - y_offset,
3976
width, height, angle1, angle2);
3981
gdk_window_draw_polygon (GdkDrawable *drawable,
3987
GdkPoint *new_points;
3989
if (GDK_WINDOW_DESTROYED (drawable))
3994
if (x_offset != 0 || y_offset != 0)
3998
new_points = g_new (GdkPoint, npoints);
3999
for (i=0; i<npoints; i++)
4001
new_points[i].x = points[i].x - x_offset;
4002
new_points[i].y = points[i].y - y_offset;
4006
new_points = points;
4008
gdk_draw_polygon (impl, gc, filled, new_points, npoints);
4010
if (new_points != points)
4011
g_free (new_points);
4017
gdk_window_draw_text (GdkDrawable *drawable,
4025
if (GDK_WINDOW_DESTROYED (drawable))
4029
gdk_draw_text (impl, font, gc,
4030
x - x_offset, y - y_offset, text, text_length);
4035
gdk_window_draw_text_wc (GdkDrawable *drawable,
4040
const GdkWChar *text,
4043
if (GDK_WINDOW_DESTROYED (drawable))
4047
gdk_draw_text_wc (impl, font, gc,
4048
x - x_offset, y - y_offset, text, text_length);
4052
static GdkDrawable *
4053
gdk_window_get_source_drawable (GdkDrawable *drawable)
4055
GdkWindow *window = GDK_WINDOW (drawable);
4056
GdkWindowObject *private;
4058
private = (GdkWindowObject *) window;
4059
if (GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable)
4060
return GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable (private->impl);
4065
static GdkDrawable *
4066
gdk_window_get_composite_drawable (GdkDrawable *drawable,
4071
gint *composite_x_offset,
4072
gint *composite_y_offset)
4074
GdkWindowObject *private = (GdkWindowObject *)drawable;
4076
GdkPixmap *tmp_pixmap;
4079
gboolean overlap_buffer;
4080
GdkDrawable *source;
4081
GdkWindowObject *impl_window;
4082
GdkWindowPaint *implicit_paint;
4084
*composite_x_offset = -private->abs_x;
4085
*composite_y_offset = -private->abs_y;
4087
if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable)))
4088
return g_object_ref (_gdk_drawable_get_source_drawable (drawable));
4090
/* See if any buffered part is overlapping the part we want
4096
rect.height = height;
4098
overlap_buffer = FALSE;
4100
for (list = private->paint_stack; list != NULL; list = list->next)
4102
GdkWindowPaint *paint = list->data;
4103
GdkOverlapType overlap;
4105
overlap = gdk_region_rect_in (paint->region, &rect);
4107
if (overlap == GDK_OVERLAP_RECTANGLE_IN)
4109
*composite_x_offset = paint->x_offset;
4110
*composite_y_offset = paint->y_offset;
4112
return g_object_ref (paint->pixmap);
4114
else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
4116
overlap_buffer = TRUE;
4121
impl_window = gdk_window_get_impl_window (private);
4122
implicit_paint = impl_window->implicit_paint;
4125
GdkOverlapType overlap;
4127
rect.x += private->abs_x;
4128
rect.y += private->abs_y;
4130
overlap = gdk_region_rect_in (implicit_paint->region, &rect);
4131
if (overlap == GDK_OVERLAP_RECTANGLE_IN)
4133
*composite_x_offset = -private->abs_x + implicit_paint->x_offset;
4134
*composite_y_offset = -private->abs_y + implicit_paint->y_offset;
4136
return g_object_ref (implicit_paint->pixmap);
4138
else if (overlap == GDK_OVERLAP_RECTANGLE_PART)
4139
overlap_buffer = TRUE;
4142
if (!overlap_buffer)
4143
return g_object_ref (_gdk_drawable_get_source_drawable (drawable));
4145
tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1);
4146
tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE);
4148
source = _gdk_drawable_get_source_drawable (drawable);
4150
/* Copy the current window contents */
4151
gdk_draw_drawable (tmp_pixmap,
4153
GDK_WINDOW_OBJECT (source)->impl,
4154
x - *composite_x_offset,
4155
y - *composite_y_offset,
4159
/* paint the backing stores */
4162
GdkWindowPaint *paint = list->data;
4164
gdk_gc_set_clip_region (tmp_gc, paint->region);
4165
gdk_gc_set_clip_origin (tmp_gc, -x - paint->x_offset, -y - paint->y_offset);
4167
gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
4168
x - paint->x_offset,
4169
y - paint->y_offset,
4170
0, 0, width, height);
4173
for (list = private->paint_stack; list != NULL; list = list->next)
4175
GdkWindowPaint *paint = list->data;
4177
if (paint->uses_implicit)
4178
continue; /* We already copied this above */
4180
gdk_gc_set_clip_region (tmp_gc, paint->region);
4181
gdk_gc_set_clip_origin (tmp_gc, -x, -y);
4183
gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap,
4184
x - paint->x_offset,
4185
y - paint->y_offset,
4186
0, 0, width, height);
4189
/* Reset clip region of the cached GdkGC */
4190
gdk_gc_set_clip_region (tmp_gc, NULL);
4192
/* Set these to location of tmp_pixmap within the window */
4193
*composite_x_offset = x;
4194
*composite_y_offset = y;
4200
gdk_window_get_clip_region (GdkDrawable *drawable)
4202
GdkWindowObject *private = (GdkWindowObject *)drawable;
4205
result = gdk_region_copy (private->clip_region);
4207
if (private->paint_stack)
4209
GdkRegion *paint_region = gdk_region_new ();
4210
GSList *tmp_list = private->paint_stack;
4214
GdkWindowPaint *paint = tmp_list->data;
4216
gdk_region_union (paint_region, paint->region);
4218
tmp_list = tmp_list->next;
4221
gdk_region_intersect (result, paint_region);
4222
gdk_region_destroy (paint_region);
4229
gdk_window_get_visible_region (GdkDrawable *drawable)
4231
GdkWindowObject *private = (GdkWindowObject*) drawable;
4233
return gdk_region_copy (private->clip_region);
4237
gdk_window_draw_drawable (GdkDrawable *drawable,
4246
GdkDrawable *original_src)
4248
GdkWindowObject *private = (GdkWindowObject *)drawable;
4250
if (GDK_WINDOW_DESTROYED (drawable))
4255
/* Call the method directly to avoid getting the composite drawable again */
4256
GDK_DRAWABLE_GET_CLASS (impl)->draw_drawable_with_src (impl, gc,
4264
if (!private->paint_stack)
4266
/* We might have drawn from an obscured part of a client
4267
side window, if so we need to send graphics exposures */
4268
if (_gdk_gc_get_exposures (gc) &&
4269
GDK_IS_WINDOW (original_src))
4271
GdkRegion *exposure_region;
4279
exposure_region = gdk_region_rectangle (&r);
4281
if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
4282
clip = private->clip_region_with_children;
4284
clip = private->clip_region;
4285
gdk_region_intersect (exposure_region, clip);
4287
_gdk_gc_remove_drawable_clip (gc);
4288
clip = _gdk_gc_get_clip_region (gc);
4291
gdk_region_offset (exposure_region,
4294
gdk_region_intersect (exposure_region, clip);
4295
gdk_region_offset (exposure_region,
4300
/* Note: We don't clip by the clip mask if set, so this
4301
may invalidate to much */
4303
/* Remove the area that is correctly copied from the src.
4304
* Note that xsrc/ysrc has been corrected for abs_x/y offsets already,
4305
* which need to be undone */
4306
clip = gdk_drawable_get_visible_region (original_src);
4307
gdk_region_offset (clip,
4308
xdest - (xsrc - GDK_WINDOW_OBJECT (original_src)->abs_x),
4309
ydest - (ysrc - GDK_WINDOW_OBJECT (original_src)->abs_y));
4310
gdk_region_subtract (exposure_region, clip);
4311
gdk_region_destroy (clip);
4313
gdk_window_invalidate_region_full (GDK_WINDOW (private),
4315
_gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS,
4318
gdk_region_destroy (exposure_region);
4326
gdk_window_draw_points (GdkDrawable *drawable,
4331
GdkPoint *new_points;
4333
if (GDK_WINDOW_DESTROYED (drawable))
4338
if (x_offset != 0 || y_offset != 0)
4342
new_points = g_new (GdkPoint, npoints);
4343
for (i=0; i<npoints; i++)
4345
new_points[i].x = points[i].x - x_offset;
4346
new_points[i].y = points[i].y - y_offset;
4350
new_points = points;
4352
gdk_draw_points (impl, gc, new_points, npoints);
4354
if (new_points != points)
4355
g_free (new_points);
4361
gdk_window_draw_segments (GdkDrawable *drawable,
4366
GdkSegment *new_segs;
4368
if (GDK_WINDOW_DESTROYED (drawable))
4373
if (x_offset != 0 || y_offset != 0)
4377
new_segs = g_new (GdkSegment, nsegs);
4378
for (i=0; i<nsegs; i++)
4380
new_segs[i].x1 = segs[i].x1 - x_offset;
4381
new_segs[i].y1 = segs[i].y1 - y_offset;
4382
new_segs[i].x2 = segs[i].x2 - x_offset;
4383
new_segs[i].y2 = segs[i].y2 - y_offset;
4389
gdk_draw_segments (impl, gc, new_segs, nsegs);
4391
if (new_segs != segs)
4398
gdk_window_draw_lines (GdkDrawable *drawable,
4403
GdkPoint *new_points;
4405
if (GDK_WINDOW_DESTROYED (drawable))
4410
if (x_offset != 0 || y_offset != 0)
4414
new_points = g_new (GdkPoint, npoints);
4415
for (i=0; i<npoints; i++)
4417
new_points[i].x = points[i].x - x_offset;
4418
new_points[i].y = points[i].y - y_offset;
4422
new_points = points;
4424
gdk_draw_lines (impl, gc, new_points, npoints);
4426
if (new_points != points)
4427
g_free (new_points);
4433
gdk_window_draw_glyphs (GdkDrawable *drawable,
4438
PangoGlyphString *glyphs)
4440
if (GDK_WINDOW_DESTROYED (drawable))
4444
gdk_draw_glyphs (impl, gc, font,
4445
x - x_offset, y - y_offset, glyphs);
4450
gdk_window_draw_glyphs_transformed (GdkDrawable *drawable,
4452
PangoMatrix *matrix,
4456
PangoGlyphString *glyphs)
4458
PangoMatrix tmp_matrix;
4460
if (GDK_WINDOW_DESTROYED (drawable))
4465
if (x_offset != 0 || y_offset != 0)
4469
tmp_matrix = *matrix;
4470
tmp_matrix.x0 -= x_offset;
4471
tmp_matrix.y0 -= y_offset;
4472
matrix = &tmp_matrix;
4474
else if (GDK_PANGO_UNITS_OVERFLOWS (x_offset, y_offset))
4476
PangoMatrix identity = PANGO_MATRIX_INIT;
4478
tmp_matrix = identity;
4479
tmp_matrix.x0 -= x_offset;
4480
tmp_matrix.y0 -= y_offset;
4481
matrix = &tmp_matrix;
4485
x -= x_offset * PANGO_SCALE;
4486
y -= y_offset * PANGO_SCALE;
4490
gdk_draw_glyphs_transformed (impl, gc, matrix, font, x, y, glyphs);
4496
cairo_t *cr; /* if non-null, it means use this cairo context */
4497
GdkGC *gc; /* if non-null, it means use this GC instead */
4498
} BackingRectMethod;
4501
setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
4503
GdkWindowObject *private = (GdkWindowObject *)window;
4505
if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
4507
GdkWindowPaint tmp_paint;
4510
tmp_paint.x_offset += private->x;
4511
tmp_paint.y_offset += private->y;
4513
x_offset_cairo += private->x;
4514
y_offset_cairo += private->y;
4516
setup_backing_rect_method (method, GDK_WINDOW (private->parent), &tmp_paint, x_offset_cairo, y_offset_cairo);
4518
else if (private->bg_pixmap &&
4519
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
4520
private->bg_pixmap != GDK_NO_BG)
4522
/* This is a workaround for https://bugs.freedesktop.org/show_bug.cgi?id=4320.
4523
* In it, using a pixmap as a repeating pattern in Cairo, and painting it to a
4524
* pixmap destination surface, can be very slow (on the order of seconds for a
4525
* whole-screen copy). The workaround is to use pretty much the same code that
4526
* we used in GTK+ 2.6 (pre-Cairo), which clears the double-buffer pixmap with
4527
* a tiled GC XFillRectangle().
4530
/* Actually computing this flag is left as an exercise for the reader */
4531
#if defined (G_OS_UNIX)
4532
# define GDK_CAIRO_REPEAT_IS_FAST 0
4534
# define GDK_CAIRO_REPEAT_IS_FAST 1
4537
#if GDK_CAIRO_REPEAT_IS_FAST
4538
cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
4539
cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface);
4540
cairo_surface_destroy (surface);
4542
if (x_offset_cairo != 0 || y_offset_cairo != 0)
4544
cairo_matrix_t matrix;
4545
cairo_matrix_init_translate (&matrix, x_offset_cairo, y_offset_cairo);
4546
cairo_pattern_set_matrix (pattern, &matrix);
4549
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
4551
method->cr = cairo_create (paint->surface);
4554
cairo_set_source (method->cr, pattern);
4555
cairo_pattern_destroy (pattern);
4558
GdkGCValues gc_values;
4560
gc_values.fill = GDK_TILED;
4561
gc_values.tile = private->bg_pixmap;
4562
gc_values.ts_x_origin = -x_offset_cairo;
4563
gc_values.ts_y_origin = -y_offset_cairo;
4565
gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN;
4567
method->gc = gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask);
4572
method->cr = cairo_create (paint->surface);
4574
gdk_cairo_set_source_color (method->cr, &private->bg_color);
4579
gdk_window_clear_backing_region (GdkWindow *window,
4582
GdkWindowObject *private = (GdkWindowObject *)window;
4583
GdkWindowPaint *paint = private->paint_stack->data;
4584
BackingRectMethod method;
4586
GdkRectangle clipbox;
4592
if (GDK_WINDOW_DESTROYED (window))
4596
timer = g_timer_new ();
4601
setup_backing_rect_method (&method, window, paint, 0, 0);
4603
clip = gdk_region_copy (paint->region);
4604
gdk_region_intersect (clip, region);
4605
gdk_region_get_clipbox (clip, &clipbox);
4610
g_assert (method.gc == NULL);
4612
gdk_cairo_region (method.cr, clip);
4613
cairo_fill (method.cr);
4615
cairo_destroy (method.cr);
4617
elapsed = g_timer_elapsed (timer, NULL);
4618
g_print ("Draw the background with Cairo: %fs\n", elapsed);
4623
g_assert (method.gc != NULL);
4625
gdk_gc_set_clip_region (method.gc, clip);
4626
gdk_draw_rectangle (window, method.gc, TRUE,
4627
clipbox.x, clipbox.y,
4628
clipbox.width, clipbox.height);
4629
g_object_unref (method.gc);
4632
elapsed = g_timer_elapsed (timer, NULL);
4633
g_print ("Draw the background with GDK: %fs\n", elapsed);
4637
gdk_region_destroy (clip);
4640
g_timer_destroy (timer);
4645
gdk_window_clear_backing_region_redirect (GdkWindow *window,
4648
GdkWindowObject *private = (GdkWindowObject *)window;
4649
GdkWindowRedirect *redirect = private->redirect;
4650
GdkRegion *clip_region;
4651
GdkRectangle clipbox;
4652
gint x_offset, y_offset;
4653
BackingRectMethod method;
4654
GdkWindowPaint paint;
4656
if (GDK_WINDOW_DESTROYED (window))
4659
clip_region = _gdk_window_calculate_full_clip_region (window,
4660
GDK_WINDOW (redirect->redirected),
4662
&x_offset, &y_offset);
4663
gdk_region_intersect (clip_region, region);
4665
/* offset is from redirected window origin to window origin, convert to
4666
the offset from the redirected pixmap origin to the window origin */
4667
x_offset += redirect->dest_x - redirect->src_x;
4668
y_offset += redirect->dest_y - redirect->src_y;
4670
/* Convert region to pixmap coords */
4671
gdk_region_offset (clip_region, x_offset, y_offset);
4675
paint.pixmap = redirect->pixmap;
4676
paint.surface = _gdk_drawable_ref_cairo_surface (redirect->pixmap);
4680
setup_backing_rect_method (&method, window, &paint, -x_offset, -y_offset);
4684
g_assert (method.gc == NULL);
4686
gdk_cairo_region (method.cr, clip_region);
4687
cairo_fill (method.cr);
4689
cairo_destroy (method.cr);
4693
g_assert (method.gc != NULL);
4695
gdk_region_get_clipbox (clip_region, &clipbox);
4696
gdk_gc_set_clip_region (method.gc, clip_region);
4697
gdk_draw_rectangle (redirect->pixmap, method.gc, TRUE,
4698
clipbox.x, clipbox.y,
4699
clipbox.width, clipbox.height);
4700
g_object_unref (method.gc);
4704
gdk_region_destroy (clip_region);
4705
cairo_surface_destroy (paint.surface);
4709
gdk_window_clear_backing_region_direct (GdkWindow *window,
4712
GdkWindowObject *private = (GdkWindowObject *)window;
4713
BackingRectMethod method;
4714
GdkWindowPaint paint;
4716
GdkRectangle clipbox;
4718
if (GDK_WINDOW_DESTROYED (window))
4723
paint.pixmap = window;
4724
paint.surface = _gdk_drawable_ref_cairo_surface (window);
4728
setup_backing_rect_method (&method, window, &paint, 0, 0);
4730
clip = gdk_region_copy (private->clip_region_with_children);
4731
gdk_region_intersect (clip, region);
4732
gdk_region_get_clipbox (clip, &clipbox);
4736
g_assert (method.gc == NULL);
4738
gdk_cairo_region (method.cr, clip);
4739
cairo_fill (method.cr);
4741
cairo_destroy (method.cr);
4745
g_assert (method.gc != NULL);
4747
gdk_gc_set_clip_region (method.gc, clip);
4748
gdk_draw_rectangle (window, method.gc, TRUE,
4749
clipbox.x, clipbox.y,
4750
clipbox.width, clipbox.height);
4751
g_object_unref (method.gc);
4755
gdk_region_destroy (clip);
4756
cairo_surface_destroy (paint.surface);
4762
* @window: a #GdkWindow
4764
* Clears an entire @window to the background color or background pixmap.
4767
gdk_window_clear (GdkWindow *window)
4771
g_return_if_fail (GDK_IS_WINDOW (window));
4773
gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
4775
gdk_window_clear_area (window, 0, 0,
4779
/* TRUE if the window clears to the same pixels as a native
4780
window clear. This means you can use the native window
4781
clearing operation, and additionally it means any clearing
4782
done by the native window system for you will already be right */
4784
clears_as_native (GdkWindowObject *private)
4786
GdkWindowObject *next;
4792
if (gdk_window_has_impl (private))
4794
next = private->parent;
4796
while (private->bg_pixmap == GDK_PARENT_RELATIVE_BG &&
4797
next && next->window_type != GDK_WINDOW_ROOT);
4802
gdk_window_clear_region_internal (GdkWindow *window,
4804
gboolean send_expose)
4806
GdkWindowObject *private = (GdkWindowObject *)window;
4807
GdkWindowImplIface *impl_iface;
4809
if (private->paint_stack)
4810
gdk_window_clear_backing_region (window, region);
4813
if (private->redirect)
4814
gdk_window_clear_backing_region_redirect (window, region);
4816
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4818
if (impl_iface->clear_region && clears_as_native (private))
4821
copy = gdk_region_copy (region);
4822
gdk_region_intersect (copy,
4823
private->clip_region_with_children);
4826
/* Drawing directly to the window, flush anything outstanding to
4827
guarantee ordering. */
4828
gdk_window_flush (window);
4829
impl_iface->clear_region (window, copy, send_expose);
4831
gdk_region_destroy (copy);
4835
gdk_window_clear_backing_region_direct (window, region);
4837
gdk_window_invalidate_region (window, region, FALSE);
4843
gdk_window_clear_area_internal (GdkWindow *window,
4848
gboolean send_expose)
4853
g_return_if_fail (GDK_IS_WINDOW (window));
4855
if (GDK_WINDOW_DESTROYED (window))
4858
/* Terminate early to avoid weird interpretation of
4859
zero width/height by XClearArea */
4860
if (width == 0 || height == 0)
4866
rect.height = height;
4868
region = gdk_region_rectangle (&rect);
4869
gdk_window_clear_region_internal (window,
4872
gdk_region_destroy (region);
4877
* gdk_window_clear_area:
4878
* @window: a #GdkWindow
4879
* @x: x coordinate of rectangle to clear
4880
* @y: y coordinate of rectangle to clear
4881
* @width: width of rectangle to clear
4882
* @height: height of rectangle to clear
4884
* Clears an area of @window to the background color or background pixmap.
4888
gdk_window_clear_area (GdkWindow *window,
4894
gdk_window_clear_area_internal (window,
4901
* gdk_window_clear_area_e:
4902
* @window: a #GdkWindow
4903
* @x: x coordinate of rectangle to clear
4904
* @y: y coordinate of rectangle to clear
4905
* @width: width of rectangle to clear
4906
* @height: height of rectangle to clear
4908
* Like gdk_window_clear_area(), but also generates an expose event for
4911
* This function has a stupid name because it dates back to the mists
4912
* time, pre-GDK-1.0.
4916
gdk_window_clear_area_e (GdkWindow *window,
4922
gdk_window_clear_area_internal (window,
4929
gdk_window_draw_image (GdkDrawable *drawable,
4939
if (GDK_WINDOW_DESTROYED (drawable))
4943
gdk_draw_image (impl, gc, image, xsrc, ysrc,
4944
xdest - x_offset, ydest - y_offset,
4950
gdk_window_draw_pixbuf (GdkDrawable *drawable,
4959
GdkRgbDither dither,
4963
GdkWindowObject *private = (GdkWindowObject *)drawable;
4964
GdkDrawableClass *klass;
4966
if (GDK_WINDOW_DESTROYED (drawable))
4969
/* If no gc => no user clipping, but we need clipping
4970
for window emulation, so use a scratch gc */
4972
gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
4976
klass = GDK_DRAWABLE_GET_CLASS (impl);
4978
if (private->paint_stack)
4979
klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
4980
dest_x - x_offset, dest_y - y_offset,
4982
dither, x_dither - x_offset, y_dither - y_offset);
4984
klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y,
4985
dest_x - x_offset, dest_y - y_offset,
4987
dither, x_dither, y_dither);
4992
gdk_window_draw_trapezoids (GdkDrawable *drawable,
4994
GdkTrapezoid *trapezoids,
4997
GdkTrapezoid *new_trapezoids = NULL;
4999
if (GDK_WINDOW_DESTROYED (drawable))
5004
if (x_offset != 0 || y_offset != 0)
5008
new_trapezoids = g_new (GdkTrapezoid, n_trapezoids);
5009
for (i=0; i < n_trapezoids; i++)
5011
new_trapezoids[i].y1 = trapezoids[i].y1 - y_offset;
5012
new_trapezoids[i].x11 = trapezoids[i].x11 - x_offset;
5013
new_trapezoids[i].x21 = trapezoids[i].x21 - x_offset;
5014
new_trapezoids[i].y2 = trapezoids[i].y2 - y_offset;
5015
new_trapezoids[i].x12 = trapezoids[i].x12 - x_offset;
5016
new_trapezoids[i].x22 = trapezoids[i].x22 - x_offset;
5019
trapezoids = new_trapezoids;
5022
gdk_draw_trapezoids (impl, gc, trapezoids, n_trapezoids);
5024
g_free (new_trapezoids);
5030
gdk_window_real_get_size (GdkDrawable *drawable,
5034
GdkWindowObject *private = (GdkWindowObject *)drawable;
5037
*width = private->width;
5039
*height = private->height;
5043
gdk_window_real_get_visual (GdkDrawable *drawable)
5045
GdkColormap *colormap;
5047
g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5049
colormap = gdk_drawable_get_colormap (drawable);
5050
return colormap ? gdk_colormap_get_visual (colormap) : NULL;
5054
gdk_window_real_get_depth (GdkDrawable *drawable)
5056
g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
5058
return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
5062
gdk_window_real_get_screen (GdkDrawable *drawable)
5064
return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl);
5068
gdk_window_real_set_colormap (GdkDrawable *drawable,
5071
GdkWindowObject *private;
5073
g_return_if_fail (GDK_IS_WINDOW (drawable));
5075
if (GDK_WINDOW_DESTROYED (drawable))
5078
private = (GdkWindowObject *)drawable;
5080
/* different colormap than parent, requires native window */
5081
if (!private->input_only &&
5082
cmap != gdk_drawable_get_colormap ((GdkDrawable *)(private->parent)))
5083
gdk_window_ensure_native ((GdkWindow *)drawable);
5085
gdk_drawable_set_colormap (private->impl, cmap);
5089
gdk_window_real_get_colormap (GdkDrawable *drawable)
5091
g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5093
if (GDK_WINDOW_DESTROYED (drawable))
5096
return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
5100
gdk_window_copy_to_image (GdkDrawable *drawable,
5109
GdkWindowObject *private = (GdkWindowObject *) drawable;
5110
gint x_offset, y_offset;
5112
g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
5114
if (GDK_WINDOW_DESTROYED (drawable))
5117
/* If we're here, a composite image was not necessary, so
5118
* we can ignore the paint stack.
5121
/* TODO: Is this right? */
5125
return gdk_drawable_copy_to_image (private->impl,
5134
gdk_window_drop_cairo_surface (GdkWindowObject *private)
5136
if (private->cairo_surface)
5138
cairo_surface_finish (private->cairo_surface);
5139
cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
5145
gdk_window_cairo_surface_destroy (void *data)
5147
GdkWindowObject *private = (GdkWindowObject*) data;
5149
private->cairo_surface = NULL;
5150
private->impl_window->outstanding_surfaces--;
5153
static cairo_surface_t *
5154
gdk_window_create_cairo_surface (GdkDrawable *drawable,
5158
return _gdk_windowing_create_cairo_surface (GDK_WINDOW_OBJECT(drawable)->impl,
5163
static cairo_surface_t *
5164
gdk_window_ref_cairo_surface (GdkDrawable *drawable)
5166
GdkWindowObject *private = (GdkWindowObject*) drawable;
5167
cairo_surface_t *surface;
5169
if (private->paint_stack)
5171
GdkWindowPaint *paint = private->paint_stack->data;
5173
surface = paint->surface;
5174
cairo_surface_reference (surface);
5179
/* This will be drawing directly to the window, so flush implicit paint */
5180
gdk_window_flush ((GdkWindow *)drawable);
5182
if (!private->cairo_surface)
5185
GdkDrawable *source;
5187
gdk_drawable_get_size ((GdkWindow *) private->impl_window,
5190
source = _gdk_drawable_get_source_drawable (drawable);
5192
private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height);
5194
if (private->cairo_surface)
5196
private->impl_window->outstanding_surfaces++;
5198
cairo_surface_set_device_offset (private->cairo_surface,
5202
cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
5203
drawable, gdk_window_cairo_surface_destroy);
5207
cairo_surface_reference (private->cairo_surface);
5209
surface = private->cairo_surface;
5216
gdk_window_set_cairo_clip (GdkDrawable *drawable,
5219
GdkWindowObject *private = (GdkWindowObject*) drawable;
5221
if (!private->paint_stack)
5223
cairo_reset_clip (cr);
5226
cairo_identity_matrix (cr);
5228
cairo_new_path (cr);
5229
gdk_cairo_region (cr, private->clip_region_with_children);
5236
GdkWindowPaint *paint = private->paint_stack->data;
5238
/* Only needs to clip to region if piggybacking
5239
on an implicit paint pixmap */
5240
cairo_reset_clip (cr);
5241
if (paint->uses_implicit)
5244
cairo_identity_matrix (cr);
5246
cairo_new_path (cr);
5247
gdk_cairo_region (cr, paint->region);
5255
/* Code for dirty-region queueing
5257
static GSList *update_windows = NULL;
5258
static guint update_idle = 0;
5259
static gboolean debug_updates = FALSE;
5261
static inline gboolean
5262
gdk_window_is_ancestor (GdkWindow *window,
5263
GdkWindow *ancestor)
5267
GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
5269
if (parent == ancestor)
5279
gdk_window_add_update_window (GdkWindow *window)
5282
GSList *prev = NULL;
5283
gboolean has_ancestor_in_list = FALSE;
5285
/* Check whether "window" is already in "update_windows" list.
5286
* It could be added during execution of gtk_widget_destroy() when
5287
* setting focus widget to NULL and redrawing old focus widget.
5290
tmp = g_slist_find (update_windows, window);
5294
for (tmp = update_windows; tmp; tmp = tmp->next)
5296
GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
5298
/* check if tmp is an ancestor of "window"; if it is, set a
5299
* flag indicating that all following windows are either
5300
* children of "window" or from a differen hierarchy
5302
if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
5303
has_ancestor_in_list = TRUE;
5305
/* insert in reverse stacking order when adding around siblings,
5306
* so processing updates properly paints over lower stacked windows
5308
if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
5310
gint index = g_list_index (parent->children, window);
5311
for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
5313
gint sibling_index = g_list_index (parent->children, tmp->data);
5314
if (index > sibling_index)
5318
/* here, tmp got advanced past all lower stacked siblings */
5319
tmp = g_slist_prepend (tmp, g_object_ref (window));
5323
update_windows = tmp;
5327
/* if "window" has an ancestor in the list and tmp is one of
5328
* "window's" children, insert "window" before tmp
5330
if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
5332
tmp = g_slist_prepend (tmp, g_object_ref (window));
5337
update_windows = tmp;
5341
/* if we're at the end of the list and had an ancestor it it,
5342
* append to the list
5344
if (! tmp->next && has_ancestor_in_list)
5346
tmp = g_slist_append (tmp, g_object_ref (window));
5353
/* if all above checks failed ("window" is from a different
5354
* hierarchy than what is already in the list) or the list is
5357
update_windows = g_slist_prepend (update_windows, g_object_ref (window));
5361
gdk_window_remove_update_window (GdkWindow *window)
5365
link = g_slist_find (update_windows, window);
5368
update_windows = g_slist_delete_link (update_windows, link);
5369
g_object_unref (window);
5374
gdk_window_update_idle (gpointer data)
5376
gdk_window_process_all_updates ();
5382
gdk_window_is_toplevel_frozen (GdkWindow *window)
5384
GdkWindowObject *toplevel;
5386
toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
5388
return toplevel->update_and_descendants_freeze_count > 0;
5392
gdk_window_schedule_update (GdkWindow *window)
5395
(GDK_WINDOW_OBJECT (window)->update_freeze_count ||
5396
gdk_window_is_toplevel_frozen (window)))
5401
gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
5402
gdk_window_update_idle,
5407
_gdk_window_process_updates_recurse (GdkWindow *window,
5408
GdkRegion *expose_region)
5410
GdkWindowObject *private = (GdkWindowObject *)window;
5411
GdkWindowObject *child;
5412
GdkRegion *child_region;
5414
GList *l, *children;
5416
if (gdk_region_empty (expose_region))
5419
/* Make this reentrancy safe for expose handlers freeing windows */
5420
children = g_list_copy (private->children);
5421
g_list_foreach (children, (GFunc)g_object_ref, NULL);
5423
/* Iterate over children, starting at topmost */
5424
for (l = children; l != NULL; l = l->next)
5428
if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
5431
/* Ignore offscreen children, as they don't draw in their parent and
5432
* don't take part in the clipping */
5433
if (gdk_window_is_offscreen (child))
5438
r.width = child->width;
5439
r.height = child->height;
5441
child_region = gdk_region_rectangle (&r);
5444
/* Adjust shape region to parent window coords */
5445
gdk_region_offset (child->shape, child->x, child->y);
5446
gdk_region_intersect (child_region, child->shape);
5447
gdk_region_offset (child->shape, -child->x, -child->y);
5450
if (child->impl == private->impl)
5452
/* Client side child, expose */
5453
gdk_region_intersect (child_region, expose_region);
5454
gdk_region_subtract (expose_region, child_region);
5455
gdk_region_offset (child_region, -child->x, -child->y);
5456
_gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
5460
/* Native child, just remove area from expose region */
5461
gdk_region_subtract (expose_region, child_region);
5463
gdk_region_destroy (child_region);
5466
g_list_foreach (children, (GFunc)g_object_unref, NULL);
5467
g_list_free (children);
5469
if (!gdk_region_empty (expose_region) &&
5470
!private->destroyed)
5472
if (private->event_mask & GDK_EXPOSURE_MASK)
5476
event.expose.type = GDK_EXPOSE;
5477
event.expose.window = g_object_ref (window);
5478
event.expose.send_event = FALSE;
5479
event.expose.count = 0;
5480
event.expose.region = expose_region;
5481
gdk_region_get_clipbox (expose_region, &event.expose.area);
5483
(*_gdk_event_func) (&event, _gdk_event_data);
5485
g_object_unref (window);
5487
else if (private->bg_pixmap != GDK_NO_BG &&
5488
private->window_type != GDK_WINDOW_FOREIGN)
5490
/* No exposure mask set, so nothing will be drawn, the
5491
* app relies on the background being what it specified
5492
* for the window. So, we need to clear this manually.
5494
* For foreign windows if expose is not set that generally
5495
* means some other client paints them, so don't clear
5498
* We use begin/end_paint around the clear so that we can
5499
* piggyback on the implicit paint */
5501
gdk_window_begin_paint_region (window, expose_region);
5502
gdk_window_clear_region_internal (window, expose_region, FALSE);
5503
gdk_window_end_paint (window);
5508
/* Process and remove any invalid area on the native window by creating
5509
* expose events for the window and all non-native descendants.
5510
* Also processes any outstanding moves on the window before doing
5511
* any drawing. Note that its possible to have outstanding moves without
5512
* any invalid area as we use the update idle mechanism to coalesce
5513
* multiple moves as well as multiple invalidations.
5516
gdk_window_process_updates_internal (GdkWindow *window)
5518
GdkWindowObject *private = (GdkWindowObject *)window;
5519
GdkWindowImplIface *impl_iface;
5520
gboolean save_region = FALSE;
5521
GdkRectangle clip_box;
5524
/* Ensure the window lives while updating it */
5525
g_object_ref (window);
5527
/* If an update got queued during update processing, we can get a
5528
* window in the update queue that has an empty update_area.
5531
* We run this multiple times if needed because on win32 the
5532
* first run can cause new (synchronous) updates from
5533
* gdk_window_flush_outstanding_moves(). However, we
5534
* limit it to two iterations to avoid any potential loops.
5537
while (private->update_area &&
5540
GdkRegion *update_area = private->update_area;
5541
private->update_area = NULL;
5543
if (_gdk_event_func && gdk_window_is_viewable (window))
5545
GdkRegion *expose_region;
5546
gboolean end_implicit;
5548
/* Clip to part visible in toplevel */
5549
gdk_region_intersect (update_area, private->clip_region);
5553
/* Make sure we see the red invalid area before redrawing. */
5554
gdk_display_sync (gdk_drawable_get_display (window));
5558
/* At this point we will be completely redrawing all of update_area.
5559
* If we have any outstanding moves that end up moving stuff inside
5560
* this area we don't actually need to move that as that part would
5561
* be overdrawn by the expose anyway. So, in order to copy less data
5562
* we remove these areas from the outstanding moves.
5564
if (private->outstanding_moves)
5566
GdkWindowRegionMove *move;
5570
remove = gdk_region_copy (update_area);
5571
/* We iterate backwards, starting from the state that would be
5572
if we had applied all the moves. */
5573
for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
5578
/* Don't need this area */
5579
gdk_region_subtract (move->dest_region, remove);
5581
/* However if any of the destination we do need has a source
5582
in the updated region we do need that as a destination for
5583
the earlier moves */
5584
gdk_region_offset (move->dest_region, -move->dx, -move->dy);
5585
gdk_region_subtract (remove, move->dest_region);
5587
if (gdk_region_empty (move->dest_region))
5589
gdk_window_region_move_free (move);
5590
private->outstanding_moves =
5591
g_list_delete_link (private->outstanding_moves, l);
5593
else /* move back */
5594
gdk_region_offset (move->dest_region, move->dx, move->dy);
5596
gdk_region_destroy (remove);
5599
/* By now we a set of window moves that should be applied, and then
5600
* an update region that should be repainted. A trivial implementation
5601
* would just do that in order, however in order to get nicer drawing
5602
* we do some tricks:
5604
* First of all, each subwindow expose may be double buffered by
5605
* itself (depending on widget setting) via
5606
* gdk_window_begin/end_paint(). But we also do an "implicit" paint,
5607
* creating a single pixmap the size of the invalid area on the
5608
* native window which all the individual normal paints will draw
5609
* into. This way in the normal case there will be only one pixmap
5610
* allocated and only once pixmap draw done for all the windows
5611
* in this native window.
5612
* There are a couple of reasons this may fail, for instance, some
5613
* backends (like quartz) do its own double buffering, so we disable
5614
* gdk double buffering there. Secondly, some subwindow could be
5615
* non-double buffered and draw directly to the window outside a
5616
* begin/end_paint pair. That will be lead to a gdk_window_flush
5617
* which immediately executes all outstanding moves and paints+removes
5618
* the implicit paint (further paints will allocate their own pixmap).
5620
* Secondly, in the case of implicit double buffering we expose all
5621
* the child windows into the implicit pixmap before we execute
5622
* the outstanding moves. This way we minimize the time between
5623
* doing the moves and rendering the new update area, thus minimizing
5624
* flashing. Of course, if any subwindow is non-double buffered we
5625
* well flush earlier than that.
5627
* Thirdly, after having done the outstanding moves we queue an
5628
* "antiexpose" on the area that will be drawn by the expose, which
5629
* means that any invalid region on the native window side before
5630
* the first expose drawing operation will be discarded, as it
5631
* has by then been overdrawn with valid data. This means we can
5632
* avoid doing the unnecessary repaint any outstanding expose events.
5635
gdk_region_get_clipbox (update_area, &clip_box);
5636
end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
5637
expose_region = gdk_region_copy (update_area);
5640
/* Rendering is not double buffered by gdk, do outstanding
5641
* moves and queue antiexposure immediately. No need to do
5643
gdk_window_flush_outstanding_moves (window);
5644
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5645
save_region = impl_iface->queue_antiexpose (window, update_area);
5648
/* Render the invalid areas to the implicit paint, by sending exposes.
5649
* May flush if non-double buffered widget draw. */
5650
_gdk_windowing_window_process_updates_recurse (window, expose_region);
5654
/* Do moves right before exposes are rendered to the window */
5655
gdk_window_flush_outstanding_moves (window);
5657
/* By this time we know that any outstanding expose for this
5658
* area is invalid and we can avoid it, so queue an antiexpose.
5659
* However, it may be that due to an non-double buffered expose
5660
* we have already started drawing to the window, so it would
5661
* be to late to anti-expose now. Since this is merely an
5662
* optimization we just avoid doing it at all in that case.
5664
if (private->implicit_paint != NULL &&
5665
!private->implicit_paint->flushed)
5667
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5668
save_region = impl_iface->queue_antiexpose (window, update_area);
5671
gdk_window_end_implicit_paint (window);
5673
gdk_region_destroy (expose_region);
5676
gdk_region_destroy (update_area);
5679
if (private->outstanding_moves)
5681
/* Flush any outstanding moves, may happen if we moved a window but got
5682
no actual invalid area */
5683
gdk_window_flush_outstanding_moves (window);
5686
g_object_unref (window);
5690
flush_all_displays (void)
5692
GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
5695
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
5696
gdk_display_flush (tmp_list->data);
5698
g_slist_free (displays);
5701
/* Currently it is not possible to override
5702
* gdk_window_process_all_updates in the same manner as
5703
* gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
5704
* by implementing the GdkPaintable interface. If in the future a
5705
* backend would need this, the right solution would be to add a
5706
* method to GdkDisplay that can be optionally
5707
* NULL. gdk_window_process_all_updates can then walk the list of open
5708
* displays and call the mehod.
5712
* gdk_window_process_all_updates:
5714
* Calls gdk_window_process_updates() for all windows (see #GdkWindow)
5715
* in the application.
5719
gdk_window_process_all_updates (void)
5721
GSList *old_update_windows = update_windows;
5722
GSList *tmp_list = update_windows;
5723
static gboolean in_process_all_updates = FALSE;
5724
static gboolean got_recursive_update = FALSE;
5726
if (in_process_all_updates)
5728
/* We can't do this now since that would recurse, so
5729
delay it until after the recursion is done. */
5730
got_recursive_update = TRUE;
5735
in_process_all_updates = TRUE;
5736
got_recursive_update = FALSE;
5739
g_source_remove (update_idle);
5741
update_windows = NULL;
5744
_gdk_windowing_before_process_all_updates ();
5748
GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
5750
if (!GDK_WINDOW_DESTROYED (tmp_list->data))
5752
if (private->update_freeze_count ||
5753
gdk_window_is_toplevel_frozen (tmp_list->data))
5754
gdk_window_add_update_window ((GdkWindow *) private);
5756
gdk_window_process_updates_internal (tmp_list->data);
5759
g_object_unref (tmp_list->data);
5760
tmp_list = tmp_list->next;
5763
g_slist_free (old_update_windows);
5765
flush_all_displays ();
5767
_gdk_windowing_after_process_all_updates ();
5769
in_process_all_updates = FALSE;
5771
/* If we ignored a recursive call, schedule a
5772
redraw now so that it eventually happens,
5773
otherwise we could miss an update if nothing
5774
else schedules an update. */
5775
if (got_recursive_update && !update_idle)
5777
gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
5778
gdk_window_update_idle,
5783
* gdk_window_process_updates:
5784
* @window: a #GdkWindow
5785
* @update_children: whether to also process updates for child windows
5787
* Sends one or more expose events to @window. The areas in each
5788
* expose event will cover the entire update area for the window (see
5789
* gdk_window_invalidate_region() for details). Normally GDK calls
5790
* gdk_window_process_all_updates() on your behalf, so there's no
5791
* need to call this function unless you want to force expose events
5792
* to be delivered immediately and synchronously (vs. the usual
5793
* case, where GDK delivers them in an idle handler). Occasionally
5794
* this is useful to produce nicer scrolling behavior, for example.
5798
gdk_window_process_updates (GdkWindow *window,
5799
gboolean update_children)
5801
GdkWindowObject *private = (GdkWindowObject *)window;
5802
GdkWindowObject *impl_window;
5804
g_return_if_fail (GDK_IS_WINDOW (window));
5806
if (GDK_WINDOW_DESTROYED (window))
5809
/* Make sure the window lives during the expose callouts */
5810
g_object_ref (window);
5812
impl_window = gdk_window_get_impl_window (private);
5813
if ((impl_window->update_area ||
5814
impl_window->outstanding_moves) &&
5815
!impl_window->update_freeze_count &&
5816
!gdk_window_is_toplevel_frozen (window) &&
5818
/* Don't recurse into process_updates_internal, we'll
5819
* do the update later when idle instead. */
5820
impl_window->implicit_paint == NULL)
5822
gdk_window_process_updates_internal ((GdkWindow *)impl_window);
5823
gdk_window_remove_update_window ((GdkWindow *)impl_window);
5826
if (update_children)
5828
/* process updates in reverse stacking order so composition or
5829
* painting over achieves the desired effect for offscreen windows
5831
GList *node, *children;
5833
children = g_list_copy (private->children);
5834
g_list_foreach (children, (GFunc)g_object_ref, NULL);
5836
for (node = g_list_last (children); node; node = node->prev)
5838
gdk_window_process_updates (node->data, TRUE);
5839
g_object_unref (node->data);
5842
g_list_free (children);
5845
g_object_unref (window);
5849
gdk_window_invalidate_rect_full (GdkWindow *window,
5850
const GdkRectangle *rect,
5851
gboolean invalidate_children,
5854
GdkRectangle window_rect;
5856
GdkWindowObject *private = (GdkWindowObject *)window;
5858
g_return_if_fail (GDK_IS_WINDOW (window));
5860
if (GDK_WINDOW_DESTROYED (window))
5863
if (private->input_only || !private->viewable)
5870
gdk_drawable_get_size (GDK_DRAWABLE (window),
5872
&window_rect.height);
5873
rect = &window_rect;
5876
region = gdk_region_rectangle (rect);
5877
gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
5878
gdk_region_destroy (region);
5882
* gdk_window_invalidate_rect:
5883
* @window: a #GdkWindow
5884
* @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
5886
* @invalidate_children: whether to also invalidate child windows
5888
* A convenience wrapper around gdk_window_invalidate_region() which
5889
* invalidates a rectangular region. See
5890
* gdk_window_invalidate_region() for details.
5893
gdk_window_invalidate_rect (GdkWindow *window,
5894
const GdkRectangle *rect,
5895
gboolean invalidate_children)
5897
gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
5901
draw_ugly_color (GdkWindow *window,
5902
const GdkRegion *region)
5904
/* Draw ugly color all over the newly-invalid region */
5905
GdkColor ugly_color = { 0, 50000, 10000, 10000 };
5907
GdkRectangle clipbox;
5909
ugly_gc = gdk_gc_new (window);
5910
gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
5911
gdk_gc_set_clip_region (ugly_gc, region);
5913
gdk_region_get_clipbox (region, &clipbox);
5915
gdk_draw_rectangle (window,
5918
clipbox.x, clipbox.y,
5919
clipbox.width, clipbox.height);
5921
g_object_unref (ugly_gc);
5925
impl_window_add_update_area (GdkWindowObject *impl_window,
5928
if (impl_window->update_area)
5929
gdk_region_union (impl_window->update_area, region);
5932
gdk_window_add_update_window ((GdkWindow *)impl_window);
5933
impl_window->update_area = gdk_region_copy (region);
5934
gdk_window_schedule_update ((GdkWindow *)impl_window);
5938
/* clear_bg controls if the region will be cleared to
5939
* the background color/pixmap if the exposure mask is not
5940
* set for the window, whereas this might not otherwise be
5941
* done (unless necessary to emulate background settings).
5942
* Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
5943
* need to clear the background, such as when exposing the area beneath a
5944
* hidden or moved window, but not when an app requests repaint or when the
5945
* windowing system exposes a newly visible area (because then the windowing
5946
* system has already cleared the area).
5949
gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
5950
const GdkRegion *region,
5952
gboolean (*child_func) (GdkWindow *,
5956
GdkWindowObject *private = (GdkWindowObject *)window;
5957
GdkWindowObject *impl_window;
5958
GdkRegion *visible_region;
5961
g_return_if_fail (GDK_IS_WINDOW (window));
5963
if (GDK_WINDOW_DESTROYED (window))
5966
if (private->input_only ||
5967
!private->viewable ||
5968
gdk_region_empty (region) ||
5969
private->window_type == GDK_WINDOW_ROOT)
5972
visible_region = gdk_drawable_get_visible_region (window);
5973
gdk_region_intersect (visible_region, region);
5975
tmp_list = private->children;
5978
GdkWindowObject *child = tmp_list->data;
5980
if (!child->input_only)
5982
GdkRegion *child_region;
5983
GdkRectangle child_rect;
5985
child_rect.x = child->x;
5986
child_rect.y = child->y;
5987
child_rect.width = child->width;
5988
child_rect.height = child->height;
5989
child_region = gdk_region_rectangle (&child_rect);
5991
/* remove child area from the invalid area of the parent */
5992
if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
5993
!child->composited &&
5994
!gdk_window_is_offscreen (child))
5995
gdk_region_subtract (visible_region, child_region);
5997
if (child_func && (*child_func) ((GdkWindow *)child, user_data))
5999
GdkRegion *tmp = gdk_region_copy (region);
6001
gdk_region_offset (tmp, - child_rect.x, - child_rect.y);
6002
gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
6003
gdk_region_intersect (child_region, tmp);
6005
gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
6006
child_region, clear_bg, child_func, user_data);
6008
gdk_region_destroy (tmp);
6011
gdk_region_destroy (child_region);
6014
tmp_list = tmp_list->next;
6017
impl_window = gdk_window_get_impl_window (private);
6019
if (!gdk_region_empty (visible_region) ||
6020
/* Even if we're not exposing anything, make sure we process
6021
idles for windows with outstanding moves */
6022
(impl_window->outstanding_moves != NULL &&
6023
impl_window->update_area == NULL))
6026
draw_ugly_color (window, region);
6028
/* Convert to impl coords */
6029
gdk_region_offset (visible_region, private->abs_x, private->abs_y);
6031
/* Only invalidate area if app requested expose events or if
6032
we need to clear the area (by request or to emulate background
6033
clearing for non-native windows or native windows with no support
6034
for window backgrounds */
6035
if (private->event_mask & GDK_EXPOSURE_MASK ||
6036
clear_bg == CLEAR_BG_ALL ||
6037
(clear_bg == CLEAR_BG_WINCLEARED &&
6038
(!clears_as_native (private) ||
6039
!GDK_WINDOW_IMPL_GET_IFACE (private->impl)->supports_native_bg)))
6040
impl_window_add_update_area (impl_window, visible_region);
6043
gdk_region_destroy (visible_region);
6047
* gdk_window_invalidate_maybe_recurse:
6048
* @window: a #GdkWindow
6049
* @region: a #GdkRegion
6050
* @child_func: function to use to decide if to recurse to a child,
6051
* %NULL means never recurse.
6052
* @user_data: data passed to @child_func
6054
* Adds @region to the update area for @window. The update area is the
6055
* region that needs to be redrawn, or "dirty region." The call
6056
* gdk_window_process_updates() sends one or more expose events to the
6057
* window, which together cover the entire update area. An
6058
* application would normally redraw the contents of @window in
6059
* response to those expose events.
6061
* GDK will call gdk_window_process_all_updates() on your behalf
6062
* whenever your program returns to the main loop and becomes idle, so
6063
* normally there's no need to do that manually, you just need to
6064
* invalidate regions that you know should be redrawn.
6066
* The @child_func parameter controls whether the region of
6067
* each child window that intersects @region will also be invalidated.
6068
* Only children for which @child_func returns TRUE will have the area
6072
gdk_window_invalidate_maybe_recurse (GdkWindow *window,
6073
const GdkRegion *region,
6074
gboolean (*child_func) (GdkWindow *,
6078
gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
6079
child_func, user_data);
6083
true_predicate (GdkWindow *window,
6090
gdk_window_invalidate_region_full (GdkWindow *window,
6091
const GdkRegion *region,
6092
gboolean invalidate_children,
6095
gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
6096
invalidate_children ?
6097
true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
6102
* gdk_window_invalidate_region:
6103
* @window: a #GdkWindow
6104
* @region: a #GdkRegion
6105
* @invalidate_children: %TRUE to also invalidate child windows
6107
* Adds @region to the update area for @window. The update area is the
6108
* region that needs to be redrawn, or "dirty region." The call
6109
* gdk_window_process_updates() sends one or more expose events to the
6110
* window, which together cover the entire update area. An
6111
* application would normally redraw the contents of @window in
6112
* response to those expose events.
6114
* GDK will call gdk_window_process_all_updates() on your behalf
6115
* whenever your program returns to the main loop and becomes idle, so
6116
* normally there's no need to do that manually, you just need to
6117
* invalidate regions that you know should be redrawn.
6119
* The @invalidate_children parameter controls whether the region of
6120
* each child window that intersects @region will also be invalidated.
6121
* If %FALSE, then the update area for child windows will remain
6122
* unaffected. See gdk_window_invalidate_maybe_recurse if you need
6123
* fine grained control over which children are invalidated.
6126
gdk_window_invalidate_region (GdkWindow *window,
6127
const GdkRegion *region,
6128
gboolean invalidate_children)
6130
gdk_window_invalidate_maybe_recurse (window, region,
6131
invalidate_children ?
6132
true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
6137
* _gdk_window_invalidate_for_expose:
6138
* @window: a #GdkWindow
6139
* @region: a #GdkRegion
6141
* Adds @region to the update area for @window. The update area is the
6142
* region that needs to be redrawn, or "dirty region." The call
6143
* gdk_window_process_updates() sends one or more expose events to the
6144
* window, which together cover the entire update area. An
6145
* application would normally redraw the contents of @window in
6146
* response to those expose events.
6148
* GDK will call gdk_window_process_all_updates() on your behalf
6149
* whenever your program returns to the main loop and becomes idle, so
6150
* normally there's no need to do that manually, you just need to
6151
* invalidate regions that you know should be redrawn.
6153
* This version of invalidation is used when you recieve expose events
6154
* from the native window system. It exposes the native window, plus
6155
* any non-native child windows (but not native child windows, as those would
6156
* have gotten their own expose events).
6159
_gdk_window_invalidate_for_expose (GdkWindow *window,
6162
GdkWindowObject *private = (GdkWindowObject *) window;
6163
GdkWindowRegionMove *move;
6164
GdkRegion *move_region;
6167
/* Any invalidations comming from the windowing system will
6168
be in areas that may be moved by outstanding moves,
6169
so we need to modify the expose region correspondingly,
6170
otherwise we would expose in the wrong place, as the
6171
outstanding moves will be copied before we draw the
6173
for (l = private->outstanding_moves; l != NULL; l = l->next)
6177
/* covert to move source region */
6178
move_region = gdk_region_copy (move->dest_region);
6179
gdk_region_offset (move_region, -move->dx, -move->dy);
6181
/* Move area of region that intersects with move source
6182
by dx, dy of the move*/
6183
gdk_region_intersect (move_region, region);
6184
gdk_region_subtract (region, move_region);
6185
gdk_region_offset (move_region, move->dx, move->dy);
6186
gdk_region_union (region, move_region);
6188
gdk_region_destroy (move_region);
6191
gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
6192
(gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
6198
* gdk_window_get_update_area:
6199
* @window: a #GdkWindow
6201
* Transfers ownership of the update area from @window to the caller
6202
* of the function. That is, after calling this function, @window will
6203
* no longer have an invalid/dirty region; the update area is removed
6204
* from @window and handed to you. If a window has no update area,
6205
* gdk_window_get_update_area() returns %NULL. You are responsible for
6206
* calling gdk_region_destroy() on the returned region if it's non-%NULL.
6208
* Return value: the update area for @window
6211
gdk_window_get_update_area (GdkWindow *window)
6213
GdkWindowObject *private = (GdkWindowObject *)window;
6214
GdkWindowObject *impl_window;
6215
GdkRegion *tmp_region;
6217
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6219
impl_window = gdk_window_get_impl_window (private);
6221
if (impl_window->update_area)
6223
tmp_region = gdk_region_copy (private->clip_region_with_children);
6224
/* Convert to impl coords */
6225
gdk_region_offset (tmp_region, private->abs_x, private->abs_y);
6226
gdk_region_intersect (tmp_region, impl_window->update_area);
6228
if (gdk_region_empty (tmp_region))
6230
gdk_region_destroy (tmp_region);
6235
gdk_region_subtract (impl_window->update_area, tmp_region);
6237
if (gdk_region_empty (impl_window->update_area) &&
6238
impl_window->outstanding_moves == NULL)
6240
gdk_region_destroy (impl_window->update_area);
6241
impl_window->update_area = NULL;
6243
gdk_window_remove_update_window ((GdkWindow *)impl_window);
6246
/* Convert from impl coords */
6247
gdk_region_offset (tmp_region, -private->abs_x, -private->abs_y);
6257
* _gdk_window_clear_update_area:
6258
* @window: a #GdkWindow.
6260
* Internal function to clear the update area for a window. This
6261
* is called when the window is hidden or destroyed.
6264
_gdk_window_clear_update_area (GdkWindow *window)
6266
GdkWindowObject *private = (GdkWindowObject *)window;
6268
g_return_if_fail (GDK_IS_WINDOW (window));
6270
if (private->update_area)
6272
gdk_window_remove_update_window (window);
6274
gdk_region_destroy (private->update_area);
6275
private->update_area = NULL;
6280
* gdk_window_freeze_updates:
6281
* @window: a #GdkWindow
6283
* Temporarily freezes a window such that it won't receive expose
6284
* events. The window will begin receiving expose events again when
6285
* gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
6286
* has been called more than once, gdk_window_thaw_updates() must be called
6287
* an equal number of times to begin processing exposes.
6290
gdk_window_freeze_updates (GdkWindow *window)
6292
GdkWindowObject *private = (GdkWindowObject *)window;
6293
GdkWindowObject *impl_window;
6295
g_return_if_fail (GDK_IS_WINDOW (window));
6297
impl_window = gdk_window_get_impl_window (private);
6298
impl_window->update_freeze_count++;
6302
* gdk_window_thaw_updates:
6303
* @window: a #GdkWindow
6305
* Thaws a window frozen with gdk_window_freeze_updates().
6308
gdk_window_thaw_updates (GdkWindow *window)
6310
GdkWindowObject *private = (GdkWindowObject *)window;
6311
GdkWindowObject *impl_window;
6313
g_return_if_fail (GDK_IS_WINDOW (window));
6315
impl_window = gdk_window_get_impl_window (private);
6317
g_return_if_fail (impl_window->update_freeze_count > 0);
6319
if (--impl_window->update_freeze_count == 0)
6320
gdk_window_schedule_update (GDK_WINDOW (impl_window));
6324
* gdk_window_freeze_toplevel_updates_libgtk_only:
6325
* @window: a #GdkWindow
6327
* Temporarily freezes a window and all its descendants such that it won't
6328
* receive expose events. The window will begin receiving expose events
6329
* again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
6330
* gdk_window_freeze_toplevel_updates_libgtk_only()
6331
* has been called more than once,
6332
* gdk_window_thaw_toplevel_updates_libgtk_only() must be called
6333
* an equal number of times to begin processing exposes.
6335
* This function is not part of the GDK public API and is only
6339
gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
6341
GdkWindowObject *private = (GdkWindowObject *)window;
6343
g_return_if_fail (GDK_IS_WINDOW (window));
6344
g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
6346
private->update_and_descendants_freeze_count++;
6350
* gdk_window_thaw_toplevel_updates_libgtk_only:
6351
* @window: a #GdkWindow
6353
* Thaws a window frozen with
6354
* gdk_window_freeze_toplevel_updates_libgtk_only().
6356
* This function is not part of the GDK public API and is only
6360
gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
6362
GdkWindowObject *private = (GdkWindowObject *)window;
6364
g_return_if_fail (GDK_IS_WINDOW (window));
6365
g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
6366
g_return_if_fail (private->update_and_descendants_freeze_count > 0);
6368
private->update_and_descendants_freeze_count--;
6370
gdk_window_schedule_update (window);
6374
* gdk_window_set_debug_updates:
6375
* @setting: %TRUE to turn on update debugging
6377
* With update debugging enabled, calls to
6378
* gdk_window_invalidate_region() clear the invalidated region of the
6379
* screen to a noticeable color, and GDK pauses for a short time
6380
* before sending exposes to windows during
6381
* gdk_window_process_updates(). The net effect is that you can see
6382
* the invalid region for each window and watch redraws as they
6383
* occur. This allows you to diagnose inefficiencies in your application.
6385
* In essence, because the GDK rendering model prevents all flicker,
6386
* if you are redrawing the same region 400 times you may never
6387
* notice, aside from noticing a speed problem. Enabling update
6388
* debugging causes GTK to flicker slowly and noticeably, so you can
6389
* see exactly what's being redrawn when, in what order.
6391
* The --gtk-debug=updates command line option passed to GTK+ programs
6392
* enables this debug option at application startup time. That's
6393
* usually more useful than calling gdk_window_set_debug_updates()
6394
* yourself, though you might want to use this function to enable
6395
* updates sometime after application startup time.
6399
gdk_window_set_debug_updates (gboolean setting)
6401
debug_updates = setting;
6405
* gdk_window_constrain_size:
6406
* @geometry: a #GdkGeometry structure
6407
* @flags: a mask indicating what portions of @geometry are set
6408
* @width: desired width of window
6409
* @height: desired height of the window
6410
* @new_width: (out): location to store resulting width
6411
* @new_height: (out): location to store resulting height
6413
* Constrains a desired width and height according to a
6414
* set of geometry hints (such as minimum and maximum size).
6417
gdk_window_constrain_size (GdkGeometry *geometry,
6424
/* This routine is partially borrowed from fvwm.
6426
* Copyright 1993, Robert Nation
6427
* You may use this code for any purpose, as long as the original
6428
* copyright remains in the source code and all documentation
6430
* which in turn borrows parts of the algorithm from uwm
6433
gint min_height = 0;
6434
gint base_width = 0;
6435
gint base_height = 0;
6438
gint max_width = G_MAXINT;
6439
gint max_height = G_MAXINT;
6441
#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
6443
if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
6445
base_width = geometry->base_width;
6446
base_height = geometry->base_height;
6447
min_width = geometry->min_width;
6448
min_height = geometry->min_height;
6450
else if (flags & GDK_HINT_BASE_SIZE)
6452
base_width = geometry->base_width;
6453
base_height = geometry->base_height;
6454
min_width = geometry->base_width;
6455
min_height = geometry->base_height;
6457
else if (flags & GDK_HINT_MIN_SIZE)
6459
base_width = geometry->min_width;
6460
base_height = geometry->min_height;
6461
min_width = geometry->min_width;
6462
min_height = geometry->min_height;
6465
if (flags & GDK_HINT_MAX_SIZE)
6467
max_width = geometry->max_width ;
6468
max_height = geometry->max_height;
6471
if (flags & GDK_HINT_RESIZE_INC)
6473
xinc = MAX (xinc, geometry->width_inc);
6474
yinc = MAX (yinc, geometry->height_inc);
6477
/* clamp width and height to min and max values
6479
width = CLAMP (width, min_width, max_width);
6480
height = CLAMP (height, min_height, max_height);
6482
/* shrink to base + N * inc
6484
width = base_width + FLOOR (width - base_width, xinc);
6485
height = base_height + FLOOR (height - base_height, yinc);
6487
/* constrain aspect ratio, according to:
6490
* min_aspect <= -------- <= max_aspect
6494
if (flags & GDK_HINT_ASPECT &&
6495
geometry->min_aspect > 0 &&
6496
geometry->max_aspect > 0)
6500
if (geometry->min_aspect * height > width)
6502
delta = FLOOR (height - width / geometry->min_aspect, yinc);
6503
if (height - delta >= min_height)
6507
delta = FLOOR (height * geometry->min_aspect - width, xinc);
6508
if (width + delta <= max_width)
6513
if (geometry->max_aspect * height < width)
6515
delta = FLOOR (width - height * geometry->max_aspect, xinc);
6516
if (width - delta >= min_width)
6520
delta = FLOOR (width / geometry->max_aspect - height, yinc);
6521
if (height + delta <= max_height)
6530
*new_height = height;
6534
* gdk_window_get_pointer:
6535
* @window: a #GdkWindow
6536
* @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
6537
* return the X coordinate
6538
* @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
6539
* return the Y coordinate
6540
* @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
6543
* Obtains the current pointer position and modifier state.
6544
* The position is given in coordinates relative to the upper left
6545
* corner of @window.
6547
* Return value: (transfer none): the window containing the pointer (as with
6548
* gdk_window_at_pointer()), or %NULL if the window containing the
6549
* pointer isn't known to GDK
6552
gdk_window_get_pointer (GdkWindow *window,
6555
GdkModifierType *mask)
6557
GdkDisplay *display;
6559
GdkModifierType tmp_mask;
6562
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
6566
display = gdk_drawable_get_display (window);
6570
GdkScreen *screen = gdk_screen_get_default ();
6572
display = gdk_screen_get_display (screen);
6573
window = gdk_screen_get_root_window (screen);
6575
GDK_NOTE (MULTIHEAD,
6576
g_message ("Passing NULL for window to gdk_window_get_pointer()\n"
6577
"is not multihead safe"));
6580
child = display->pointer_hooks->window_get_pointer (display, window, &tmp_x, &tmp_y, &tmp_mask);
6589
_gdk_display_enable_motion_hints (display);
6595
* gdk_window_at_pointer:
6596
* @win_x: (out) (allow-none): return location for origin of the window under the pointer
6597
* @win_y: (out) (allow-none): return location for origin of the window under the pointer
6599
* Obtains the window underneath the mouse pointer, returning the
6600
* location of that window in @win_x, @win_y. Returns %NULL if the
6601
* window under the mouse pointer is not known to GDK (if the window
6602
* belongs to another application and a #GdkWindow hasn't been created
6603
* for it with gdk_window_foreign_new())
6605
* NOTE: For multihead-aware widgets or applications use
6606
* gdk_display_get_window_at_pointer() instead.
6608
* Return value: (transfer none): window under the mouse pointer
6611
gdk_window_at_pointer (gint *win_x,
6614
return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
6618
* gdk_get_default_root_window:
6620
* Obtains the root window (parent all other windows are inside)
6621
* for the default display and screen.
6623
* Return value: the default root window
6626
gdk_get_default_root_window (void)
6628
return gdk_screen_get_root_window (gdk_screen_get_default ());
6632
* gdk_window_foreign_new:
6633
* @anid: a native window handle.
6635
* Wraps a native window for the default display in a #GdkWindow.
6636
* This may fail if the window has been destroyed.
6638
* For example in the X backend, a native window handle is an Xlib
6641
* Return value: the newly-created #GdkWindow wrapper for the
6642
* native window or %NULL if the window has been destroyed.
6645
gdk_window_foreign_new (GdkNativeWindow anid)
6647
return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
6651
get_all_native_children (GdkWindowObject *private,
6654
GdkWindowObject *child;
6657
for (l = private->children; l != NULL; l = l->next)
6661
if (gdk_window_has_impl (child))
6662
*native = g_list_prepend (*native, child);
6664
get_all_native_children (child, native);
6670
gdk_window_raise_internal (GdkWindow *window)
6672
GdkWindowObject *private = (GdkWindowObject *)window;
6673
GdkWindowObject *parent = private->parent;
6674
GdkWindowObject *above;
6675
GList *native_children;
6677
GdkWindowImplIface *impl_iface;
6681
parent->children = g_list_remove (parent->children, window);
6682
parent->children = g_list_prepend (parent->children, window);
6685
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6686
/* Just do native raise for toplevels */
6687
if (gdk_window_is_toplevel (private) ||
6688
/* The restack_under codepath should work correctly even if the parent
6689
is native, but it relies on the order of ->children to be correct,
6690
and some apps like SWT reorder the x windows without gdks knowledge,
6691
so we use raise directly in order to make these behave as before
6692
when using native windows */
6693
(gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
6695
impl_iface->raise (window);
6697
else if (gdk_window_has_impl (private))
6699
above = find_native_sibling_above (parent, private);
6702
listhead.data = window;
6703
listhead.next = NULL;
6704
listhead.prev = NULL;
6705
impl_iface->restack_under ((GdkWindow *)above,
6709
impl_iface->raise (window);
6713
native_children = NULL;
6714
get_all_native_children (private, &native_children);
6715
if (native_children != NULL)
6717
above = find_native_sibling_above (parent, private);
6720
impl_iface->restack_under ((GdkWindow *)above,
6724
/* Right order, since native_children is bottom-topmost first */
6725
for (l = native_children; l != NULL; l = l->next)
6726
impl_iface->raise (l->data);
6729
g_list_free (native_children);
6735
/* Returns TRUE If the native window was mapped or unmapped */
6737
set_viewable (GdkWindowObject *w,
6740
GdkWindowObject *child;
6741
GdkWindowImplIface *impl_iface;
6744
if (w->viewable == val)
6750
recompute_visible_regions (w, FALSE, FALSE);
6752
for (l = w->children; l != NULL; l = l->next)
6756
if (GDK_WINDOW_IS_MAPPED (child) &&
6757
child->window_type != GDK_WINDOW_FOREIGN)
6758
set_viewable (child, val);
6761
if (!_gdk_native_windows &&
6762
gdk_window_has_impl (w) &&
6763
w->window_type != GDK_WINDOW_FOREIGN &&
6764
!gdk_window_is_toplevel (w))
6766
/* For most native windows we show/hide them not when they are
6767
* mapped/unmapped, because that may not produce the correct results.
6768
* For instance, if a native window have a non-native parent which is
6769
* hidden, but its native parent is viewable then showing the window
6770
* would make it viewable to X but its not viewable wrt the non-native
6771
* hierarchy. In order to handle this we track the gdk side viewability
6772
* and only map really viewable windows.
6774
* There are two exceptions though:
6776
* For foreign windows we don't want ever change the mapped state
6777
* except when explicitly done via gdk_window_show/hide, as this may
6778
* cause problems for client owning the foreign window when its window
6779
* is suddenly mapped or unmapped.
6781
* For toplevel windows embedded in a foreign window (e.g. a plug)
6782
* we sometimes synthesize a map of a window, but the native
6783
* window is really shown by the embedder, so we don't want to
6784
* do the show ourselves. We can't really tell this case from the normal
6785
* toplevel show as such toplevels are seen by gdk as parents of the
6786
* root window, so we make an exception for all toplevels.
6788
* Also, when in GDK_NATIVE_WINDOW mode we never need to play games
6789
* like this, so we just always show/hide directly.
6792
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
6794
impl_iface->show ((GdkWindow *)w, FALSE);
6796
impl_iface->hide ((GdkWindow *)w);
6804
/* Returns TRUE If the native window was mapped or unmapped */
6806
_gdk_window_update_viewable (GdkWindow *window)
6808
GdkWindowObject *priv = (GdkWindowObject *)window;
6811
if (priv->window_type == GDK_WINDOW_FOREIGN ||
6812
priv->window_type == GDK_WINDOW_ROOT)
6814
else if (gdk_window_is_toplevel (priv) ||
6815
priv->parent->viewable)
6816
viewable = GDK_WINDOW_IS_MAPPED (priv);
6820
return set_viewable (priv, viewable);
6824
gdk_window_show_internal (GdkWindow *window, gboolean raise)
6826
GdkWindowObject *private;
6827
GdkWindowImplIface *impl_iface;
6828
gboolean was_mapped, was_viewable;
6831
g_return_if_fail (GDK_IS_WINDOW (window));
6833
private = (GdkWindowObject *) window;
6834
if (private->destroyed)
6837
was_mapped = GDK_WINDOW_IS_MAPPED (window);
6838
was_viewable = private->viewable;
6841
/* Keep children in (reverse) stacking order */
6842
gdk_window_raise_internal (window);
6844
if (gdk_window_has_impl (private))
6847
gdk_synthesize_window_state (window,
6848
GDK_WINDOW_STATE_WITHDRAWN,
6856
did_show = _gdk_window_update_viewable (window);
6858
/* If it was already viewable the backend show op won't be called, call it
6859
again to ensure things happen right if the mapped tracking was not right
6860
for e.g. a foreign window.
6861
Dunno if this is strictly needed but its what happened pre-csw.
6862
Also show if not done by gdk_window_update_viewable. */
6863
if (gdk_window_has_impl (private) && (was_viewable || !did_show))
6865
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6866
impl_iface->show ((GdkWindow *)private,
6867
!did_show ? was_mapped : TRUE);
6870
if (!was_mapped && !gdk_window_has_impl (private))
6872
if (private->event_mask & GDK_STRUCTURE_MASK)
6873
_gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
6875
if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
6876
_gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
6879
if (!was_mapped || raise)
6881
recompute_visible_regions (private, TRUE, FALSE);
6883
/* If any decendants became visible we need to send visibility notify */
6884
gdk_window_update_visibility_recursively (private, NULL);
6886
if (gdk_window_is_viewable (window))
6888
_gdk_synthesize_crossing_events_for_geometry_change (window);
6889
gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
6895
* gdk_window_show_unraised:
6896
* @window: a #GdkWindow
6898
* Shows a #GdkWindow onscreen, but does not modify its stacking
6899
* order. In contrast, gdk_window_show() will raise the window
6900
* to the top of the window stack.
6902
* On the X11 platform, in Xlib terms, this function calls
6903
* XMapWindow() (it also updates some internal GDK state, which means
6904
* that you can't really use XMapWindow() directly on a GDK window).
6907
gdk_window_show_unraised (GdkWindow *window)
6909
gdk_window_show_internal (window, FALSE);
6914
* @window: a #GdkWindow
6916
* Raises @window to the top of the Z-order (stacking order), so that
6917
* other windows with the same parent window appear below @window.
6918
* This is true whether or not the windows are visible.
6920
* If @window is a toplevel, the window manager may choose to deny the
6921
* request to move the window in the Z-order, gdk_window_raise() only
6922
* requests the restack, does not guarantee it.
6925
gdk_window_raise (GdkWindow *window)
6927
GdkWindowObject *private;
6928
GdkRegion *old_region, *new_region;
6930
g_return_if_fail (GDK_IS_WINDOW (window));
6932
private = (GdkWindowObject *) window;
6933
if (private->destroyed)
6936
gdk_window_flush_if_exposing (window);
6939
if (gdk_window_is_viewable (window) &&
6940
!private->input_only)
6941
old_region = gdk_region_copy (private->clip_region);
6943
/* Keep children in (reverse) stacking order */
6944
gdk_window_raise_internal (window);
6946
recompute_visible_regions (private, TRUE, FALSE);
6950
new_region = gdk_region_copy (private->clip_region);
6952
gdk_region_subtract (new_region, old_region);
6953
gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
6955
gdk_region_destroy (old_region);
6956
gdk_region_destroy (new_region);
6961
gdk_window_lower_internal (GdkWindow *window)
6963
GdkWindowObject *private = (GdkWindowObject *)window;
6964
GdkWindowObject *parent = private->parent;
6965
GdkWindowImplIface *impl_iface;
6966
GdkWindowObject *above;
6967
GList *native_children;
6972
parent->children = g_list_remove (parent->children, window);
6973
parent->children = g_list_append (parent->children, window);
6976
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6977
/* Just do native lower for toplevels */
6978
if (gdk_window_is_toplevel (private) ||
6979
/* The restack_under codepath should work correctly even if the parent
6980
is native, but it relies on the order of ->children to be correct,
6981
and some apps like SWT reorder the x windows without gdks knowledge,
6982
so we use lower directly in order to make these behave as before
6983
when using native windows */
6984
(gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
6986
impl_iface->lower (window);
6988
else if (gdk_window_has_impl (private))
6990
above = find_native_sibling_above (parent, private);
6993
listhead.data = window;
6994
listhead.next = NULL;
6995
listhead.prev = NULL;
6996
impl_iface->restack_under ((GdkWindow *)above, &listhead);
6999
impl_iface->raise (window);
7003
native_children = NULL;
7004
get_all_native_children (private, &native_children);
7005
if (native_children != NULL)
7007
above = find_native_sibling_above (parent, private);
7010
impl_iface->restack_under ((GdkWindow *)above,
7014
/* Right order, since native_children is bottom-topmost first */
7015
for (l = native_children; l != NULL; l = l->next)
7016
impl_iface->raise (l->data);
7019
g_list_free (native_children);
7026
gdk_window_invalidate_in_parent (GdkWindowObject *private)
7028
GdkRectangle r, child;
7030
if (gdk_window_is_toplevel (private))
7033
/* get the visible rectangle of the parent */
7035
r.width = private->parent->width;
7036
r.height = private->parent->height;
7038
child.x = private->x;
7039
child.y = private->y;
7040
child.width = private->width;
7041
child.height = private->height;
7042
gdk_rectangle_intersect (&r, &child, &r);
7044
gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
7050
* @window: a #GdkWindow
7052
* Lowers @window to the bottom of the Z-order (stacking order), so that
7053
* other windows with the same parent window appear above @window.
7054
* This is true whether or not the other windows are visible.
7056
* If @window is a toplevel, the window manager may choose to deny the
7057
* request to move the window in the Z-order, gdk_window_lower() only
7058
* requests the restack, does not guarantee it.
7060
* Note that gdk_window_show() raises the window again, so don't call this
7061
* function before gdk_window_show(). (Try gdk_window_show_unraised().)
7064
gdk_window_lower (GdkWindow *window)
7066
GdkWindowObject *private;
7068
g_return_if_fail (GDK_IS_WINDOW (window));
7070
private = (GdkWindowObject *) window;
7071
if (private->destroyed)
7074
gdk_window_flush_if_exposing (window);
7076
/* Keep children in (reverse) stacking order */
7077
gdk_window_lower_internal (window);
7079
recompute_visible_regions (private, TRUE, FALSE);
7081
_gdk_synthesize_crossing_events_for_geometry_change (window);
7082
gdk_window_invalidate_in_parent (private);
7086
* gdk_window_restack:
7087
* @window: a #GdkWindow
7088
* @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
7091
* Changes the position of @window in the Z-order (stacking order), so that
7092
* it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
7095
* If @sibling is %NULL, then this either raises (if @above is %TRUE) or
7096
* lowers the window.
7098
* If @window is a toplevel, the window manager may choose to deny the
7099
* request to move the window in the Z-order, gdk_window_restack() only
7100
* requests the restack, does not guarantee it.
7105
gdk_window_restack (GdkWindow *window,
7109
GdkWindowObject *private;
7110
GdkWindowImplIface *impl_iface;
7111
GdkWindowObject *parent;
7112
GdkWindowObject *above_native;
7113
GList *sibling_link;
7114
GList *native_children;
7117
g_return_if_fail (GDK_IS_WINDOW (window));
7118
g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
7120
private = (GdkWindowObject *) window;
7121
if (private->destroyed)
7124
if (sibling == NULL)
7127
gdk_window_raise (window);
7129
gdk_window_lower (window);
7133
gdk_window_flush_if_exposing (window);
7135
if (gdk_window_is_toplevel (private))
7137
g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
7138
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7139
impl_iface->restack_toplevel (window, sibling, above);
7143
parent = private->parent;
7146
sibling_link = g_list_find (parent->children, sibling);
7147
g_return_if_fail (sibling_link != NULL);
7148
if (sibling_link == NULL)
7151
parent->children = g_list_remove (parent->children, window);
7153
parent->children = g_list_insert_before (parent->children,
7157
parent->children = g_list_insert_before (parent->children,
7161
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7162
if (gdk_window_has_impl (private))
7164
above_native = find_native_sibling_above (parent, private);
7167
listhead.data = window;
7168
listhead.next = NULL;
7169
listhead.prev = NULL;
7170
impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
7173
impl_iface->raise (window);
7177
native_children = NULL;
7178
get_all_native_children (private, &native_children);
7179
if (native_children != NULL)
7181
above_native = find_native_sibling_above (parent, private);
7183
impl_iface->restack_under ((GdkWindow *)above_native,
7187
/* Right order, since native_children is bottom-topmost first */
7188
for (l = native_children; l != NULL; l = l->next)
7189
impl_iface->raise (l->data);
7192
g_list_free (native_children);
7197
recompute_visible_regions (private, TRUE, FALSE);
7199
_gdk_synthesize_crossing_events_for_geometry_change (window);
7200
gdk_window_invalidate_in_parent (private);
7206
* @window: a #GdkWindow
7208
* Like gdk_window_show_unraised(), but also raises the window to the
7209
* top of the window stack (moves the window to the front of the
7212
* This function maps a window so it's visible onscreen. Its opposite
7213
* is gdk_window_hide().
7215
* When implementing a #GtkWidget, you should call this function on the widget's
7216
* #GdkWindow as part of the "map" method.
7219
gdk_window_show (GdkWindow *window)
7221
gdk_window_show_internal (window, TRUE);
7226
* @window: a #GdkWindow
7228
* For toplevel windows, withdraws them, so they will no longer be
7229
* known to the window manager; for all windows, unmaps them, so
7230
* they won't be displayed. Normally done automatically as
7231
* part of gtk_widget_hide().
7234
gdk_window_hide (GdkWindow *window)
7236
GdkWindowObject *private;
7237
GdkWindowImplIface *impl_iface;
7238
gboolean was_mapped, did_hide;
7240
g_return_if_fail (GDK_IS_WINDOW (window));
7242
private = (GdkWindowObject *) window;
7243
if (private->destroyed)
7246
was_mapped = GDK_WINDOW_IS_MAPPED (private);
7248
if (gdk_window_has_impl (private))
7251
if (GDK_WINDOW_IS_MAPPED (window))
7252
gdk_synthesize_window_state (window,
7254
GDK_WINDOW_STATE_WITHDRAWN);
7256
else if (was_mapped)
7258
GdkDisplay *display;
7260
/* May need to break grabs on children */
7261
display = gdk_drawable_get_display (window);
7263
if (_gdk_display_end_pointer_grab (display,
7264
_gdk_windowing_window_get_next_serial (display),
7267
gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
7269
if (display->keyboard_grab.window != NULL)
7271
if (is_parent_of (window, display->keyboard_grab.window))
7273
/* Call this ourselves, even though gdk_display_keyboard_ungrab
7274
does so too, since we want to pass implicit == TRUE so the
7275
broken grab event is generated */
7276
_gdk_display_unset_has_keyboard_grab (display,
7278
gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
7282
private->state = GDK_WINDOW_STATE_WITHDRAWN;
7285
did_hide = _gdk_window_update_viewable (window);
7287
/* Hide foreign window as those are not handled by update_viewable. */
7288
if (gdk_window_has_impl (private) && (!did_hide))
7290
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7291
impl_iface->hide (window);
7294
recompute_visible_regions (private, TRUE, FALSE);
7296
/* all decendants became non-visible, we need to send visibility notify */
7297
gdk_window_update_visibility_recursively (private, NULL);
7299
if (was_mapped && !gdk_window_has_impl (private))
7301
if (private->event_mask & GDK_STRUCTURE_MASK)
7302
_gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7304
if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
7305
_gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7307
_gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
7310
/* Invalidate the rect */
7312
gdk_window_invalidate_in_parent (private);
7316
* gdk_window_withdraw:
7317
* @window: a toplevel #GdkWindow
7319
* Withdraws a window (unmaps it and asks the window manager to forget about it).
7320
* This function is not really useful as gdk_window_hide() automatically
7321
* withdraws toplevel windows before hiding them.
7324
gdk_window_withdraw (GdkWindow *window)
7326
GdkWindowObject *private;
7327
GdkWindowImplIface *impl_iface;
7328
gboolean was_mapped;
7330
g_return_if_fail (GDK_IS_WINDOW (window));
7332
private = (GdkWindowObject *) window;
7333
if (private->destroyed)
7336
was_mapped = GDK_WINDOW_IS_MAPPED (private);
7338
if (gdk_window_has_impl (private))
7340
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7341
impl_iface->withdraw (window);
7345
if (private->event_mask & GDK_STRUCTURE_MASK)
7346
_gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7348
if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
7349
_gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
7351
_gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
7354
recompute_visible_regions (private, TRUE, FALSE);
7359
* gdk_window_set_events:
7360
* @window: a #GdkWindow
7361
* @event_mask: event mask for @window
7363
* The event mask for a window determines which events will be reported
7364
* for that window. For example, an event mask including #GDK_BUTTON_PRESS_MASK
7365
* means the window should report button press events. The event mask
7366
* is the bitwise OR of values from the #GdkEventMask enumeration.
7369
gdk_window_set_events (GdkWindow *window,
7370
GdkEventMask event_mask)
7372
GdkWindowObject *private;
7373
GdkWindowImplIface *impl_iface;
7374
GdkDisplay *display;
7376
g_return_if_fail (GDK_IS_WINDOW (window));
7378
private = (GdkWindowObject *) window;
7379
if (private->destroyed)
7382
/* If motion hint is disabled, enable motion events again */
7383
display = gdk_drawable_get_display (window);
7384
if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
7385
!(event_mask & GDK_POINTER_MOTION_HINT_MASK))
7386
_gdk_display_enable_motion_hints (display);
7388
private->event_mask = event_mask;
7390
if (gdk_window_has_impl (private))
7392
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7393
impl_iface->set_events (window,
7394
get_native_event_mask (private));
7400
* gdk_window_get_events:
7401
* @window: a #GdkWindow
7403
* Gets the event mask for @window. See gdk_window_set_events().
7405
* Return value: event mask for @window
7408
gdk_window_get_events (GdkWindow *window)
7410
GdkWindowObject *private;
7412
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7414
private = (GdkWindowObject *) window;
7415
if (private->destroyed)
7418
return private->event_mask;
7422
gdk_window_move_resize_toplevel (GdkWindow *window,
7429
GdkWindowObject *private;
7430
GdkRegion *old_region, *new_region;
7431
GdkWindowImplIface *impl_iface;
7433
int old_x, old_y, old_abs_x, old_abs_y;
7437
private = (GdkWindowObject *) window;
7445
is_resize = (width != -1) || (height != -1);
7447
if (gdk_window_is_viewable (window) &&
7448
!private->input_only)
7451
old_region = gdk_region_copy (private->clip_region);
7454
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7455
impl_iface->move_resize (window, with_move, x, y, width, height);
7457
dx = private->x - old_x;
7458
dy = private->y - old_y;
7460
old_abs_x = private->abs_x;
7461
old_abs_y = private->abs_y;
7463
/* Avoid recomputing for pure toplevel moves, for performance reasons */
7465
recompute_visible_regions (private, TRUE, FALSE);
7469
new_region = gdk_region_copy (private->clip_region);
7471
/* This is the newly exposed area (due to any resize),
7472
* X will expose it, but lets do that without the
7475
gdk_region_subtract (new_region, old_region);
7476
gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
7478
gdk_region_destroy (old_region);
7479
gdk_region_destroy (new_region);
7482
_gdk_synthesize_crossing_events_for_geometry_change (window);
7487
move_native_children (GdkWindowObject *private)
7490
GdkWindowObject *child;
7491
GdkWindowImplIface *impl_iface;
7493
for (l = private->children; l; l = l->next)
7497
if (child->impl != private->impl)
7499
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
7500
impl_iface->move_resize ((GdkWindow *)child, TRUE,
7502
child->width, child->height);
7505
move_native_children (child);
7510
collect_native_child_region_helper (GdkWindowObject *window,
7516
GdkWindowObject *child;
7520
for (l = window->children; l != NULL; l = l->next)
7524
if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
7527
if (child->impl != impl)
7529
tmp = gdk_region_copy (child->clip_region);
7530
gdk_region_offset (tmp,
7531
x_offset + child->x,
7532
y_offset + child->y);
7533
if (*region == NULL)
7537
gdk_region_union (*region, tmp);
7538
gdk_region_destroy (tmp);
7542
collect_native_child_region_helper (child, impl, region,
7543
x_offset + child->x,
7544
y_offset + child->y);
7551
collect_native_child_region (GdkWindowObject *window,
7552
gboolean include_this)
7556
if (include_this && gdk_window_has_impl (window) && window->viewable)
7557
return gdk_region_copy (window->clip_region);
7561
collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
7568
gdk_window_move_resize_internal (GdkWindow *window,
7575
GdkWindowObject *private;
7576
GdkRegion *old_region, *new_region, *copy_area;
7577
GdkRegion *old_native_child_region, *new_native_child_region;
7578
GdkWindowObject *impl_window;
7579
GdkWindowImplIface *impl_iface;
7581
int old_x, old_y, old_abs_x, old_abs_y;
7584
g_return_if_fail (GDK_IS_WINDOW (window));
7586
private = (GdkWindowObject *) window;
7587
if (private->destroyed)
7590
if (gdk_window_is_toplevel (private))
7592
gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
7596
/* Bail early if no change */
7597
if (private->width == width &&
7598
private->height == height &&
7604
gdk_window_flush_if_exposing (window);
7606
/* Handle child windows */
7611
impl_window = gdk_window_get_impl_window (private);
7616
old_native_child_region = NULL;
7617
if (gdk_window_is_viewable (window) &&
7618
!private->input_only)
7622
old_region = gdk_region_copy (private->clip_region);
7623
/* Adjust region to parent window coords */
7624
gdk_region_offset (old_region, private->x, private->y);
7626
old_native_child_region = collect_native_child_region (private, TRUE);
7627
if (old_native_child_region)
7629
/* Adjust region to parent window coords */
7630
gdk_region_offset (old_native_child_region, private->x, private->y);
7632
/* Any native window move will immediately copy stuff to the destination, which may overwrite a
7633
* source or destination for a delayed GdkWindowRegionMove. So, we need
7634
* to flush those here for the parent window and all overlapped subwindows
7635
* of it. And we need to do this before setting the new clips as those will be
7638
gdk_window_flush_recursive (private->parent);
7642
/* Set the new position and size */
7648
if (!(width < 0 && height < 0))
7652
private->width = width;
7655
private->height = height;
7658
dx = private->x - old_x;
7659
dy = private->y - old_y;
7661
old_abs_x = private->abs_x;
7662
old_abs_y = private->abs_y;
7664
recompute_visible_regions (private, TRUE, FALSE);
7666
new_native_child_region = NULL;
7667
if (old_native_child_region)
7669
new_native_child_region = collect_native_child_region (private, TRUE);
7670
/* Adjust region to parent window coords */
7671
gdk_region_offset (new_native_child_region, private->x, private->y);
7674
if (gdk_window_has_impl (private))
7676
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7678
/* Do the actual move after recomputing things, as this will have set the shape to
7679
the now correct one, thus avoiding copying regions that should not be copied. */
7680
impl_iface->move_resize (window, TRUE,
7681
private->x, private->y,
7682
private->width, private->height);
7684
else if (old_abs_x != private->abs_x ||
7685
old_abs_y != private->abs_y)
7686
move_native_children (private);
7690
new_region = gdk_region_copy (private->clip_region);
7691
/* Adjust region to parent window coords */
7692
gdk_region_offset (new_region, private->x, private->y);
7695
* Part of the data at the new location can be copied from the
7696
* old location, this area is the intersection of the old region
7697
* moved as the copy will move it and then intersected with
7701
* Everything in the old and new regions that is not copied must be
7702
* invalidated (including children) as this is newly exposed
7704
copy_area = gdk_region_copy (new_region);
7706
gdk_region_union (new_region, old_region);
7708
if (old_native_child_region)
7710
/* Don't copy from inside native children, as this is copied by
7711
* the native window move.
7713
gdk_region_subtract (old_region, old_native_child_region);
7715
gdk_region_offset (old_region, dx, dy);
7717
gdk_region_intersect (copy_area, old_region);
7719
if (new_native_child_region)
7721
/* Don't copy any bits that would cause a read from the moved
7722
native windows, as we can't read that data */
7723
gdk_region_offset (new_native_child_region, dx, dy);
7724
gdk_region_subtract (copy_area, new_native_child_region);
7725
gdk_region_offset (new_native_child_region, -dx, -dy);
7728
gdk_region_subtract (new_region, copy_area);
7730
/* Convert old region to impl coords */
7731
gdk_region_offset (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
7733
/* convert from parent coords to impl */
7734
gdk_region_offset (copy_area, private->abs_x - private->x, private->abs_y - private->y);
7736
move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
7738
/* Invalidate affected part in the parent window
7739
* (no higher window should be affected)
7740
* We also invalidate any children in that area, which could include
7741
* this window if it still overlaps that area.
7743
if (old_native_child_region)
7745
/* No need to expose the region that the native window move copies */
7746
gdk_region_offset (old_native_child_region, dx, dy);
7747
gdk_region_intersect (old_native_child_region, new_native_child_region);
7748
gdk_region_subtract (new_region, old_native_child_region);
7750
gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
7752
gdk_region_destroy (old_region);
7753
gdk_region_destroy (new_region);
7756
if (old_native_child_region)
7758
gdk_region_destroy (old_native_child_region);
7759
gdk_region_destroy (new_native_child_region);
7762
_gdk_synthesize_crossing_events_for_geometry_change (window);
7769
* @window: a #GdkWindow
7770
* @x: X coordinate relative to window's parent
7771
* @y: Y coordinate relative to window's parent
7773
* Repositions a window relative to its parent window.
7774
* For toplevel windows, window managers may ignore or modify the move;
7775
* you should probably use gtk_window_move() on a #GtkWindow widget
7776
* anyway, instead of using GDK functions. For child windows,
7777
* the move will reliably succeed.
7779
* If you're also planning to resize the window, use gdk_window_move_resize()
7780
* to both move and resize simultaneously, for a nicer visual effect.
7783
gdk_window_move (GdkWindow *window,
7787
gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
7791
* gdk_window_resize:
7792
* @window: a #GdkWindow
7793
* @width: new width of the window
7794
* @height: new height of the window
7796
* Resizes @window; for toplevel windows, asks the window manager to resize
7797
* the window. The window manager may not allow the resize. When using GTK+,
7798
* use gtk_window_resize() instead of this low-level GDK function.
7800
* Windows may not be resized below 1x1.
7802
* If you're also planning to move the window, use gdk_window_move_resize()
7803
* to both move and resize simultaneously, for a nicer visual effect.
7806
gdk_window_resize (GdkWindow *window,
7810
gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
7815
* gdk_window_move_resize:
7816
* @window: a #GdkWindow
7817
* @x: new X position relative to window's parent
7818
* @y: new Y position relative to window's parent
7820
* @height: new height
7822
* Equivalent to calling gdk_window_move() and gdk_window_resize(),
7823
* except that both operations are performed at once, avoiding strange
7824
* visual effects. (i.e. the user may be able to see the window first
7825
* move, then resize, if you don't use gdk_window_move_resize().)
7828
gdk_window_move_resize (GdkWindow *window,
7834
gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
7839
* gdk_window_scroll:
7840
* @window: a #GdkWindow
7841
* @dx: Amount to scroll in the X direction
7842
* @dy: Amount to scroll in the Y direction
7844
* Scroll the contents of @window, both pixels and children, by the
7845
* given amount. @window itself does not move. Portions of the window
7846
* that the scroll operation brings in from offscreen areas are
7847
* invalidated. The invalidated region may be bigger than what would
7848
* strictly be necessary.
7850
* For X11, a minimum area will be invalidated if the window has no
7851
* subwindows, or if the edges of the window's parent do not extend
7852
* beyond the edges of the window. In other cases, a multi-step process
7853
* is used to scroll the window which may produce temporary visual
7854
* artifacts and unnecessary invalidations.
7857
gdk_window_scroll (GdkWindow *window,
7861
GdkWindowObject *private = (GdkWindowObject *) window;
7862
GdkWindowObject *impl_window;
7863
GdkRegion *copy_area, *noncopy_area;
7864
GdkRegion *old_native_child_region, *new_native_child_region;
7867
g_return_if_fail (GDK_IS_WINDOW (window));
7869
if (dx == 0 && dy == 0)
7872
if (private->destroyed)
7875
gdk_window_flush_if_exposing (window);
7877
old_native_child_region = collect_native_child_region (private, FALSE);
7878
if (old_native_child_region)
7880
/* Any native window move will immediately copy stuff to the destination, which may overwrite a
7881
* source or destination for a delayed GdkWindowRegionMove. So, we need
7882
* to flush those here for the window and all overlapped subwindows
7883
* of it. And we need to do this before setting the new clips as those will be
7886
gdk_window_flush_recursive (private);
7890
/* First move all child windows, without causing invalidation */
7892
tmp_list = private->children;
7895
GdkWindow *child = GDK_WINDOW (tmp_list->data);
7896
GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
7898
/* Just update the positions, the bits will move with the copy */
7902
tmp_list = tmp_list->next;
7905
recompute_visible_regions (private, FALSE, TRUE);
7907
new_native_child_region = NULL;
7908
if (old_native_child_region)
7909
new_native_child_region = collect_native_child_region (private, FALSE);
7911
move_native_children (private);
7913
/* Then copy the actual bits of the window w/ child windows */
7915
impl_window = gdk_window_get_impl_window (private);
7917
/* Calculate the area that can be gotten by copying the old area */
7918
copy_area = gdk_region_copy (private->clip_region);
7919
if (old_native_child_region)
7921
/* Don't copy from inside native children, as this is copied by
7922
* the native window move.
7924
gdk_region_subtract (copy_area, old_native_child_region);
7926
/* Don't copy any bits that would cause a read from the moved
7927
native windows, as we can't read that data */
7928
gdk_region_subtract (copy_area, new_native_child_region);
7930
gdk_region_offset (copy_area, dx, dy);
7931
gdk_region_intersect (copy_area, private->clip_region);
7933
/* And the rest need to be invalidated */
7934
noncopy_area = gdk_region_copy (private->clip_region);
7935
gdk_region_subtract (noncopy_area, copy_area);
7937
/* convert from window coords to impl */
7938
gdk_region_offset (copy_area, private->abs_x, private->abs_y);
7940
move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
7942
/* Invalidate not copied regions */
7943
if (old_native_child_region)
7945
/* No need to expose the region that the native window move copies */
7946
gdk_region_offset (old_native_child_region, dx, dy);
7947
gdk_region_intersect (old_native_child_region, new_native_child_region);
7948
gdk_region_subtract (noncopy_area, old_native_child_region);
7950
gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
7952
gdk_region_destroy (noncopy_area);
7954
if (old_native_child_region)
7956
gdk_region_destroy (old_native_child_region);
7957
gdk_region_destroy (new_native_child_region);
7960
_gdk_synthesize_crossing_events_for_geometry_change (window);
7964
* gdk_window_move_region:
7965
* @window: a #GdkWindow
7966
* @region: The #GdkRegion to move
7967
* @dx: Amount to move in the X direction
7968
* @dy: Amount to move in the Y direction
7970
* Move the part of @window indicated by @region by @dy pixels in the Y
7971
* direction and @dx pixels in the X direction. The portions of @region
7972
* that not covered by the new position of @region are invalidated.
7974
* Child windows are not moved.
7979
gdk_window_move_region (GdkWindow *window,
7980
const GdkRegion *region,
7984
GdkWindowObject *private = (GdkWindowObject *) window;
7985
GdkWindowObject *impl_window;
7986
GdkRegion *nocopy_area;
7987
GdkRegion *copy_area;
7989
g_return_if_fail (GDK_IS_WINDOW (window));
7990
g_return_if_fail (region != NULL);
7992
if (dx == 0 && dy == 0)
7995
if (private->destroyed)
7998
impl_window = gdk_window_get_impl_window (private);
8000
/* compute source regions */
8001
copy_area = gdk_region_copy (region);
8002
gdk_region_intersect (copy_area, private->clip_region_with_children);
8004
/* compute destination regions */
8005
gdk_region_offset (copy_area, dx, dy);
8006
gdk_region_intersect (copy_area, private->clip_region_with_children);
8008
/* Invalidate parts of the region (source and dest) not covered
8010
nocopy_area = gdk_region_copy (region);
8011
gdk_region_offset (nocopy_area, dx, dy);
8012
gdk_region_union (nocopy_area, region);
8013
gdk_region_subtract (nocopy_area, copy_area);
8015
/* convert from window coords to impl */
8016
gdk_region_offset (copy_area, private->abs_x, private->abs_y);
8017
move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
8019
gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
8020
gdk_region_destroy (nocopy_area);
8024
* gdk_window_set_background:
8025
* @window: a #GdkWindow
8026
* @color: an allocated #GdkColor
8028
* Sets the background color of @window. (However, when using GTK+,
8029
* set the background of a widget with gtk_widget_modify_bg() - if
8030
* you're an application - or gtk_style_set_background() - if you're
8031
* implementing a custom widget.)
8033
* The @color must be allocated; gdk_rgb_find_color() is the best way
8034
* to allocate a color.
8036
* See also gdk_window_set_back_pixmap().
8039
gdk_window_set_background (GdkWindow *window,
8040
const GdkColor *color)
8042
GdkWindowObject *private;
8043
GdkColormap *colormap = gdk_drawable_get_colormap (window);
8044
GdkWindowImplIface *impl_iface;
8046
g_return_if_fail (GDK_IS_WINDOW (window));
8048
private = (GdkWindowObject *) window;
8050
private->bg_color = *color;
8051
gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
8053
if (private->bg_pixmap &&
8054
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
8055
private->bg_pixmap != GDK_NO_BG)
8056
g_object_unref (private->bg_pixmap);
8058
private->bg_pixmap = NULL;
8060
if (private->background)
8062
cairo_pattern_destroy (private->background);
8063
private->background = NULL;
8066
if (!GDK_WINDOW_DESTROYED (window) &&
8067
gdk_window_has_impl (private) &&
8068
!private->input_only)
8070
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8071
impl_iface->set_background (window, &private->bg_color);
8076
* gdk_window_set_back_pixmap:
8077
* @window: a #GdkWindow
8078
* @pixmap: (allow-none): a #GdkPixmap, or %NULL
8079
* @parent_relative: whether the tiling origin is at the origin of
8082
* Sets the background pixmap of @window. May also be used to set a
8083
* background of "None" on @window, by setting a background pixmap
8086
* A background pixmap will be tiled, positioning the first tile at
8087
* the origin of @window, or if @parent_relative is %TRUE, the tiling
8088
* will be done based on the origin of the parent window (useful to
8089
* align tiles in a parent with tiles in a child).
8091
* A background pixmap of %NULL means that the window will have no
8092
* background. A window with no background will never have its
8093
* background filled by the windowing system, instead the window will
8094
* contain whatever pixels were already in the corresponding area of
8097
* The windowing system will normally fill a window with its background
8098
* when the window is obscured then exposed, and when you call
8099
* gdk_window_clear().
8102
gdk_window_set_back_pixmap (GdkWindow *window,
8104
gboolean parent_relative)
8106
GdkWindowObject *private;
8107
GdkWindowImplIface *impl_iface;
8109
g_return_if_fail (GDK_IS_WINDOW (window));
8110
g_return_if_fail (pixmap == NULL || !parent_relative);
8111
g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
8113
private = (GdkWindowObject *) window;
8115
if (pixmap && !gdk_drawable_get_colormap (pixmap))
8117
g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
8121
if (private->bg_pixmap &&
8122
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
8123
private->bg_pixmap != GDK_NO_BG)
8124
g_object_unref (private->bg_pixmap);
8126
if (private->background)
8128
cairo_pattern_destroy (private->background);
8129
private->background = NULL;
8132
if (parent_relative)
8133
private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
8135
private->bg_pixmap = g_object_ref (pixmap);
8137
private->bg_pixmap = GDK_NO_BG;
8139
if (!GDK_WINDOW_DESTROYED (window) &&
8140
gdk_window_has_impl (private) &&
8141
!private->input_only)
8143
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8144
impl_iface->set_back_pixmap (window, private->bg_pixmap);
8149
* gdk_window_get_background_pattern:
8152
* Gets the pattern used to clear the background on @window. If @window
8153
* does not have its own background and reuses the parent's, %NULL is
8154
* returned and you'll have to query it yourself.
8156
* Returns: (transfer none): The pattern to use for the background or
8157
* %NULL to use the parent's background.
8162
gdk_window_get_background_pattern (GdkWindow *window)
8164
GdkWindowObject *private = (GdkWindowObject *) window;
8166
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
8168
if (private->background == NULL)
8170
if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG)
8171
private->background = NULL;
8172
else if (private->bg_pixmap != GDK_NO_BG &&
8173
private->bg_pixmap != NULL)
8175
static cairo_user_data_key_t key;
8176
cairo_surface_t *surface;
8178
surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
8179
private->background = cairo_pattern_create_for_surface (surface);
8180
cairo_surface_destroy (surface);
8182
cairo_pattern_set_extend (private->background, CAIRO_EXTEND_REPEAT);
8183
cairo_pattern_set_user_data (private->background,
8185
g_object_ref (private->bg_pixmap),
8189
private->background =
8190
cairo_pattern_create_rgb (private->bg_color.red / 65535.,
8191
private->bg_color.green / 65535.,
8192
private->bg_color.blue / 65535.);
8195
return private->background;
8199
* gdk_window_get_cursor:
8200
* @window: a #GdkWindow
8202
* Retrieves a #GdkCursor pointer for the cursor currently set on the
8203
* specified #GdkWindow, or %NULL. If the return value is %NULL then
8204
* there is no custom cursor set on the specified window, and it is
8205
* using the cursor for its parent window.
8207
* Return value: (transfer none): a #GdkCursor, or %NULL. The returned
8208
* object is owned by the #GdkWindow and should not be unreferenced
8209
* directly. Use gdk_window_set_cursor() to unset the cursor of the
8215
gdk_window_get_cursor (GdkWindow *window)
8217
GdkWindowObject *private;
8219
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
8221
private = (GdkWindowObject *) window;
8223
return private->cursor;
8227
* gdk_window_set_cursor:
8228
* @window: a #GdkWindow
8229
* @cursor: (allow-none): a cursor
8231
* Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
8232
* or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor
8233
* invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
8234
* to gdk_window_set_cursor() means that @window will use the cursor of its
8235
* parent window. Most windows should use this default.
8238
gdk_window_set_cursor (GdkWindow *window,
8241
GdkWindowObject *private;
8242
GdkWindowImplIface *impl_iface;
8243
GdkDisplay *display;
8245
g_return_if_fail (GDK_IS_WINDOW (window));
8247
private = (GdkWindowObject *) window;
8248
display = gdk_drawable_get_display (window);
8250
if (private->cursor)
8252
gdk_cursor_unref (private->cursor);
8253
private->cursor = NULL;
8256
if (!GDK_WINDOW_DESTROYED (window))
8259
private->cursor = gdk_cursor_ref (cursor);
8261
if (_gdk_native_windows ||
8262
private->window_type == GDK_WINDOW_ROOT ||
8263
private->window_type == GDK_WINDOW_FOREIGN)
8265
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8266
impl_iface->set_cursor (window, cursor);
8268
else if (_gdk_window_event_parent_of (window, display->pointer_info.window_under_pointer))
8269
update_cursor (display);
8271
g_object_notify (G_OBJECT (window), "cursor");
8276
* gdk_window_get_geometry:
8277
* @window: a #GdkWindow
8278
* @x: return location for X coordinate of window (relative to its parent)
8279
* @y: return location for Y coordinate of window (relative to its parent)
8280
* @width: return location for width of window
8281
* @height: return location for height of window
8282
* @depth: return location for bit depth of window
8284
* Any of the return location arguments to this function may be %NULL,
8285
* if you aren't interested in getting the value of that field.
8287
* The X and Y coordinates returned are relative to the parent window
8288
* of @window, which for toplevels usually means relative to the
8289
* window decorations (titlebar, etc.) rather than relative to the
8290
* root window (screen-size background window).
8292
* On the X11 platform, the geometry is obtained from the X server,
8293
* so reflects the latest position of @window; this may be out-of-sync
8294
* with the position of @window delivered in the most-recently-processed
8295
* #GdkEventConfigure. gdk_window_get_position() in contrast gets the
8296
* position from the most recent configure event.
8299
* If @window is not a toplevel, it is <emphasis>much</emphasis> better
8300
* to call gdk_window_get_position() and gdk_drawable_get_size() instead,
8301
* because it avoids the roundtrip to the X server and because
8302
* gdk_drawable_get_size() supports the full 32-bit coordinate space,
8303
* whereas gdk_window_get_geometry() is restricted to the 16-bit
8304
* coordinates of X11.
8308
gdk_window_get_geometry (GdkWindow *window,
8315
GdkWindowObject *private, *parent;
8316
GdkWindowImplIface *impl_iface;
8320
GDK_NOTE (MULTIHEAD,
8321
g_message ("gdk_window_get_geometry(): Window needs "
8322
"to be non-NULL to be multi head safe"));
8323
window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
8326
g_return_if_fail (GDK_IS_WINDOW (window));
8328
private = (GdkWindowObject *) window;
8330
if (!GDK_WINDOW_DESTROYED (window))
8332
if (gdk_window_has_impl (private))
8334
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8335
impl_iface->get_geometry (window, x, y,
8338
/* This reports the position wrt to the native parent, we need to convert
8339
it to be relative to the client side parent */
8340
parent = private->parent;
8341
if (parent && !gdk_window_has_impl (parent))
8344
*x -= parent->abs_x;
8346
*y -= parent->abs_y;
8356
*width = private->width;
8358
*height = private->height;
8360
*depth = private->depth;
8366
* gdk_window_get_origin:
8367
* @window: a #GdkWindow
8368
* @x: return location for X coordinate
8369
* @y: return location for Y coordinate
8371
* Obtains the position of a window in root window coordinates.
8372
* (Compare with gdk_window_get_position() and
8373
* gdk_window_get_geometry() which return the position of a window
8374
* relative to its parent window.)
8376
* Return value: not meaningful, ignore
8379
gdk_window_get_origin (GdkWindow *window,
8383
GdkWindowObject *private;
8384
GdkWindowImplIface *impl_iface;
8386
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8388
if (GDK_WINDOW_DESTROYED (window))
8397
private = (GdkWindowObject *) window;
8399
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8400
impl_iface->get_root_coords (window,
8409
* gdk_window_get_root_coords:
8410
* @window: a #GdkWindow
8411
* @x: X coordinate in window
8412
* @y: Y coordinate in window
8413
* @root_x: (out): return location for X coordinate
8414
* @root_y: (out): return location for Y coordinate
8416
* Obtains the position of a window position in root
8417
* window coordinates. This is similar to
8418
* gdk_window_get_origin() but allows you go pass
8419
* in any position in the window, not just the origin.
8424
gdk_window_get_root_coords (GdkWindow *window,
8430
GdkWindowObject *private;
8431
GdkWindowImplIface *impl_iface;
8433
g_return_if_fail (GDK_IS_WINDOW (window));
8435
private = (GdkWindowObject *) window;
8437
if (GDK_WINDOW_DESTROYED (window))
8446
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8447
impl_iface->get_root_coords (window,
8454
* gdk_window_coords_to_parent:
8455
* @window: a child window
8456
* @x: X coordinate in child's coordinate system
8457
* @y: Y coordinate in child's coordinate system
8458
* @parent_x: (out) (allow-none): return location for X coordinate
8459
* in parent's coordinate system, or %NULL
8460
* @parent_y: (out) (allow-none): return location for Y coordinate
8461
* in parent's coordinate system, or %NULL
8463
* Transforms window coordinates from a child window to its parent
8464
* window, where the parent window is the normal parent as returned by
8465
* gdk_window_get_parent() for normal windows, and the window's
8466
* embedder as returned by gdk_offscreen_window_get_embedder() for
8467
* offscreen windows.
8469
* For normal windows, calling this function is equivalent to adding
8470
* the return values of gdk_window_get_position() to the child coordinates.
8471
* For offscreen windows however (which can be arbitrarily transformed),
8472
* this function calls the GdkWindow::to-embedder: signal to translate
8475
* You should always use this function when writing generic code that
8476
* walks up a window hierarchy.
8478
* See also: gdk_window_coords_from_parent()
8483
gdk_window_coords_to_parent (GdkWindow *window,
8489
GdkWindowObject *obj;
8491
g_return_if_fail (GDK_IS_WINDOW (window));
8493
obj = (GdkWindowObject *) window;
8495
if (gdk_window_is_offscreen (obj))
8499
to_embedder (obj, x, y, &px, &py);
8510
*parent_x = x + obj->x;
8513
*parent_y = y + obj->y;
8518
* gdk_window_coords_from_parent:
8519
* @window: a child window
8520
* @parent_x: X coordinate in parent's coordinate system
8521
* @parent_y: Y coordinate in parent's coordinate system
8522
* @x: (out) (allow-none): return location for X coordinate in child's coordinate system
8523
* @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
8525
* Transforms window coordinates from a parent window to a child
8526
* window, where the parent window is the normal parent as returned by
8527
* gdk_window_get_parent() for normal windows, and the window's
8528
* embedder as returned by gdk_offscreen_window_get_embedder() for
8529
* offscreen windows.
8531
* For normal windows, calling this function is equivalent to subtracting
8532
* the return values of gdk_window_get_position() from the parent coordinates.
8533
* For offscreen windows however (which can be arbitrarily transformed),
8534
* this function calls the GdkWindow::from-embedder: signal to translate
8537
* You should always use this function when writing generic code that
8538
* walks down a window hierarchy.
8540
* See also: gdk_window_coords_to_parent()
8545
gdk_window_coords_from_parent (GdkWindow *window,
8551
GdkWindowObject *obj;
8553
g_return_if_fail (GDK_IS_WINDOW (window));
8555
obj = (GdkWindowObject *) window;
8557
if (gdk_window_is_offscreen (obj))
8561
from_embedder (obj, parent_x, parent_y, &cx, &cy);
8572
*x = parent_x - obj->x;
8575
*y = parent_y - obj->y;
8580
* gdk_window_get_deskrelative_origin:
8581
* @window: a toplevel #GdkWindow
8582
* @x: return location for X coordinate
8583
* @y: return location for Y coordinate
8585
* This gets the origin of a #GdkWindow relative to
8586
* an Enlightenment-window-manager desktop. As long as you don't
8587
* assume that the user's desktop/workspace covers the entire
8588
* root window (i.e. you don't assume that the desktop begins
8589
* at root window coordinate 0,0) this function is not necessary.
8590
* It's deprecated for that reason.
8592
* Return value: not meaningful
8595
gdk_window_get_deskrelative_origin (GdkWindow *window,
8599
GdkWindowObject *private;
8600
GdkWindowImplIface *impl_iface;
8601
gboolean return_val = FALSE;
8605
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8607
private = (GdkWindowObject *) window;
8609
if (!GDK_WINDOW_DESTROYED (window))
8611
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8612
return_val = impl_iface->get_deskrelative_origin (window, &tx, &ty);
8615
*x = tx + private->abs_x;
8617
*y = ty + private->abs_y;
8624
* gdk_window_shape_combine_mask:
8625
* @window: a #GdkWindow
8627
* @x: X position of shape mask with respect to @window
8628
* @y: Y position of shape mask with respect to @window
8630
* Applies a shape mask to @window. Pixels in @window corresponding to
8631
* set bits in the @mask will be visible; pixels in @window
8632
* corresponding to unset bits in the @mask will be transparent. This
8633
* gives a non-rectangular window.
8635
* If @mask is %NULL, the shape mask will be unset, and the @x/@y
8636
* parameters are not used.
8638
* On the X11 platform, this uses an X server extension which is
8639
* widely available on most common platforms, but not available on
8640
* very old X servers, and occasionally the implementation will be
8641
* buggy. On servers without the shape extension, this function
8644
* This function works on both toplevel and child windows.
8647
gdk_window_shape_combine_mask (GdkWindow *window,
8652
GdkWindowObject *private;
8655
g_return_if_fail (GDK_IS_WINDOW (window));
8657
private = (GdkWindowObject *) window;
8660
region = _gdk_windowing_get_shape_for_mask (mask);
8664
gdk_window_shape_combine_region (window,
8669
gdk_region_destroy (region);
8673
* gdk_window_shape_combine_region:
8674
* @window: a #GdkWindow
8675
* @shape_region: region of window to be non-transparent
8676
* @offset_x: X position of @shape_region in @window coordinates
8677
* @offset_y: Y position of @shape_region in @window coordinates
8679
* Makes pixels in @window outside @shape_region be transparent,
8680
* so that the window may be nonrectangular. See also
8681
* gdk_window_shape_combine_mask() to use a bitmap as the mask.
8683
* If @shape_region is %NULL, the shape will be unset, so the whole
8684
* window will be opaque again. @offset_x and @offset_y are ignored
8685
* if @shape_region is %NULL.
8687
* On the X11 platform, this uses an X server extension which is
8688
* widely available on most common platforms, but not available on
8689
* very old X servers, and occasionally the implementation will be
8690
* buggy. On servers without the shape extension, this function
8693
* This function works on both toplevel and child windows.
8696
gdk_window_shape_combine_region (GdkWindow *window,
8697
const GdkRegion *shape_region,
8701
GdkWindowObject *private;
8702
GdkRegion *old_region, *new_region, *diff;
8704
g_return_if_fail (GDK_IS_WINDOW (window));
8706
private = (GdkWindowObject *) window;
8708
if (GDK_WINDOW_DESTROYED (window))
8711
if (!private->shaped && shape_region == NULL)
8714
private->shaped = (shape_region != NULL);
8717
gdk_region_destroy (private->shape);
8720
if (GDK_WINDOW_IS_MAPPED (window))
8721
old_region = gdk_region_copy (private->clip_region);
8725
private->shape = gdk_region_copy (shape_region);
8726
gdk_region_offset (private->shape, offset_x, offset_y);
8729
private->shape = NULL;
8731
recompute_visible_regions (private, TRUE, FALSE);
8733
if (gdk_window_has_impl (private) &&
8734
!should_apply_clip_as_shape (private))
8735
apply_shape (private, private->shape);
8739
new_region = gdk_region_copy (private->clip_region);
8741
/* New area in the window, needs invalidation */
8742
diff = gdk_region_copy (new_region);
8743
gdk_region_subtract (diff, old_region);
8745
gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
8747
gdk_region_destroy (diff);
8749
if (!gdk_window_is_toplevel (private))
8751
/* New area in the non-root parent window, needs invalidation */
8752
diff = gdk_region_copy (old_region);
8753
gdk_region_subtract (diff, new_region);
8755
/* Adjust region to parent window coords */
8756
gdk_region_offset (diff, private->x, private->y);
8758
gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
8760
gdk_region_destroy (diff);
8763
gdk_region_destroy (new_region);
8764
gdk_region_destroy (old_region);
8769
do_child_shapes (GdkWindow *window,
8772
GdkWindowObject *private;
8776
private = (GdkWindowObject *) window;
8780
r.width = private->width;
8781
r.height = private->height;
8783
region = gdk_region_rectangle (&r);
8784
remove_child_area (private, NULL, FALSE, region);
8786
if (merge && private->shape)
8787
gdk_region_subtract (region, private->shape);
8789
gdk_window_shape_combine_region (window, region, 0, 0);
8793
* gdk_window_set_child_shapes:
8794
* @window: a #GdkWindow
8796
* Sets the shape mask of @window to the union of shape masks
8797
* for all children of @window, ignoring the shape mask of @window
8798
* itself. Contrast with gdk_window_merge_child_shapes() which includes
8799
* the shape mask of @window in the masks to be merged.
8802
gdk_window_set_child_shapes (GdkWindow *window)
8804
g_return_if_fail (GDK_IS_WINDOW (window));
8806
do_child_shapes (window, FALSE);
8810
* gdk_window_merge_child_shapes:
8811
* @window: a #GdkWindow
8813
* Merges the shape masks for any child windows into the
8814
* shape mask for @window. i.e. the union of all masks
8815
* for @window and its children will become the new mask
8816
* for @window. See gdk_window_shape_combine_mask().
8818
* This function is distinct from gdk_window_set_child_shapes()
8819
* because it includes @window's shape mask in the set of shapes to
8823
gdk_window_merge_child_shapes (GdkWindow *window)
8825
g_return_if_fail (GDK_IS_WINDOW (window));
8827
do_child_shapes (window, TRUE);
8831
* gdk_window_input_shape_combine_mask:
8832
* @window: a #GdkWindow
8833
* @mask: (allow-none): shape mask, or %NULL
8834
* @x: X position of shape mask with respect to @window
8835
* @y: Y position of shape mask with respect to @window
8837
* Like gdk_window_shape_combine_mask(), but the shape applies
8838
* only to event handling. Mouse events which happen while
8839
* the pointer position corresponds to an unset bit in the
8840
* mask will be passed on the window below @window.
8842
* An input shape is typically used with RGBA windows.
8843
* The alpha channel of the window defines which pixels are
8844
* invisible and allows for nicely antialiased borders,
8845
* and the input shape controls where the window is
8848
* On the X11 platform, this requires version 1.1 of the
8851
* On the Win32 platform, this functionality is not present and the
8852
* function does nothing.
8857
gdk_window_input_shape_combine_mask (GdkWindow *window,
8862
GdkWindowObject *private;
8865
g_return_if_fail (GDK_IS_WINDOW (window));
8867
private = (GdkWindowObject *) window;
8870
region = _gdk_windowing_get_shape_for_mask (mask);
8874
gdk_window_input_shape_combine_region (window,
8879
gdk_region_destroy (region);
8883
* gdk_window_input_shape_combine_region:
8884
* @window: a #GdkWindow
8885
* @shape_region: region of window to be non-transparent
8886
* @offset_x: X position of @shape_region in @window coordinates
8887
* @offset_y: Y position of @shape_region in @window coordinates
8889
* Like gdk_window_shape_combine_region(), but the shape applies
8890
* only to event handling. Mouse events which happen while
8891
* the pointer position corresponds to an unset bit in the
8892
* mask will be passed on the window below @window.
8894
* An input shape is typically used with RGBA windows.
8895
* The alpha channel of the window defines which pixels are
8896
* invisible and allows for nicely antialiased borders,
8897
* and the input shape controls where the window is
8900
* On the X11 platform, this requires version 1.1 of the
8903
* On the Win32 platform, this functionality is not present and the
8904
* function does nothing.
8909
gdk_window_input_shape_combine_region (GdkWindow *window,
8910
const GdkRegion *shape_region,
8914
GdkWindowObject *private;
8915
GdkWindowImplIface *impl_iface;
8917
g_return_if_fail (GDK_IS_WINDOW (window));
8919
private = (GdkWindowObject *) window;
8921
if (GDK_WINDOW_DESTROYED (window))
8924
if (private->input_shape)
8925
gdk_region_destroy (private->input_shape);
8929
private->input_shape = gdk_region_copy (shape_region);
8930
gdk_region_offset (private->input_shape, offset_x, offset_y);
8933
private->input_shape = NULL;
8935
if (gdk_window_has_impl (private))
8937
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
8938
impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
8941
/* Pointer may have e.g. moved outside window due to the input mask change */
8942
_gdk_synthesize_crossing_events_for_geometry_change (window);
8946
do_child_input_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, TRUE, region);
8963
if (merge && private->shape)
8964
gdk_region_subtract (region, private->shape);
8965
if (merge && private->input_shape)
8966
gdk_region_subtract (region, private->input_shape);
8968
gdk_window_input_shape_combine_region (window, region, 0, 0);
8973
* gdk_window_set_child_input_shapes:
8974
* @window: a #GdkWindow
8976
* Sets the input shape mask of @window to the union of input shape masks
8977
* for all children of @window, ignoring the input shape mask of @window
8978
* itself. Contrast with gdk_window_merge_child_input_shapes() which includes
8979
* the input shape mask of @window in the masks to be merged.
8984
gdk_window_set_child_input_shapes (GdkWindow *window)
8986
g_return_if_fail (GDK_IS_WINDOW (window));
8988
do_child_input_shapes (window, FALSE);
8992
* gdk_window_merge_child_input_shapes:
8993
* @window: a #GdkWindow
8995
* Merges the input shape masks for any child windows into the
8996
* input shape mask for @window. i.e. the union of all input masks
8997
* for @window and its children will become the new input mask
8998
* for @window. See gdk_window_input_shape_combine_mask().
9000
* This function is distinct from gdk_window_set_child_input_shapes()
9001
* because it includes @window's input shape mask in the set of
9002
* shapes to be merged.
9007
gdk_window_merge_child_input_shapes (GdkWindow *window)
9009
g_return_if_fail (GDK_IS_WINDOW (window));
9011
do_child_input_shapes (window, TRUE);
9016
* gdk_window_set_static_gravities:
9017
* @window: a #GdkWindow
9018
* @use_static: %TRUE to turn on static gravity
9020
* Set the bit gravity of the given window to static, and flag it so
9021
* all children get static subwindow gravity. This is used if you are
9022
* implementing scary features that involve deep knowledge of the
9023
* windowing system. Don't worry about it unless you have to.
9025
* Return value: %TRUE if the server supports static gravity
9028
gdk_window_set_static_gravities (GdkWindow *window,
9029
gboolean use_static)
9031
GdkWindowObject *private;
9032
GdkWindowImplIface *impl_iface;
9034
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9036
private = (GdkWindowObject *) window;
9038
if (gdk_window_has_impl (private))
9040
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
9041
return impl_iface->set_static_gravities (window, use_static);
9048
* gdk_window_get_composited:
9049
* @window: a #GdkWindow
9051
* Determines whether @window is composited.
9053
* See gdk_window_set_composited().
9055
* Returns: %TRUE if the window is composited.
9060
gdk_window_get_composited (GdkWindow *window)
9062
GdkWindowObject *private;
9064
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9066
private = (GdkWindowObject *)window;
9068
return private->composited;
9072
* gdk_window_set_composited:
9073
* @window: a #GdkWindow
9074
* @composited: %TRUE to set the window as composited
9076
* Sets a #GdkWindow as composited, or unsets it. Composited
9077
* windows do not automatically have their contents drawn to
9078
* the screen. Drawing is redirected to an offscreen buffer
9079
* and an expose event is emitted on the parent of the composited
9080
* window. It is the responsibility of the parent's expose handler
9081
* to manually merge the off-screen content onto the screen in
9082
* whatever way it sees fit. See <xref linkend="composited-window-example"/>
9085
* It only makes sense for child windows to be composited; see
9086
* gdk_window_set_opacity() if you need translucent toplevel
9089
* An additional effect of this call is that the area of this
9090
* window is no longer clipped from regions marked for
9091
* invalidation on its parent. Draws done on the parent
9092
* window are also no longer clipped by the child.
9094
* This call is only supported on some systems (currently,
9095
* only X11 with new enough Xcomposite and Xdamage extensions).
9096
* You must call gdk_display_supports_composite() to check if
9097
* setting a window as composited is supported before
9098
* attempting to do so.
9103
gdk_window_set_composited (GdkWindow *window,
9104
gboolean composited)
9106
GdkWindowObject *private = (GdkWindowObject *)window;
9107
GdkDisplay *display;
9109
g_return_if_fail (GDK_IS_WINDOW (window));
9111
composited = composited != FALSE;
9113
if (private->composited == composited)
9117
gdk_window_ensure_native (window);
9119
display = gdk_drawable_get_display (GDK_DRAWABLE (window));
9121
if (!gdk_display_supports_composite (display) && composited)
9123
g_warning ("gdk_window_set_composited called but "
9124
"compositing is not supported");
9128
_gdk_windowing_window_set_composited (window, composited);
9130
recompute_visible_regions (private, TRUE, FALSE);
9132
if (GDK_WINDOW_IS_MAPPED (window))
9133
gdk_window_invalidate_in_parent (private);
9135
private->composited = composited;
9140
remove_redirect_from_children (GdkWindowObject *private,
9141
GdkWindowRedirect *redirect)
9144
GdkWindowObject *child;
9146
for (l = private->children; l != NULL; l = l->next)
9150
/* Don't redirect this child if it already has another redirect */
9151
if (child->redirect == redirect)
9153
child->redirect = NULL;
9154
remove_redirect_from_children (child, redirect);
9160
* gdk_window_remove_redirection:
9161
* @window: a #GdkWindow
9163
* Removes any active redirection started by
9164
* gdk_window_redirect_to_drawable().
9169
gdk_window_remove_redirection (GdkWindow *window)
9171
GdkWindowObject *private;
9173
g_return_if_fail (GDK_IS_WINDOW (window));
9175
private = (GdkWindowObject *) window;
9177
if (private->redirect &&
9178
private->redirect->redirected == private)
9180
remove_redirect_from_children (private, private->redirect);
9181
gdk_window_redirect_free (private->redirect);
9182
private->redirect = NULL;
9187
* gdk_window_get_modal_hint:
9188
* @window: A toplevel #GdkWindow.
9190
* Determines whether or not the window manager is hinted that @window
9191
* has modal behaviour.
9193
* Return value: whether or not the window has the modal hint set.
9198
gdk_window_get_modal_hint (GdkWindow *window)
9200
GdkWindowObject *private;
9202
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9204
private = (GdkWindowObject*) window;
9206
return private->modal_hint;
9210
* gdk_window_get_accept_focus:
9211
* @window: a toplevel #GdkWindow.
9213
* Determines whether or not the desktop environment shuld be hinted that
9214
* the window does not want to receive input focus.
9216
* Return value: whether or not the window should receive input focus.
9221
gdk_window_get_accept_focus (GdkWindow *window)
9223
GdkWindowObject *private;
9225
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9227
private = (GdkWindowObject *)window;
9229
return private->accept_focus;
9233
* gdk_window_get_focus_on_map:
9234
* @window: a toplevel #GdkWindow.
9236
* Determines whether or not the desktop environment should be hinted that the
9237
* window does not want to receive input focus when it is mapped.
9239
* Return value: whether or not the window wants to receive input focus when
9245
gdk_window_get_focus_on_map (GdkWindow *window)
9247
GdkWindowObject *private;
9249
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9251
private = (GdkWindowObject *)window;
9253
return private->focus_on_map;
9257
* gdk_window_is_input_only:
9258
* @window: a toplevel #GdkWindow
9260
* Determines whether or not the window is an input only window.
9262
* Return value: %TRUE if @window is input only
9267
gdk_window_is_input_only (GdkWindow *window)
9269
GdkWindowObject *private;
9271
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9273
private = (GdkWindowObject *)window;
9275
return private->input_only;
9279
* gdk_window_is_shaped:
9280
* @window: a toplevel #GdkWindow
9282
* Determines whether or not the window is shaped.
9284
* Return value: %TRUE if @window is shaped
9289
gdk_window_is_shaped (GdkWindow *window)
9291
GdkWindowObject *private;
9293
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
9295
private = (GdkWindowObject *)window;
9297
return private->shaped;
9301
apply_redirect_to_children (GdkWindowObject *private,
9302
GdkWindowRedirect *redirect)
9305
GdkWindowObject *child;
9307
for (l = private->children; l != NULL; l = l->next)
9311
/* Don't redirect this child if it already has another redirect */
9312
if (!child->redirect)
9314
child->redirect = redirect;
9315
apply_redirect_to_children (child, redirect);
9321
* gdk_window_redirect_to_drawable:
9322
* @window: a #GdkWindow
9323
* @drawable: a #GdkDrawable
9324
* @src_x: x position in @window
9325
* @src_y: y position in @window
9326
* @dest_x: x position in @drawable
9327
* @dest_y: y position in @drawable
9328
* @width: width of redirection, or -1 to use the width of @window
9329
* @height: height of redirection or -1 to use the height of @window
9331
* Redirects drawing into @window so that drawing to the
9332
* window in the rectangle specified by @src_x, @src_y,
9333
* @width and @height is also drawn into @drawable at
9336
* Only drawing between gdk_window_begin_paint_region() or
9337
* gdk_window_begin_paint_rect() and gdk_window_end_paint() is
9340
* Redirection is active until gdk_window_remove_redirection()
9346
gdk_window_redirect_to_drawable (GdkWindow *window,
9347
GdkDrawable *drawable,
9355
GdkWindowObject *private;
9357
g_return_if_fail (GDK_IS_WINDOW (window));
9358
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
9359
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
9361
private = (GdkWindowObject *) window;
9363
if (private->redirect)
9364
gdk_window_remove_redirection (window);
9366
if (width == -1 || height == -1)
9369
gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
9376
private->redirect = g_new0 (GdkWindowRedirect, 1);
9377
private->redirect->redirected = private;
9378
private->redirect->pixmap = g_object_ref (drawable);
9379
private->redirect->src_x = src_x;
9380
private->redirect->src_y = src_y;
9381
private->redirect->dest_x = dest_x;
9382
private->redirect->dest_y = dest_y;
9383
private->redirect->width = width;
9384
private->redirect->height = height;
9386
apply_redirect_to_children (private, private->redirect);
9390
window_get_size_rectangle (GdkWindow *window,
9393
GdkWindowObject *private = (GdkWindowObject *) window;
9395
rect->x = rect->y = 0;
9396
rect->width = private->width;
9397
rect->height = private->height;
9400
/* Calculates the real clipping region for a window, in window coordinates,
9401
* taking into account other windows, gc clip region and gc clip mask.
9404
_gdk_window_calculate_full_clip_region (GdkWindow *window,
9405
GdkWindow *base_window,
9406
gboolean do_children,
9407
gint *base_x_offset,
9408
gint *base_y_offset)
9410
GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
9411
GdkRectangle visible_rect;
9412
GdkRegion *real_clip_region, *tmpreg;
9413
gint x_offset, y_offset;
9414
GdkWindowObject *parentwin, *lastwin;
9421
if (!private->viewable || private->input_only)
9422
return gdk_region_new ();
9424
window_get_size_rectangle (window, &visible_rect);
9426
/* real_clip_region is in window coordinates */
9427
real_clip_region = gdk_region_rectangle (&visible_rect);
9429
x_offset = y_offset = 0;
9433
parentwin = lastwin;
9435
parentwin = lastwin->parent;
9437
/* Remove the areas of all overlapping windows above parentwin in the hiearachy */
9438
for (; parentwin != NULL &&
9439
(parentwin == private || lastwin != (GdkWindowObject*) base_window);
9440
lastwin = parentwin, parentwin = lastwin->parent)
9443
GdkRectangle real_clip_rect;
9445
if (parentwin != private)
9447
x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
9448
y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
9451
/* children is ordered in reverse stack order */
9452
for (cur = parentwin->children;
9453
cur && cur->data != lastwin;
9456
GdkWindow *child = cur->data;
9457
GdkWindowObject *child_private = (GdkWindowObject *)child;
9459
if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
9462
/* Ignore offscreen children, as they don't draw in their parent and
9463
* don't take part in the clipping */
9464
if (gdk_window_is_offscreen (child_private))
9467
window_get_size_rectangle (child, &visible_rect);
9469
/* Convert rect to "window" coords */
9470
visible_rect.x += child_private->x - x_offset;
9471
visible_rect.y += child_private->y - y_offset;
9473
/* This shortcut is really necessary for performance when there are a lot of windows */
9474
gdk_region_get_clipbox (real_clip_region, &real_clip_rect);
9475
if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
9476
visible_rect.x + visible_rect.width <= real_clip_rect.x ||
9477
visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
9478
visible_rect.y + visible_rect.height <= real_clip_rect.y)
9481
tmpreg = gdk_region_rectangle (&visible_rect);
9482
gdk_region_subtract (real_clip_region, tmpreg);
9483
gdk_region_destroy (tmpreg);
9486
/* Clip to the parent */
9487
window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
9488
/* Convert rect to "window" coords */
9489
visible_rect.x += - x_offset;
9490
visible_rect.y += - y_offset;
9492
tmpreg = gdk_region_rectangle (&visible_rect);
9493
gdk_region_intersect (real_clip_region, tmpreg);
9494
gdk_region_destroy (tmpreg);
9498
*base_x_offset = x_offset;
9500
*base_y_offset = y_offset;
9502
return real_clip_region;
9506
_gdk_window_add_damage (GdkWindow *toplevel,
9507
GdkRegion *damaged_region)
9509
GdkDisplay *display;
9510
GdkEvent event = { 0, };
9511
event.expose.type = GDK_DAMAGE;
9512
event.expose.window = toplevel;
9513
event.expose.send_event = FALSE;
9514
event.expose.region = damaged_region;
9515
gdk_region_get_clipbox (event.expose.region, &event.expose.area);
9516
display = gdk_drawable_get_display (event.expose.window);
9517
_gdk_event_queue_append (display, gdk_event_copy (&event));
9521
gdk_window_redirect_free (GdkWindowRedirect *redirect)
9523
g_object_unref (redirect->pixmap);
9527
/* Gets the toplevel for a window as used for events,
9528
i.e. including offscreen parents */
9529
static GdkWindowObject *
9530
get_event_parent (GdkWindowObject *window)
9532
if (gdk_window_is_offscreen (window))
9533
return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
9535
return window->parent;
9538
/* Gets the toplevel for a window as used for events,
9539
i.e. including offscreen parents going up to the native
9542
get_event_toplevel (GdkWindow *w)
9544
GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
9545
GdkWindowObject *parent;
9547
while ((parent = get_event_parent (private)) != NULL &&
9548
(parent->window_type != GDK_WINDOW_ROOT))
9551
return GDK_WINDOW (private);
9555
_gdk_window_event_parent_of (GdkWindow *parent,
9566
w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
9573
update_cursor (GdkDisplay *display)
9575
GdkWindowObject *cursor_window, *parent, *toplevel;
9576
GdkWindow *pointer_window;
9577
GdkWindowImplIface *impl_iface;
9578
GdkPointerGrabInfo *grab;
9580
pointer_window = display->pointer_info.window_under_pointer;
9582
/* We ignore the serials here and just pick the last grab
9583
we've sent, as that would shortly be used anyway. */
9584
grab = _gdk_display_get_last_pointer_grab (display);
9587
/* the pointer is not in a descendant of the grab window */
9588
!_gdk_window_event_parent_of (grab->window, pointer_window))
9589
/* use the cursor from the grab window */
9590
cursor_window = (GdkWindowObject *)grab->window;
9592
/* otherwise use the cursor from the pointer window */
9593
cursor_window = (GdkWindowObject *)pointer_window;
9595
/* Find the first window with the cursor actually set, as
9596
the cursor is inherited from the parent */
9597
while (cursor_window->cursor == NULL &&
9598
(parent = get_event_parent (cursor_window)) != NULL &&
9599
parent->window_type != GDK_WINDOW_ROOT)
9600
cursor_window = parent;
9602
/* Set all cursors on toplevel, otherwise its tricky to keep track of
9603
* which native window has what cursor set. */
9604
toplevel = (GdkWindowObject *)get_event_toplevel (pointer_window);
9605
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
9606
impl_iface->set_cursor ((GdkWindow *)toplevel, cursor_window->cursor);
9610
point_in_window (GdkWindowObject *window,
9615
x >= 0 && x < window->width &&
9616
y >= 0 && y < window->height &&
9617
(window->shape == NULL ||
9618
gdk_region_point_in (window->shape,
9620
(window->input_shape == NULL ||
9621
gdk_region_point_in (window->input_shape,
9626
convert_native_coords_to_toplevel (GdkWindow *window,
9629
gdouble *toplevel_x,
9630
gdouble *toplevel_y)
9632
GdkWindowObject *private = (GdkWindowObject *)window;
9638
while (!gdk_window_is_toplevel (private))
9642
private = private->parent;
9648
return (GdkWindow *)private;
9652
convert_toplevel_coords_to_window (GdkWindow *window,
9658
GdkWindowObject *private;
9659
GdkWindowObject *parent;
9661
GList *children, *l;
9663
private = GDK_WINDOW_OBJECT (window);
9669
while ((parent = get_event_parent (private)) != NULL &&
9670
(parent->window_type != GDK_WINDOW_ROOT))
9672
children = g_list_prepend (children, private);
9676
for (l = children; l != NULL; l = l->next)
9677
gdk_window_coords_from_parent (l->data, x, y, &x, &y);
9679
g_list_free (children);
9685
static GdkWindowObject *
9686
pick_embedded_child (GdkWindowObject *window,
9690
GdkWindowObject *res;
9693
g_signal_emit (window,
9694
signals[PICK_EMBEDDED_CHILD], 0,
9701
_gdk_window_find_child_at (GdkWindow *window,
9705
GdkWindowObject *private, *sub;
9706
double child_x, child_y;
9709
private = (GdkWindowObject *)window;
9711
if (point_in_window (private, x, y))
9713
/* Children is ordered in reverse stack order, i.e. first is topmost */
9714
for (l = private->children; l != NULL; l = l->next)
9718
if (!GDK_WINDOW_IS_MAPPED (sub))
9721
gdk_window_coords_from_parent ((GdkWindow *)sub,
9723
&child_x, &child_y);
9724
if (point_in_window (sub, child_x, child_y))
9725
return (GdkWindow *)sub;
9728
if (private->num_offscreen_children > 0)
9730
sub = pick_embedded_child (private,
9733
return (GdkWindow *)sub;
9741
_gdk_window_find_descendant_at (GdkWindow *toplevel,
9747
GdkWindowObject *private, *sub;
9748
gdouble child_x, child_y;
9752
private = (GdkWindowObject *)toplevel;
9754
if (point_in_window (private, x, y))
9759
/* Children is ordered in reverse stack order, i.e. first is topmost */
9760
for (l = private->children; l != NULL; l = l->next)
9764
if (!GDK_WINDOW_IS_MAPPED (sub))
9767
gdk_window_coords_from_parent ((GdkWindow *)sub,
9769
&child_x, &child_y);
9770
if (point_in_window (sub, child_x, child_y))
9780
private->num_offscreen_children > 0)
9782
sub = pick_embedded_child (private,
9788
from_embedder (sub, x, y, &x, &y);
9796
/* Not in window at all */
9805
return (GdkWindow *)private;
9810
* @window: a toplevel #GdkWindow
9812
* Emits a short beep associated to @window in the appropriate
9813
* display, if supported. Otherwise, emits a short beep on
9814
* the display just as gdk_display_beep().
9819
gdk_window_beep (GdkWindow *window)
9821
GdkDisplay *display;
9822
GdkWindow *toplevel;
9824
g_return_if_fail (GDK_IS_WINDOW (window));
9826
if (GDK_WINDOW_DESTROYED (window))
9829
toplevel = get_event_toplevel (window);
9830
display = gdk_drawable_get_display (GDK_DRAWABLE (window));
9832
if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
9833
_gdk_windowing_window_beep (toplevel);
9835
gdk_display_beep (display);
9838
static const guint type_masks[] = {
9839
GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
9840
GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
9841
GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
9842
GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
9843
GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
9844
GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
9845
GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
9846
GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
9847
GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
9848
GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
9849
GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
9850
GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
9851
GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
9852
GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
9853
GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
9854
GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
9855
GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
9856
GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
9857
GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
9858
GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
9859
GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
9860
GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
9861
GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
9862
GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
9863
GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
9864
GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
9865
GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
9866
GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
9867
GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
9868
GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
9869
GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
9870
GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
9871
0, /* GDK_WINDOW_STATE = 32 */
9872
0, /* GDK_SETTING = 33 */
9873
0, /* GDK_OWNER_CHANGE = 34 */
9874
0, /* GDK_GRAB_BROKEN = 35 */
9875
0, /* GDK_DAMAGE = 36 */
9877
G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
9879
/* send motion events if the right buttons are down */
9881
update_evmask_for_button_motion (guint evmask,
9882
GdkModifierType mask)
9884
if (evmask & GDK_BUTTON_MOTION_MASK &&
9885
mask & (GDK_BUTTON1_MASK |
9890
evmask |= GDK_POINTER_MOTION_MASK;
9892
if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
9893
(evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
9894
(evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
9895
evmask |= GDK_POINTER_MOTION_MASK;
9901
is_button_type (GdkEventType type)
9903
return type == GDK_BUTTON_PRESS ||
9904
type == GDK_2BUTTON_PRESS ||
9905
type == GDK_3BUTTON_PRESS ||
9906
type == GDK_BUTTON_RELEASE ||
9911
is_motion_type (GdkEventType type)
9913
return type == GDK_MOTION_NOTIFY ||
9914
type == GDK_ENTER_NOTIFY ||
9915
type == GDK_LEAVE_NOTIFY;
9918
static GdkWindowObject *
9919
find_common_ancestor (GdkWindowObject *win1,
9920
GdkWindowObject *win2)
9922
GdkWindowObject *tmp;
9923
GList *path1 = NULL, *path2 = NULL;
9924
GList *list1, *list2;
9927
while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
9929
path1 = g_list_prepend (path1, tmp);
9930
tmp = get_event_parent (tmp);
9934
while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
9936
path2 = g_list_prepend (path2, tmp);
9937
tmp = get_event_parent (tmp);
9943
while (list1 && list2 && (list1->data == list2->data))
9945
tmp = (GdkWindowObject *)list1->data;
9946
list1 = g_list_next (list1);
9947
list2 = g_list_next (list2);
9949
g_list_free (path1);
9950
g_list_free (path2);
9956
_gdk_make_event (GdkWindow *window,
9958
GdkEvent *event_in_queue,
9959
gboolean before_event)
9961
GdkEvent *event = gdk_event_new (type);
9963
GdkModifierType the_state;
9965
the_time = gdk_event_get_time (event_in_queue);
9966
gdk_event_get_state (event_in_queue, &the_state);
9968
event->any.window = g_object_ref (window);
9969
event->any.send_event = FALSE;
9970
if (event_in_queue && event_in_queue->any.send_event)
9971
event->any.send_event = TRUE;
9975
case GDK_MOTION_NOTIFY:
9976
event->motion.time = the_time;
9977
event->motion.axes = NULL;
9978
event->motion.state = the_state;
9981
case GDK_BUTTON_PRESS:
9982
case GDK_2BUTTON_PRESS:
9983
case GDK_3BUTTON_PRESS:
9984
case GDK_BUTTON_RELEASE:
9985
event->button.time = the_time;
9986
event->button.axes = NULL;
9987
event->button.state = the_state;
9991
event->scroll.time = the_time;
9992
event->scroll.state = the_state;
9996
case GDK_KEY_RELEASE:
9997
event->key.time = the_time;
9998
event->key.state = the_state;
10001
case GDK_ENTER_NOTIFY:
10002
case GDK_LEAVE_NOTIFY:
10003
event->crossing.time = the_time;
10004
event->crossing.state = the_state;
10007
case GDK_PROPERTY_NOTIFY:
10008
event->property.time = the_time;
10009
event->property.state = the_state;
10012
case GDK_SELECTION_CLEAR:
10013
case GDK_SELECTION_REQUEST:
10014
case GDK_SELECTION_NOTIFY:
10015
event->selection.time = the_time;
10018
case GDK_PROXIMITY_IN:
10019
case GDK_PROXIMITY_OUT:
10020
event->proximity.time = the_time;
10023
case GDK_DRAG_ENTER:
10024
case GDK_DRAG_LEAVE:
10025
case GDK_DRAG_MOTION:
10026
case GDK_DRAG_STATUS:
10027
case GDK_DROP_START:
10028
case GDK_DROP_FINISHED:
10029
event->dnd.time = the_time;
10032
case GDK_FOCUS_CHANGE:
10033
case GDK_CONFIGURE:
10036
case GDK_CLIENT_EVENT:
10037
case GDK_VISIBILITY_NOTIFY:
10038
case GDK_NO_EXPOSE:
10046
if (event_in_queue)
10049
_gdk_event_queue_insert_before (gdk_drawable_get_display (window), event_in_queue, event);
10051
_gdk_event_queue_insert_after (gdk_drawable_get_display (window), event_in_queue, event);
10054
_gdk_event_queue_append (gdk_drawable_get_display (window), event);
10060
send_crossing_event (GdkDisplay *display,
10061
GdkWindowObject *toplevel,
10062
GdkWindowObject *window,
10064
GdkCrossingMode mode,
10065
GdkNotifyType notify_type,
10066
GdkWindow *subwindow,
10069
GdkModifierType mask,
10071
GdkEvent *event_in_queue,
10075
guint32 window_event_mask, type_event_mask;
10076
GdkPointerGrabInfo *grab;
10077
GdkWindowImplIface *impl_iface;
10079
grab = _gdk_display_has_pointer_grab (display, serial);
10081
if (grab != NULL &&
10082
!grab->owner_events)
10084
/* !owner_event => only report events wrt grab window, ignore rest */
10085
if ((GdkWindow *)window != grab->window)
10087
window_event_mask = grab->event_mask;
10090
window_event_mask = window->event_mask;
10092
if (type == GDK_LEAVE_NOTIFY)
10093
type_event_mask = GDK_LEAVE_NOTIFY_MASK;
10095
type_event_mask = GDK_ENTER_NOTIFY_MASK;
10097
if (window->extension_events != 0)
10099
impl_iface = GDK_WINDOW_IMPL_GET_IFACE (window->impl);
10100
impl_iface->input_window_crossing ((GdkWindow *)window,
10101
type == GDK_ENTER_NOTIFY);
10104
if (window_event_mask & type_event_mask)
10106
event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
10107
event->crossing.time = time_;
10108
event->crossing.subwindow = subwindow;
10110
g_object_ref (subwindow);
10111
convert_toplevel_coords_to_window ((GdkWindow *)window,
10112
toplevel_x, toplevel_y,
10113
&event->crossing.x, &event->crossing.y);
10114
event->crossing.x_root = toplevel_x + toplevel->x;
10115
event->crossing.y_root = toplevel_y + toplevel->y;
10116
event->crossing.mode = mode;
10117
event->crossing.detail = notify_type;
10118
event->crossing.focus = FALSE;
10119
event->crossing.state = mask;
10124
/* The coordinates are in the toplevel window that src/dest are in.
10125
* src and dest are always (if != NULL) in the same toplevel, as
10126
* we get a leave-notify and set the window_under_pointer to null
10127
* before crossing to another toplevel.
10130
_gdk_synthesize_crossing_events (GdkDisplay *display,
10133
GdkCrossingMode mode,
10136
GdkModifierType mask,
10138
GdkEvent *event_in_queue,
10140
gboolean non_linear)
10142
GdkWindowObject *c;
10143
GdkWindowObject *win, *last, *next;
10144
GList *path, *list;
10145
GdkWindowObject *a;
10146
GdkWindowObject *b;
10147
GdkWindowObject *toplevel;
10148
GdkNotifyType notify_type;
10150
/* TODO: Don't send events to toplevel, as we get those from the windowing system */
10152
a = (GdkWindowObject *)src;
10153
b = (GdkWindowObject *)dest;
10155
return; /* No crossings generated between src and dest */
10157
c = find_common_ancestor (a, b);
10159
non_linear |= (c != a) && (c != b);
10161
if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
10163
toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
10165
/* Traverse up from a to (excluding) c sending leave events */
10167
notify_type = GDK_NOTIFY_NONLINEAR;
10169
notify_type = GDK_NOTIFY_INFERIOR;
10171
notify_type = GDK_NOTIFY_ANCESTOR;
10172
send_crossing_event (display, toplevel,
10173
a, GDK_LEAVE_NOTIFY,
10177
toplevel_x, toplevel_y,
10185
notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
10187
notify_type = GDK_NOTIFY_VIRTUAL;
10190
win = get_event_parent (a);
10191
while (win != c && win->window_type != GDK_WINDOW_ROOT)
10193
send_crossing_event (display, toplevel,
10194
win, GDK_LEAVE_NOTIFY,
10198
toplevel_x, toplevel_y,
10204
win = get_event_parent (win);
10209
if (b) /* Might not be a dest, e.g. if we're moving out of the window */
10211
toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
10213
/* Traverse down from c to b */
10217
win = get_event_parent (b);
10218
while (win != c && win->window_type != GDK_WINDOW_ROOT)
10220
path = g_list_prepend (path, win);
10221
win = get_event_parent (win);
10225
notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
10227
notify_type = GDK_NOTIFY_VIRTUAL;
10232
win = (GdkWindowObject *)list->data;
10233
list = g_list_next (list);
10235
next = (GdkWindowObject *)list->data;
10239
send_crossing_event (display, toplevel,
10240
win, GDK_ENTER_NOTIFY,
10244
toplevel_x, toplevel_y,
10249
g_list_free (path);
10254
notify_type = GDK_NOTIFY_NONLINEAR;
10256
notify_type = GDK_NOTIFY_ANCESTOR;
10258
notify_type = GDK_NOTIFY_INFERIOR;
10260
send_crossing_event (display, toplevel,
10261
b, GDK_ENTER_NOTIFY,
10265
toplevel_x, toplevel_y,
10272
/* Returns the window inside the event window with the pointer in it
10273
* at the specified coordinates, or NULL if its not in any child of
10274
* the toplevel. It also takes into account !owner_events grabs.
10277
get_pointer_window (GdkDisplay *display,
10278
GdkWindow *event_window,
10279
gdouble toplevel_x,
10280
gdouble toplevel_y,
10283
GdkWindow *pointer_window;
10284
GdkPointerGrabInfo *grab;
10286
if (event_window == display->pointer_info.toplevel_under_pointer)
10288
_gdk_window_find_descendant_at (event_window,
10289
toplevel_x, toplevel_y,
10292
pointer_window = NULL;
10294
grab = _gdk_display_has_pointer_grab (display, serial);
10295
if (grab != NULL &&
10296
!grab->owner_events &&
10297
pointer_window != grab->window)
10298
pointer_window = NULL;
10300
return pointer_window;
10304
_gdk_display_set_window_under_pointer (GdkDisplay *display,
10307
/* We don't track this if all native, and it can cause issues
10308
with the update_cursor call below */
10309
if (_gdk_native_windows)
10312
if (display->pointer_info.window_under_pointer)
10313
g_object_unref (display->pointer_info.window_under_pointer);
10314
display->pointer_info.window_under_pointer = window;
10316
g_object_ref (window);
10319
update_cursor (display);
10321
_gdk_display_enable_motion_hints (display);
10325
*--------------------------------------------------------------
10328
* Grabs the pointer to a specific window
10331
* "window" is the window which will receive the grab
10332
* "owner_events" specifies whether events will be reported as is,
10333
* or relative to "window"
10334
* "event_mask" masks only interesting events
10335
* "confine_to" limits the cursor movement to the specified window
10336
* "cursor" changes the cursor for the duration of the grab
10337
* "time" specifies the time
10342
* requires a corresponding call to gdk_pointer_ungrab
10344
*--------------------------------------------------------------
10347
gdk_pointer_grab (GdkWindow * window,
10348
gboolean owner_events,
10349
GdkEventMask event_mask,
10350
GdkWindow * confine_to,
10351
GdkCursor * cursor,
10355
GdkDisplay *display;
10359
g_return_val_if_fail (window != NULL, 0);
10360
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
10361
g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
10363
/* We need a native window for confine to to work, ensure we have one */
10366
if (!gdk_window_ensure_native (confine_to))
10368
g_warning ("Can't confine to grabbed window, not native");
10373
/* Non-viewable client side window => fail */
10374
if (!_gdk_window_has_impl (window) &&
10375
!gdk_window_is_viewable (window))
10376
return GDK_GRAB_NOT_VIEWABLE;
10378
if (_gdk_native_windows)
10381
native = gdk_window_get_toplevel (window);
10382
while (gdk_window_is_offscreen ((GdkWindowObject *)native))
10384
native = gdk_offscreen_window_get_embedder (native);
10386
if (native == NULL ||
10387
(!_gdk_window_has_impl (native) &&
10388
!gdk_window_is_viewable (native)))
10389
return GDK_GRAB_NOT_VIEWABLE;
10391
native = gdk_window_get_toplevel (native);
10394
display = gdk_drawable_get_display (window);
10396
serial = _gdk_windowing_window_get_next_serial (display);
10398
res = _gdk_windowing_pointer_grab (window,
10401
get_native_grab_event_mask (event_mask),
10406
if (res == GDK_GRAB_SUCCESS)
10407
_gdk_display_add_pointer_grab (display,
10420
* gdk_window_geometry_changed:
10421
* @window: an embedded offscreen #GdkWindow
10423
* This function informs GDK that the geometry of an embedded
10424
* offscreen window has changed. This is necessary for GDK to keep
10425
* track of which offscreen window the pointer is in.
10430
gdk_window_geometry_changed (GdkWindow *window)
10432
_gdk_synthesize_crossing_events_for_geometry_change (window);
10436
do_synthesize_crossing_event (gpointer data)
10438
GdkDisplay *display;
10439
GdkWindow *changed_toplevel;
10440
GdkWindowObject *changed_toplevel_priv;
10441
GdkWindow *new_window_under_pointer;
10444
changed_toplevel = data;
10445
changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
10447
changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
10449
if (GDK_WINDOW_DESTROYED (changed_toplevel))
10452
display = gdk_drawable_get_display (changed_toplevel);
10453
serial = _gdk_windowing_window_get_next_serial (display);
10455
if (changed_toplevel == display->pointer_info.toplevel_under_pointer)
10457
new_window_under_pointer =
10458
get_pointer_window (display, changed_toplevel,
10459
display->pointer_info.toplevel_x,
10460
display->pointer_info.toplevel_y,
10462
if (new_window_under_pointer !=
10463
display->pointer_info.window_under_pointer)
10465
_gdk_synthesize_crossing_events (display,
10466
display->pointer_info.window_under_pointer,
10467
new_window_under_pointer,
10468
GDK_CROSSING_NORMAL,
10469
display->pointer_info.toplevel_x,
10470
display->pointer_info.toplevel_y,
10471
display->pointer_info.state,
10476
_gdk_display_set_window_under_pointer (display, new_window_under_pointer);
10484
_gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
10486
GdkDisplay *display;
10487
GdkWindow *toplevel;
10488
GdkWindowObject *toplevel_priv;
10490
if (_gdk_native_windows)
10491
return; /* We use the native crossing events if all native */
10493
display = gdk_drawable_get_display (changed_window);
10495
toplevel = get_event_toplevel (changed_window);
10496
toplevel_priv = (GdkWindowObject *)toplevel;
10498
if (toplevel == display->pointer_info.toplevel_under_pointer &&
10499
!toplevel_priv->synthesize_crossing_event_queued)
10501
toplevel_priv->synthesize_crossing_event_queued = TRUE;
10502
gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
10503
do_synthesize_crossing_event,
10504
g_object_ref (toplevel),
10509
/* Don't use for crossing events */
10511
get_event_window (GdkDisplay *display,
10512
GdkWindow *pointer_window,
10514
GdkModifierType mask,
10519
GdkWindow *grab_window;
10520
GdkWindowObject *w;
10521
GdkPointerGrabInfo *grab;
10523
grab = _gdk_display_has_pointer_grab (display, serial);
10525
if (grab != NULL && !grab->owner_events)
10527
evmask = grab->event_mask;
10528
evmask = update_evmask_for_button_motion (evmask, mask);
10530
grab_window = grab->window;
10532
if (evmask & type_masks[type])
10535
*evmask_out = evmask;
10536
return grab_window;
10542
w = (GdkWindowObject *)pointer_window;
10545
evmask = w->event_mask;
10546
evmask = update_evmask_for_button_motion (evmask, mask);
10548
if (evmask & type_masks[type])
10551
*evmask_out = evmask;
10552
return (GdkWindow *)w;
10555
w = get_event_parent (w);
10558
if (grab != NULL &&
10559
grab->owner_events)
10561
evmask = grab->event_mask;
10562
evmask = update_evmask_for_button_motion (evmask, mask);
10564
if (evmask & type_masks[type])
10567
*evmask_out = evmask;
10568
return grab->window;
10578
proxy_pointer_event (GdkDisplay *display,
10579
GdkEvent *source_event,
10582
GdkWindow *toplevel_window, *event_window;
10583
GdkWindow *pointer_window;
10586
gdouble toplevel_x, toplevel_y;
10588
gboolean non_linear;
10590
event_window = source_event->any.window;
10591
gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
10592
gdk_event_get_state (source_event, &state);
10593
time_ = gdk_event_get_time (source_event);
10594
toplevel_window = convert_native_coords_to_toplevel (event_window,
10595
toplevel_x, toplevel_y,
10596
&toplevel_x, &toplevel_y);
10598
non_linear = FALSE;
10599
if ((source_event->type == GDK_LEAVE_NOTIFY ||
10600
source_event->type == GDK_ENTER_NOTIFY) &&
10601
(source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
10602
source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
10605
/* If we get crossing events with subwindow unexpectedly being NULL
10606
that means there is a native subwindow that gdk doesn't know about.
10607
We track these and forward them, with the correct virtual window
10609
This is important to get right, as metacity uses gdk for the frame
10610
windows, but gdk doesn't know about the client windows reparented
10612
if (((source_event->type == GDK_LEAVE_NOTIFY &&
10613
source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
10614
(source_event->type == GDK_ENTER_NOTIFY &&
10615
(source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
10616
source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
10617
source_event->crossing.subwindow == NULL)
10619
/* Left for an unknown (to gdk) subwindow */
10621
/* Send leave events from window under pointer to event window
10622
that will get the subwindow == NULL window */
10623
_gdk_synthesize_crossing_events (display,
10624
display->pointer_info.window_under_pointer,
10626
source_event->crossing.mode,
10627
toplevel_x, toplevel_y,
10633
/* Send subwindow == NULL event */
10634
send_crossing_event (display,
10635
(GdkWindowObject *)toplevel_window,
10636
(GdkWindowObject *)event_window,
10637
source_event->type,
10638
source_event->crossing.mode,
10639
source_event->crossing.detail,
10641
toplevel_x, toplevel_y,
10646
_gdk_display_set_window_under_pointer (display, NULL);
10650
pointer_window = get_pointer_window (display, toplevel_window,
10651
toplevel_x, toplevel_y, serial);
10653
if (((source_event->type == GDK_ENTER_NOTIFY &&
10654
source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
10655
(source_event->type == GDK_LEAVE_NOTIFY &&
10656
(source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
10657
source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
10658
source_event->crossing.subwindow == NULL)
10660
/* Entered from an unknown (to gdk) subwindow */
10662
/* Send subwindow == NULL event */
10663
send_crossing_event (display,
10664
(GdkWindowObject *)toplevel_window,
10665
(GdkWindowObject *)event_window,
10666
source_event->type,
10667
source_event->crossing.mode,
10668
source_event->crossing.detail,
10670
toplevel_x, toplevel_y,
10675
/* Send enter events from event window to pointer_window */
10676
_gdk_synthesize_crossing_events (display,
10679
source_event->crossing.mode,
10680
toplevel_x, toplevel_y,
10683
serial, non_linear);
10684
_gdk_display_set_window_under_pointer (display, pointer_window);
10688
if (display->pointer_info.window_under_pointer != pointer_window)
10690
/* Either a toplevel crossing notify that ended up inside a child window,
10691
or a motion notify that got into another child window */
10693
/* Different than last time, send crossing events */
10694
_gdk_synthesize_crossing_events (display,
10695
display->pointer_info.window_under_pointer,
10697
GDK_CROSSING_NORMAL,
10698
toplevel_x, toplevel_y,
10701
serial, non_linear);
10702
_gdk_display_set_window_under_pointer (display, pointer_window);
10704
else if (source_event->type == GDK_MOTION_NOTIFY)
10706
GdkWindow *event_win;
10710
event_win = get_event_window (display,
10712
source_event->type,
10720
(evmask & GDK_POINTER_MOTION_HINT_MASK))
10722
if (display->pointer_info.motion_hint_serial != 0 &&
10723
serial < display->pointer_info.motion_hint_serial)
10724
event_win = NULL; /* Ignore event */
10728
display->pointer_info.motion_hint_serial = G_MAXULONG;
10732
if (event_win && !display->ignore_core_events)
10734
event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
10735
event->motion.time = time_;
10736
convert_toplevel_coords_to_window (event_win,
10737
toplevel_x, toplevel_y,
10738
&event->motion.x, &event->motion.y);
10739
event->motion.x_root = source_event->motion.x_root;
10740
event->motion.y_root = source_event->motion.y_root;;
10741
event->motion.state = state;
10742
event->motion.is_hint = is_hint;
10743
event->motion.device = NULL;
10744
event->motion.device = source_event->motion.device;
10748
/* unlink all move events from queue.
10749
We handle our own, including our emulated masks. */
10753
#define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
10754
GDK_BUTTON2_MASK | \
10755
GDK_BUTTON3_MASK | \
10756
GDK_BUTTON4_MASK | \
10760
proxy_button_event (GdkEvent *source_event,
10763
GdkWindow *toplevel_window, *event_window;
10764
GdkWindow *event_win;
10765
GdkWindow *pointer_window;
10766
GdkWindowObject *parent;
10771
gdouble toplevel_x, toplevel_y;
10772
GdkDisplay *display;
10773
GdkWindowObject *w;
10775
type = source_event->any.type;
10776
event_window = source_event->any.window;
10777
gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
10778
gdk_event_get_state (source_event, &state);
10779
time_ = gdk_event_get_time (source_event);
10780
display = gdk_drawable_get_display (source_event->any.window);
10781
toplevel_window = convert_native_coords_to_toplevel (event_window,
10782
toplevel_x, toplevel_y,
10783
&toplevel_x, &toplevel_y);
10785
if (type == GDK_BUTTON_PRESS &&
10786
!source_event->any.send_event &&
10787
_gdk_display_has_pointer_grab (display, serial) == NULL)
10790
_gdk_window_find_descendant_at (toplevel_window,
10791
toplevel_x, toplevel_y,
10794
/* Find the event window, that gets the grab */
10795
w = (GdkWindowObject *)pointer_window;
10796
while (w != NULL &&
10797
(parent = get_event_parent (w)) != NULL &&
10798
parent->window_type != GDK_WINDOW_ROOT)
10800
if (w->event_mask & GDK_BUTTON_PRESS_MASK)
10804
pointer_window = (GdkWindow *)w;
10806
_gdk_display_add_pointer_grab (display,
10810
gdk_window_get_events (pointer_window),
10814
_gdk_display_pointer_grab_update (display, serial);
10817
pointer_window = get_pointer_window (display, toplevel_window,
10818
toplevel_x, toplevel_y,
10821
event_win = get_event_window (display,
10826
if (event_win == NULL || display->ignore_core_events)
10829
event = _gdk_make_event (event_win, type, source_event, FALSE);
10833
case GDK_BUTTON_PRESS:
10834
case GDK_BUTTON_RELEASE:
10835
event->button.button = source_event->button.button;
10836
convert_toplevel_coords_to_window (event_win,
10837
toplevel_x, toplevel_y,
10838
&event->button.x, &event->button.y);
10839
event->button.x_root = source_event->button.x_root;
10840
event->button.y_root = source_event->button.y_root;
10841
event->button.state = state;
10842
event->button.device = source_event->button.device;
10844
if (type == GDK_BUTTON_PRESS)
10845
_gdk_event_button_generate (display, event);
10849
event->scroll.direction = source_event->scroll.direction;
10850
convert_toplevel_coords_to_window (event_win,
10851
toplevel_x, toplevel_y,
10852
&event->scroll.x, &event->scroll.y);
10853
event->scroll.x_root = source_event->scroll.x_root;
10854
event->scroll.y_root = source_event->scroll.y_root;
10855
event->scroll.state = state;
10856
event->scroll.device = source_event->scroll.device;
10863
return TRUE; /* Always unlink original, we want to obey the emulated event mask */
10866
#ifdef DEBUG_WINDOW_PRINTING
10868
gdk_window_print (GdkWindowObject *window,
10872
const char *window_types[] = {
10882
g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
10883
window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
10884
window->x, window->y,
10885
window->width, window->height
10888
if (gdk_window_has_impl (window))
10890
#ifdef GDK_WINDOWING_X11
10891
g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
10895
if (window->window_type != GDK_WINDOW_CHILD)
10896
g_print (" %s", window_types[window->window_type]);
10898
if (window->input_only)
10899
g_print (" input-only");
10901
if (window->shaped)
10902
g_print (" shaped");
10904
if (!gdk_window_is_visible ((GdkWindow *)window))
10905
g_print (" hidden");
10907
g_print (" abs[%d,%d]",
10908
window->abs_x, window->abs_y);
10910
gdk_region_get_clipbox (window->clip_region, &r);
10911
if (gdk_region_empty (window->clip_region))
10912
g_print (" clipbox[empty]");
10914
g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
10921
gdk_window_print_tree (GdkWindow *window,
10923
gboolean include_input_only)
10925
GdkWindowObject *private;
10928
private = (GdkWindowObject *)window;
10930
if (private->input_only && !include_input_only)
10933
gdk_window_print (private, indent);
10935
for (l = private->children; l != NULL; l = l->next)
10936
gdk_window_print_tree (l->data, indent + 4, include_input_only);
10939
#endif /* DEBUG_WINDOW_PRINTING */
10942
is_input_event (GdkDisplay *display,
10945
GdkDevice *core_pointer;
10947
core_pointer = gdk_display_get_core_pointer (display);
10948
if ((event->type == GDK_MOTION_NOTIFY &&
10949
event->motion.device != core_pointer) ||
10950
((event->type == GDK_BUTTON_PRESS ||
10951
event->type == GDK_BUTTON_RELEASE) &&
10952
event->button.device != core_pointer))
10958
_gdk_windowing_got_event (GdkDisplay *display,
10963
GdkWindow *event_window;
10964
GdkWindowObject *event_private;
10966
gboolean unlink_event;
10967
guint old_state, old_button;
10968
GdkPointerGrabInfo *button_release_grab;
10969
gboolean is_toplevel;
10971
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
10972
display->last_event_time = gdk_event_get_time (event);
10974
_gdk_display_pointer_grab_update (display,
10977
event_window = event->any.window;
10981
event_private = GDK_WINDOW_OBJECT (event_window);
10983
#ifdef DEBUG_WINDOW_PRINTING
10984
if (event->type == GDK_KEY_PRESS &&
10985
(event->key.keyval == 0xa7 ||
10986
event->key.keyval == 0xbd))
10988
gdk_window_print_tree (event_window, 0,
10989
event->key.keyval == 0xbd);
10993
if (_gdk_native_windows)
10995
if (event->type == GDK_BUTTON_PRESS &&
10996
!event->any.send_event &&
10997
_gdk_display_has_pointer_grab (display, serial) == NULL)
10999
_gdk_display_add_pointer_grab (display,
11003
gdk_window_get_events (event_window),
11005
gdk_event_get_time (event),
11007
_gdk_display_pointer_grab_update (display,
11010
if (event->type == GDK_BUTTON_RELEASE &&
11011
!event->any.send_event)
11013
button_release_grab =
11014
_gdk_display_has_pointer_grab (display, serial);
11015
if (button_release_grab &&
11016
button_release_grab->implicit &&
11017
(event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
11019
button_release_grab->serial_end = serial;
11020
button_release_grab->implicit_ungrab = FALSE;
11021
_gdk_display_pointer_grab_update (display, serial);
11025
if (event->type == GDK_BUTTON_PRESS)
11026
_gdk_event_button_generate (display, event);
11031
if (event->type == GDK_VISIBILITY_NOTIFY)
11033
event_private->native_visibility = event->visibility.state;
11034
gdk_window_update_visibility_recursively (event_private,
11039
if (is_input_event (display, event))
11042
if (!(is_button_type (event->type) ||
11043
is_motion_type (event->type)) ||
11044
event_private->window_type == GDK_WINDOW_ROOT)
11047
is_toplevel = gdk_window_is_toplevel (event_private);
11049
if ((event->type == GDK_ENTER_NOTIFY ||
11050
event->type == GDK_LEAVE_NOTIFY) &&
11051
(event->crossing.mode == GDK_CROSSING_GRAB ||
11052
event->crossing.mode == GDK_CROSSING_UNGRAB) &&
11053
(_gdk_display_has_pointer_grab (display, serial) ||
11054
event->crossing.detail == GDK_NOTIFY_INFERIOR))
11056
/* We synthesize all crossing events due to grabs ourselves,
11057
* so we ignore the native ones caused by our native pointer_grab
11058
* calls. Otherwise we would proxy these crossing event and cause
11059
* multiple copies of crossing events for grabs.
11061
* We do want to handle grabs from other clients though, as for
11062
* instance alt-tab in metacity causes grabs like these and
11063
* we want to handle those. Thus the has_pointer_grab check.
11065
* Implicit grabs on child windows create some grabbing events
11066
* that are sent before the button press. This means we can't
11067
* detect these with the has_pointer_grab check (as the implicit
11068
* grab is only noticed when we get button press event), so we
11069
* detect these events by checking for INFERIOR enter or leave
11070
* events. These should never be a problem to filter out.
11073
/* We ended up in this window after some (perhaps other clients)
11074
grab, so update the toplevel_under_window state */
11076
event->type == GDK_ENTER_NOTIFY &&
11077
event->crossing.mode == GDK_CROSSING_UNGRAB)
11079
if (display->pointer_info.toplevel_under_pointer)
11080
g_object_unref (display->pointer_info.toplevel_under_pointer);
11081
display->pointer_info.toplevel_under_pointer = g_object_ref (event_window);
11084
unlink_event = TRUE;
11088
/* Track toplevel_under_pointer */
11091
if (event->type == GDK_ENTER_NOTIFY &&
11092
event->crossing.detail != GDK_NOTIFY_INFERIOR)
11094
if (display->pointer_info.toplevel_under_pointer)
11095
g_object_unref (display->pointer_info.toplevel_under_pointer);
11096
display->pointer_info.toplevel_under_pointer = g_object_ref (event_window);
11098
else if (event->type == GDK_LEAVE_NOTIFY &&
11099
event->crossing.detail != GDK_NOTIFY_INFERIOR &&
11100
display->pointer_info.toplevel_under_pointer == event_window)
11102
if (display->pointer_info.toplevel_under_pointer)
11103
g_object_unref (display->pointer_info.toplevel_under_pointer);
11104
display->pointer_info.toplevel_under_pointer = NULL;
11108
/* Store last pointer window and position/state */
11109
old_state = display->pointer_info.state;
11110
old_button = display->pointer_info.button;
11112
gdk_event_get_coords (event, &x, &y);
11113
convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
11114
display->pointer_info.toplevel_x = x;
11115
display->pointer_info.toplevel_y = y;
11116
gdk_event_get_state (event, &display->pointer_info.state);
11117
if (event->type == GDK_BUTTON_PRESS ||
11118
event->type == GDK_BUTTON_RELEASE)
11119
display->pointer_info.button = event->button.button;
11121
if (display->pointer_info.state != old_state ||
11122
display->pointer_info.button != old_button)
11123
_gdk_display_enable_motion_hints (display);
11125
unlink_event = FALSE;
11126
if (is_motion_type (event->type))
11127
unlink_event = proxy_pointer_event (display,
11130
else if (is_button_type (event->type))
11131
unlink_event = proxy_button_event (event,
11134
if (event->type == GDK_BUTTON_RELEASE &&
11135
!event->any.send_event)
11137
button_release_grab =
11138
_gdk_display_has_pointer_grab (display, serial);
11139
if (button_release_grab &&
11140
button_release_grab->implicit &&
11141
(event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
11143
button_release_grab->serial_end = serial;
11144
button_release_grab->implicit_ungrab = FALSE;
11145
_gdk_display_pointer_grab_update (display, serial);
11152
_gdk_event_queue_remove_link (display, event_link);
11153
g_list_free_1 (event_link);
11154
gdk_event_free (event);
11160
get_extension_event_window (GdkDisplay *display,
11161
GdkWindow *pointer_window,
11163
GdkModifierType mask,
11167
GdkWindow *grab_window;
11168
GdkWindowObject *w;
11169
GdkPointerGrabInfo *grab;
11171
grab = _gdk_display_has_pointer_grab (display, serial);
11173
if (grab != NULL && !grab->owner_events)
11175
evmask = grab->event_mask;
11176
evmask = update_evmask_for_button_motion (evmask, mask);
11178
grab_window = grab->window;
11180
if (evmask & type_masks[type])
11181
return grab_window;
11186
w = (GdkWindowObject *)pointer_window;
11189
evmask = w->extension_events;
11190
evmask = update_evmask_for_button_motion (evmask, mask);
11192
if (evmask & type_masks[type])
11193
return (GdkWindow *)w;
11195
w = get_event_parent (w);
11198
if (grab != NULL &&
11199
grab->owner_events)
11201
evmask = grab->event_mask;
11202
evmask = update_evmask_for_button_motion (evmask, mask);
11204
if (evmask & type_masks[type])
11205
return grab->window;
11215
_gdk_window_get_input_window_for_event (GdkWindow *native_window,
11216
GdkEventType event_type,
11217
GdkModifierType mask,
11221
GdkDisplay *display;
11222
GdkWindow *toplevel_window;
11223
GdkWindow *pointer_window;
11224
GdkWindow *event_win;
11225
gdouble toplevel_x, toplevel_y;
11230
display = gdk_drawable_get_display (native_window);
11231
toplevel_window = convert_native_coords_to_toplevel (native_window,
11232
toplevel_x, toplevel_y,
11233
&toplevel_x, &toplevel_y);
11234
pointer_window = get_pointer_window (display, toplevel_window,
11235
toplevel_x, toplevel_y, serial);
11236
event_win = get_extension_event_window (display,
11246
* gdk_window_create_similar_surface:
11247
* @window: window to make new surface similar to
11248
* @content: the content for the new surface
11249
* @width: width of the new surface
11250
* @height: height of the new surface
11252
* Create a new surface that is as compatible as possible with the
11253
* given @window. For example the new surface will have the same
11254
* fallback resolution and font options as @window. Generally, the new
11255
* surface will also use the same backend as @window, unless that is
11256
* not possible for some reason. The type of the returned surface may
11257
* be examined with cairo_surface_get_type().
11259
* Initially the surface contents are all 0 (transparent if contents
11260
* have transparency, black otherwise.)
11262
* Returns: a pointer to the newly allocated surface. The caller
11263
* owns the surface and should call cairo_surface_destroy() when done
11266
* This function always returns a valid pointer, but it will return a
11267
* pointer to a "nil" surface if @other is already in an error state
11268
* or any other error occurs.
11273
gdk_window_create_similar_surface (GdkWindow * window,
11274
cairo_content_t content,
11278
cairo_surface_t *window_surface, *surface;
11280
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
11282
window_surface = _gdk_drawable_ref_cairo_surface (window);
11284
surface = cairo_surface_create_similar (window_surface,
11288
cairo_surface_destroy (window_surface);
11294
* gdk_window_get_screen:
11295
* @window: a #GdkWindow
11297
* Gets the #GdkScreen associated with a #GdkWindow.
11299
* Return value: the #GdkScreen associated with @window
11304
gdk_window_get_screen (GdkWindow *window)
11306
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
11308
return gdk_drawable_get_screen (GDK_DRAWABLE (window));
11312
* gdk_window_get_display:
11313
* @window: a #GdkWindow
11315
* Gets the #GdkDisplay associated with a #GdkWindow.
11317
* Return value: the #GdkDisplay associated with @window
11322
gdk_window_get_display (GdkWindow *window)
11324
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
11326
return gdk_drawable_get_display (GDK_DRAWABLE (window));
11330
* gdk_window_get_visual:
11331
* @window: a #GdkWindow
11333
* Gets the #GdkVisual describing the pixel format of @window.
11335
* Return value: a #GdkVisual
11340
gdk_window_get_visual (GdkWindow *window)
11342
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
11344
return gdk_drawable_get_visual (GDK_DRAWABLE (window));
11348
* gdk_window_get_width:
11349
* @window: a #GdkWindow
11351
* Returns the width of the given @window.
11353
* On the X11 platform the returned size is the size reported in the
11354
* most-recently-processed configure event, rather than the current
11355
* size on the X server.
11357
* Returns: The width of @window
11362
gdk_window_get_width (GdkWindow *window)
11364
gint width, height;
11366
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
11368
gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
11374
* gdk_window_get_height:
11375
* @window: a #GdkWindow
11377
* Returns the height of the given @window.
11379
* On the X11 platform the returned size is the size reported in the
11380
* most-recently-processed configure event, rather than the current
11381
* size on the X server.
11383
* Returns: The height of @window
11388
gdk_window_get_height (GdkWindow *window)
11390
gint width, height;
11392
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
11394
gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
11400
#define __GDK_WINDOW_C__
11401
#include "gdkaliasdef.c"