1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 #include "gdkwindow.h"
28 #include "gdkinternals.h"
29 #include "gdk.h" /* For gdk_rectangle_union() */
30 #include "gdkpixmap.h"
32 #ifndef USE_BACKING_STORE
33 #ifndef GDK_WINDOWING_WIN32
34 #define USE_BACKING_STORE /* Doesn't work yet on Win32 */
38 typedef struct _GdkWindowPaint GdkWindowPaint;
40 struct _GdkWindowPaint
47 static GdkGC *gdk_window_create_gc (GdkDrawable *drawable,
49 GdkGCValuesMask mask);
50 static void gdk_window_draw_rectangle (GdkDrawable *drawable,
57 static void gdk_window_draw_arc (GdkDrawable *drawable,
66 static void gdk_window_draw_polygon (GdkDrawable *drawable,
71 static void gdk_window_draw_text (GdkDrawable *drawable,
78 static void gdk_window_draw_text_wc (GdkDrawable *drawable,
85 static void gdk_window_draw_drawable (GdkDrawable *drawable,
94 static void gdk_window_draw_points (GdkDrawable *drawable,
98 static void gdk_window_draw_segments (GdkDrawable *drawable,
102 static void gdk_window_draw_lines (GdkDrawable *drawable,
106 static void gdk_window_draw_glyphs (GdkDrawable *drawable,
111 PangoGlyphString *glyphs);
113 static void gdk_window_draw_image (GdkDrawable *drawable,
124 static void gdk_window_real_get_size (GdkDrawable *drawable,
128 static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable);
129 static gint gdk_window_real_get_depth (GdkDrawable *drawable);
130 static void gdk_window_real_set_colormap (GdkDrawable *drawable,
132 static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable);
134 static void gdk_window_free_paint_stack (GdkWindow *window);
136 static void gdk_window_init (GdkWindowObject *window);
137 static void gdk_window_class_init (GdkWindowObjectClass *klass);
138 static void gdk_window_finalize (GObject *object);
140 static gpointer parent_class = NULL;
143 gdk_window_object_get_type (void)
145 static GType object_type = 0;
149 static const GTypeInfo object_info =
151 sizeof (GdkWindowObjectClass),
152 (GBaseInitFunc) NULL,
153 (GBaseFinalizeFunc) NULL,
154 (GClassInitFunc) gdk_window_class_init,
155 NULL, /* class_finalize */
156 NULL, /* class_data */
157 sizeof (GdkWindowObject),
159 (GInstanceInitFunc) gdk_window_init,
162 object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
171 gdk_window_init (GdkWindowObject *window)
173 /* 0-initialization is good for all other fields. */
175 window->window_type = GDK_WINDOW_CHILD;
178 GDK_DRAWABLE (g_type_create_instance (_gdk_window_impl_get_type ()));
182 gdk_window_class_init (GdkWindowObjectClass *klass)
184 GObjectClass *object_class = G_OBJECT_CLASS (klass);
185 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
187 parent_class = g_type_class_peek_parent (klass);
189 object_class->finalize = gdk_window_finalize;
191 drawable_class->create_gc = gdk_window_create_gc;
192 drawable_class->draw_rectangle = gdk_window_draw_rectangle;
193 drawable_class->draw_arc = gdk_window_draw_arc;
194 drawable_class->draw_polygon = gdk_window_draw_polygon;
195 drawable_class->draw_text = gdk_window_draw_text;
196 drawable_class->draw_text_wc = gdk_window_draw_text_wc;
197 drawable_class->draw_drawable = gdk_window_draw_drawable;
198 drawable_class->draw_points = gdk_window_draw_points;
199 drawable_class->draw_segments = gdk_window_draw_segments;
200 drawable_class->draw_lines = gdk_window_draw_lines;
201 drawable_class->draw_glyphs = gdk_window_draw_glyphs;
202 drawable_class->draw_image = gdk_window_draw_image;
203 drawable_class->get_depth = gdk_window_real_get_depth;
204 drawable_class->get_size = gdk_window_real_get_size;
205 drawable_class->set_colormap = gdk_window_real_set_colormap;
206 drawable_class->get_colormap = gdk_window_real_get_colormap;
207 drawable_class->get_visual = gdk_window_real_get_visual;
211 gdk_window_finalize (GObject *object)
213 GdkWindow *window = GDK_WINDOW (object);
214 GdkWindowObject *obj = (GdkWindowObject *) object;
216 if (!GDK_WINDOW_DESTROYED (window))
218 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
220 g_warning ("losing last reference to undestroyed window\n");
221 _gdk_window_destroy (window, FALSE);
224 /* We use TRUE here, to keep us from actually calling
225 * XDestroyWindow() on the window
227 _gdk_window_destroy (window, TRUE);
230 g_object_unref (G_OBJECT (obj->impl));
233 G_OBJECT_CLASS (parent_class)->finalize (object);
237 * _gdk_window_destroy_hierarchy:
238 * @window: a #GdkWindow
239 * @recursing: If TRUE, then this is being called because a parent
240 * was destroyed. This generally means that the call to the windowing system
241 * to destroy the window can be omitted, since it will be destroyed as a result
242 * of the parent being destroyed. Unless @foreign_destroy
244 * foreign_destroy: If TRUE, the window or a parent was destroyed by some external
245 * agency. The window has already been destroyed and no windowing
246 * system calls should be made. (This may never happen for some
247 * windowing systems.)
249 * Internal function to destroy a window. Like gdk_window_destroy(), but does not
250 * drop the reference count created by gdk_window_new().
253 _gdk_window_destroy_hierarchy (GdkWindow *window,
255 gboolean foreign_destroy)
257 GdkWindowObject *private;
258 GdkWindowObject *temp_private;
259 GdkWindow *temp_window;
263 g_return_if_fail (window != NULL);
265 private = (GdkWindowObject*) window;
267 switch (GDK_WINDOW_TYPE (window))
269 case GDK_WINDOW_TOPLEVEL:
270 case GDK_WINDOW_CHILD:
271 case GDK_WINDOW_DIALOG:
272 case GDK_WINDOW_TEMP:
273 case GDK_WINDOW_FOREIGN:
274 if (!GDK_WINDOW_DESTROYED (window))
276 private->mapped = FALSE;
277 private->destroyed = TRUE;
279 _gdk_windowing_window_destroy (window, recursing, foreign_destroy);
283 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
284 if (parent_private->children)
285 parent_private->children = g_list_remove (parent_private->children, window);
288 _gdk_window_clear_update_area (window);
289 gdk_window_free_paint_stack (window);
291 if (private->bg_pixmap &&
292 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
293 private->bg_pixmap != GDK_NO_BG)
295 gdk_pixmap_unref (private->bg_pixmap);
296 private->bg_pixmap = NULL;
299 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
301 children = tmp = private->children;
302 private->children = NULL;
306 temp_window = tmp->data;
309 temp_private = (GdkWindowObject*) temp_window;
311 _gdk_window_destroy_hierarchy (temp_window, TRUE, foreign_destroy);
314 g_list_free (children);
317 if (private->filters)
319 tmp = private->filters;
327 g_list_free (private->filters);
328 private->filters = NULL;
331 gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
335 case GDK_WINDOW_ROOT:
336 g_error ("attempted to destroy root window");
342 * _gdk_window_destroy:
343 * @window: a #GdkWindow
344 * foreign_destroy: If TRUE, the window or a parent was destroyed by some external
345 * agency. The window has already been destroyed and no windowing
346 * system calls should be made. (This may never happen for some
347 * windowing systems.)
349 * Internal function to destroy a window. Like gdk_window_destroy(), but does not
350 * drop the reference count created by gdk_window_new().
353 _gdk_window_destroy (GdkWindow *window,
354 gboolean foreign_destroy)
356 _gdk_window_destroy_hierarchy (window, FALSE, foreign_destroy);
360 gdk_window_destroy (GdkWindow *window)
362 _gdk_window_destroy_hierarchy (window, FALSE, FALSE);
363 gdk_drawable_unref (window);
367 gdk_window_set_user_data (GdkWindow *window,
370 g_return_if_fail (window != NULL);
372 ((GdkWindowObject*)window)->user_data = user_data;
376 gdk_window_get_user_data (GdkWindow *window,
379 g_return_if_fail (window != NULL);
381 *data = ((GdkWindowObject*)window)->user_data;
385 gdk_window_get_window_type (GdkWindow *window)
387 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
389 return GDK_WINDOW_TYPE (window);
393 gdk_window_get_position (GdkWindow *window,
397 GdkWindowObject *obj;
399 g_return_if_fail (GDK_IS_WINDOW (window));
401 obj = (GdkWindowObject*) window;
410 gdk_window_get_parent (GdkWindow *window)
412 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
414 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
418 gdk_window_get_toplevel (GdkWindow *window)
420 GdkWindowObject *obj;
422 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
424 obj = (GdkWindowObject *)window;
425 while (GDK_WINDOW_TYPE (obj) == GDK_WINDOW_CHILD)
426 obj = (GdkWindowObject *)obj->parent;
428 return GDK_WINDOW (obj);
432 gdk_window_get_children (GdkWindow *window)
434 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
436 if (GDK_WINDOW_DESTROYED (window))
439 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
443 gdk_window_peek_children (GdkWindow *window)
445 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
447 if (GDK_WINDOW_DESTROYED (window))
450 return GDK_WINDOW_OBJECT (window)->children;
454 gdk_window_add_filter (GdkWindow *window,
455 GdkFilterFunc function,
458 GdkWindowObject *private;
460 GdkEventFilter *filter;
462 g_return_if_fail (window != NULL);
463 g_return_if_fail (GDK_IS_WINDOW (window));
465 private = (GdkWindowObject*) window;
466 if (private && GDK_WINDOW_DESTROYED (window))
470 tmp_list = private->filters;
472 tmp_list = gdk_default_filters;
476 filter = (GdkEventFilter *)tmp_list->data;
477 if ((filter->function == function) && (filter->data == data))
479 tmp_list = tmp_list->next;
482 filter = g_new (GdkEventFilter, 1);
483 filter->function = function;
487 private->filters = g_list_append (private->filters, filter);
489 gdk_default_filters = g_list_append (gdk_default_filters, filter);
493 gdk_window_remove_filter (GdkWindow *window,
494 GdkFilterFunc function,
497 GdkWindowObject *private;
498 GList *tmp_list, *node;
499 GdkEventFilter *filter;
501 g_return_if_fail (window != NULL);
502 g_return_if_fail (GDK_IS_WINDOW (window));
504 private = (GdkWindowObject*) window;
507 tmp_list = private->filters;
509 tmp_list = gdk_default_filters;
513 filter = (GdkEventFilter *)tmp_list->data;
515 tmp_list = tmp_list->next;
517 if ((filter->function == function) && (filter->data == data))
520 private->filters = g_list_remove_link (private->filters, node);
522 gdk_default_filters = g_list_remove_link (gdk_default_filters, node);
523 g_list_free_1 (node);
532 gdk_window_get_toplevels (void)
534 GList *new_list = NULL;
537 tmp_list = ((GdkWindowObject *)gdk_parent_root)->children;
540 new_list = g_list_prepend (new_list, tmp_list->data);
541 tmp_list = tmp_list->next;
547 /*************************************************************
548 * gdk_window_is_visible:
549 * Check if the given window is mapped.
553 * is the window mapped
554 *************************************************************/
557 gdk_window_is_visible (GdkWindow *window)
559 GdkWindowObject *private = (GdkWindowObject *)window;
561 g_return_val_if_fail (window != NULL, FALSE);
562 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
564 return private->mapped;
567 /*************************************************************
568 * gdk_window_is_viewable:
569 * Check if the window and all ancestors of the window
570 * are mapped. (This is not necessarily "viewable" in
571 * the X sense, since we only check as far as we have
572 * GDK window parents, not to the root window)
576 * is the window viewable
577 *************************************************************/
580 gdk_window_is_viewable (GdkWindow *window)
582 GdkWindowObject *private = (GdkWindowObject *)window;
584 g_return_val_if_fail (window != NULL, FALSE);
585 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
588 (private != (GdkWindowObject *)gdk_parent_root) &&
589 (GDK_WINDOW_TYPE (private) != GDK_WINDOW_FOREIGN))
591 if (!private->mapped)
594 private = (GdkWindowObject *)private->parent;
601 gdk_window_begin_paint_rect (GdkWindow *window,
602 GdkRectangle *rectangle)
606 g_return_if_fail (window != NULL);
607 g_return_if_fail (GDK_IS_WINDOW (window));
609 region = gdk_region_rectangle (rectangle);
610 gdk_window_begin_paint_region (window, region);
611 gdk_region_destroy (region);
615 gdk_window_get_bg_gc (GdkWindow *window, GdkWindowPaint *paint)
617 GdkWindowObject *private = (GdkWindowObject *)window;
620 GdkGCValues gc_values;
622 if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
624 GdkWindowPaint tmp_paint = *paint;
625 tmp_paint.x_offset += private->x;
626 tmp_paint.y_offset += private->y;
628 return gdk_window_get_bg_gc (GDK_WINDOW (private->parent), &tmp_paint);
630 else if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && private->bg_pixmap != GDK_NO_BG)
632 gc_values.fill = GDK_TILED;
633 gc_values.tile = private->bg_pixmap;
634 gc_values.ts_x_origin = - paint->x_offset;
635 gc_values.ts_y_origin = - paint->y_offset;
637 gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN;
641 gc_values.foreground = private->bg_color;
642 gc_mask = GDK_GC_FOREGROUND;
645 return gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask);
649 gdk_window_paint_init_bg (GdkWindow *window,
650 GdkWindowPaint *paint,
651 GdkRegion *init_region)
655 tmp_gc = gdk_window_get_bg_gc (window, paint);
656 gdk_draw_rectangle (paint->pixmap, tmp_gc, TRUE, 0, 0, -1, -1);
657 gdk_gc_unref (tmp_gc);
661 gdk_window_begin_paint_region (GdkWindow *window,
664 #ifdef USE_BACKING_STORE
665 GdkWindowObject *private = (GdkWindowObject *)window;
666 GdkRectangle clip_box;
667 GdkWindowPaint *paint;
668 GdkRegion *init_region;
671 g_return_if_fail (window != NULL);
672 g_return_if_fail (GDK_IS_WINDOW (window));
674 if (GDK_WINDOW_DESTROYED (window))
677 paint = g_new (GdkWindowPaint, 1);
679 paint->region = gdk_region_copy (region);
681 init_region = gdk_region_copy (region);
682 gdk_region_get_clipbox (paint->region, &clip_box);
684 if (private->paint_stack)
686 gint old_width, old_height;
687 GdkWindowPaint *tmp_paint = private->paint_stack->data;
688 GdkRectangle old_rect, new_rect;
691 gdk_drawable_get_size (tmp_paint->pixmap, &old_width, &old_height);
692 old_rect.x = tmp_paint->x_offset;
693 old_rect.y = tmp_paint->y_offset;
694 old_rect.width = old_width;
695 old_rect.height = old_height;
697 gdk_rectangle_union (&clip_box, &old_rect, &new_rect);
699 if (new_rect.width > old_rect.width || new_rect.height > old_rect.height)
701 paint->pixmap = gdk_pixmap_new (window, new_rect.width, new_rect.height, -1);
702 tmp_gc = gdk_gc_new (paint->pixmap);
703 gdk_draw_drawable (paint->pixmap, tmp_gc, tmp_paint->pixmap,
704 0, 0, old_rect.width, old_rect.height,
705 old_rect.x - new_rect.x, old_rect.y - new_rect.y);
706 gdk_gc_unref (tmp_gc);
707 gdk_drawable_unref (tmp_paint->pixmap);
709 paint->x_offset = new_rect.x;
710 paint->y_offset = new_rect.y;
712 tmp_list = private->paint_stack;
715 tmp_paint = private->paint_stack->data;
716 gdk_region_subtract (init_region, tmp_paint->region);
718 tmp_paint->pixmap = paint->pixmap;
719 tmp_paint->x_offset = paint->x_offset;
720 tmp_paint->y_offset = paint->x_offset;
722 tmp_list = tmp_list->next;
727 paint->x_offset = tmp_paint->x_offset;
728 paint->y_offset = tmp_paint->y_offset;
729 paint->pixmap = tmp_paint->pixmap;
731 tmp_list = private->paint_stack;
734 tmp_paint = private->paint_stack->data;
735 gdk_region_subtract (init_region, tmp_paint->region);
737 tmp_list = tmp_list->next;
743 paint->x_offset = clip_box.x;
744 paint->y_offset = clip_box.y;
745 paint->pixmap = gdk_pixmap_new (window, clip_box.width, clip_box.height, -1);
748 if (!gdk_region_empty (init_region))
749 gdk_window_paint_init_bg (window, paint, init_region);
750 gdk_region_destroy (init_region);
752 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
753 #endif /* USE_BACKING_STORE */
757 gdk_window_end_paint (GdkWindow *window)
759 #ifdef USE_BACKING_STORE
760 GdkWindowObject *private = (GdkWindowObject *)window;
761 GdkWindowPaint *paint;
763 GdkRectangle clip_box;
764 gint x_offset, y_offset;
766 g_return_if_fail (window != NULL);
767 g_return_if_fail (GDK_IS_WINDOW (window));
769 if (GDK_WINDOW_DESTROYED (window))
772 g_return_if_fail (private->paint_stack != NULL);
774 paint = private->paint_stack->data;
775 private->paint_stack = g_slist_delete_link (private->paint_stack, private->paint_stack);
777 gdk_region_get_clipbox (paint->region, &clip_box);
779 tmp_gc = gdk_gc_new (window);
781 _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset);
783 gdk_gc_set_clip_region (tmp_gc, paint->region);
784 gdk_gc_set_clip_origin (tmp_gc, -x_offset, -y_offset);
786 gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
787 clip_box.x - paint->x_offset,
788 clip_box.y - paint->y_offset,
789 clip_box.x - x_offset, clip_box.y - y_offset,
790 clip_box.width, clip_box.height);
791 gdk_gc_unref (tmp_gc);
793 if (private->paint_stack)
795 GSList *tmp_list = private->paint_stack;
798 GdkWindowPaint *tmp_paint = tmp_list->data;
799 gdk_region_subtract (tmp_paint->region, paint->region);
801 tmp_list = tmp_list->next;
805 gdk_drawable_unref (paint->pixmap);
807 gdk_region_destroy (paint->region);
809 #endif /* USE_BACKING_STORE */
813 gdk_window_free_paint_stack (GdkWindow *window)
815 GdkWindowObject *private = (GdkWindowObject *)window;
817 if (private->paint_stack)
819 GSList *tmp_list = private->paint_stack;
823 GdkWindowPaint *paint = tmp_list->data;
825 if (tmp_list == private->paint_stack)
826 gdk_drawable_unref (paint->pixmap);
828 gdk_region_destroy (paint->region);
831 tmp_list = tmp_list->next;
834 g_slist_free (private->paint_stack);
835 private->paint_stack = NULL;
840 gdk_window_get_offsets (GdkWindow *window,
844 GdkWindowObject *private = (GdkWindowObject *)window;
846 if (private->paint_stack)
848 GdkWindowPaint *paint = private->paint_stack->data;
849 *x_offset = paint->x_offset;
850 *y_offset = paint->y_offset;
853 _gdk_windowing_window_get_offsets (window, x_offset, y_offset);
856 #define OFFSET_GC(gc) \
857 gint x_offset, y_offset; \
858 gint old_clip_x = gc->clip_x_origin; \
859 gint old_clip_y = gc->clip_y_origin; \
860 gint old_ts_x = gc->ts_x_origin; \
861 gint old_ts_y = gc->ts_y_origin; \
862 gdk_window_get_offsets (drawable, &x_offset, &y_offset); \
863 if (x_offset != 0 || y_offset != 0) \
865 gdk_gc_set_clip_origin (gc, old_clip_x - x_offset, \
866 old_clip_y - y_offset); \
867 gdk_gc_set_ts_origin (gc, old_ts_x - x_offset, \
868 old_ts_y - y_offset); \
871 #define RESTORE_GC(gc) \
872 if (x_offset != 0 || y_offset != 0) \
874 gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \
875 gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y); \
879 gdk_window_create_gc (GdkDrawable *drawable,
881 GdkGCValuesMask mask)
883 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
885 if (GDK_WINDOW_DESTROYED (drawable))
888 return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl,
893 gdk_window_draw_rectangle (GdkDrawable *drawable,
901 GdkWindowObject *private = (GdkWindowObject *)drawable;
904 if (GDK_WINDOW_DESTROYED (drawable))
907 if (private->paint_stack)
909 GdkWindowPaint *paint = private->paint_stack->data;
910 gdk_draw_rectangle (paint->pixmap, gc, filled,
911 x - x_offset, y - y_offset, width, height);
914 gdk_draw_rectangle (private->impl, gc, filled,
915 x - x_offset, y - y_offset, width, height);
921 gdk_window_draw_arc (GdkDrawable *drawable,
931 GdkWindowObject *private = (GdkWindowObject *)drawable;
934 if (GDK_WINDOW_DESTROYED (drawable))
937 if (private->paint_stack)
939 GdkWindowPaint *paint = private->paint_stack->data;
940 gdk_draw_arc (paint->pixmap, gc, filled,
941 x - x_offset, y_offset,
942 width, height, angle1, angle2);
945 gdk_draw_arc (private->impl, gc, filled,
946 x - x_offset, y - y_offset,
947 width, height, angle1, angle2);
952 gdk_window_draw_polygon (GdkDrawable *drawable,
958 GdkWindowObject *private = (GdkWindowObject *)drawable;
959 GdkPoint *new_points;
963 if (GDK_WINDOW_DESTROYED (drawable))
966 if (x_offset != 0 || y_offset != 0)
970 new_points = g_new (GdkPoint, npoints);
971 for (i=0; i<npoints; i++)
973 new_points[i].x = points[i].x - x_offset;
974 new_points[i].y = points[i].y - y_offset;
980 if (private->paint_stack)
982 GdkWindowPaint *paint = private->paint_stack->data;
983 gdk_draw_polygon (paint->pixmap, gc, filled, new_points, npoints);
987 gdk_draw_polygon (private->impl, gc, filled, new_points, npoints);
989 if (new_points != points)
996 gdk_window_draw_text (GdkDrawable *drawable,
1004 GdkWindowObject *private = (GdkWindowObject *)drawable;
1007 if (GDK_WINDOW_DESTROYED (drawable))
1010 if (private->paint_stack)
1012 GdkWindowPaint *paint = private->paint_stack->data;
1013 gdk_draw_text (paint->pixmap, font, gc,
1014 x - x_offset, y - y_offset, text, text_length);
1018 gdk_draw_text (private->impl, font, gc,
1019 x - x_offset, y - y_offset, text, text_length);
1025 gdk_window_draw_text_wc (GdkDrawable *drawable,
1030 const GdkWChar *text,
1033 GdkWindowObject *private = (GdkWindowObject *)drawable;
1036 if (GDK_WINDOW_DESTROYED (drawable))
1039 if (private->paint_stack)
1041 GdkWindowPaint *paint = private->paint_stack->data;
1042 gdk_draw_text_wc (paint->pixmap, font, gc,
1043 x - x_offset, y - y_offset, text, text_length);
1046 gdk_draw_text_wc (private->impl, font, gc,
1047 x - x_offset, y - y_offset, text, text_length);
1053 gdk_window_draw_drawable (GdkDrawable *drawable,
1063 GdkWindowObject *private = (GdkWindowObject *)drawable;
1066 if (GDK_WINDOW_DESTROYED (drawable))
1069 if (private->paint_stack)
1071 GdkWindowPaint *paint = private->paint_stack->data;
1072 gdk_draw_drawable (paint->pixmap, gc, src, xsrc, ysrc,
1073 xdest - x_offset, ydest - y_offset, width, height);
1077 gdk_draw_drawable (private->impl, gc, src, xsrc, ysrc,
1078 xdest - x_offset, ydest - y_offset,
1084 gdk_window_draw_points (GdkDrawable *drawable,
1089 GdkWindowObject *private = (GdkWindowObject *)drawable;
1090 GdkPoint *new_points;
1094 if (GDK_WINDOW_DESTROYED (drawable))
1097 if (x_offset != 0 || y_offset != 0)
1101 new_points = g_new (GdkPoint, npoints);
1102 for (i=0; i<npoints; i++)
1104 new_points[i].x = points[i].x - x_offset;
1105 new_points[i].y = points[i].y - y_offset;
1109 new_points = points;
1111 if (private->paint_stack)
1113 GdkWindowPaint *paint = private->paint_stack->data;
1114 gdk_draw_points (paint->pixmap, gc, new_points, npoints);
1117 gdk_draw_points (private->impl, gc, points, npoints);
1119 if (new_points != points)
1120 g_free (new_points);
1126 gdk_window_draw_segments (GdkDrawable *drawable,
1131 GdkWindowObject *private = (GdkWindowObject *)drawable;
1132 GdkSegment *new_segs;
1136 if (GDK_WINDOW_DESTROYED (drawable))
1139 if (x_offset != 0 || y_offset != 0)
1143 new_segs = g_new (GdkSegment, nsegs);
1144 for (i=0; i<nsegs; i++)
1146 new_segs[i].x1 = segs[i].x1 - x_offset;
1147 new_segs[i].y1 = segs[i].y1 - y_offset;
1148 new_segs[i].x2 = segs[i].x2 - x_offset;
1149 new_segs[i].y2 = segs[i].y2 - y_offset;
1155 if (private->paint_stack)
1157 GdkWindowPaint *paint = private->paint_stack->data;
1158 gdk_draw_segments (paint->pixmap, gc, new_segs, nsegs);
1161 gdk_draw_segments (private->impl, gc, new_segs, nsegs);
1163 if (new_segs != segs)
1170 gdk_window_draw_lines (GdkDrawable *drawable,
1175 GdkWindowObject *private = (GdkWindowObject *)drawable;
1176 GdkPoint *new_points;
1180 if (GDK_WINDOW_DESTROYED (drawable))
1183 if (x_offset != 0 || y_offset != 0)
1187 new_points = g_new (GdkPoint, npoints);
1188 for (i=0; i<npoints; i++)
1190 new_points[i].x = points[i].x - x_offset;
1191 new_points[i].y = points[i].y - y_offset;
1195 new_points = points;
1197 if (private->paint_stack)
1199 GdkWindowPaint *paint = private->paint_stack->data;
1200 gdk_draw_lines (paint->pixmap, gc, new_points, npoints);
1203 gdk_draw_lines (private->impl, gc, new_points, npoints);
1205 if (new_points != points)
1206 g_free (new_points);
1212 gdk_window_draw_glyphs (GdkDrawable *drawable,
1217 PangoGlyphString *glyphs)
1219 GdkWindowObject *private = (GdkWindowObject *)drawable;
1223 if (GDK_WINDOW_DESTROYED (drawable))
1226 if (private->paint_stack)
1228 GdkWindowPaint *paint = private->paint_stack->data;
1230 gdk_draw_glyphs (paint->pixmap, gc, font, x - x_offset, y - y_offset, glyphs);
1233 gdk_draw_glyphs (private->impl, gc, font,
1234 x - x_offset, y - y_offset, glyphs);
1239 /* Fixme - this is just like gdk_window_paint_init_bg */
1241 gdk_window_clear_backing_rect (GdkWindow *window,
1247 GdkWindowObject *private = (GdkWindowObject *)window;
1248 GdkWindowPaint *paint = private->paint_stack->data;
1251 if (GDK_WINDOW_DESTROYED (window))
1254 tmp_gc = gdk_window_get_bg_gc (window, paint);
1255 gdk_draw_rectangle (paint->pixmap, tmp_gc, TRUE,
1256 x - paint->x_offset, y - paint->y_offset, width, height);
1257 gdk_gc_unref (tmp_gc);
1261 gdk_window_clear (GdkWindow *window)
1265 g_return_if_fail (window != NULL);
1266 g_return_if_fail (GDK_IS_WINDOW (window));
1268 gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
1270 gdk_window_clear_area (window, 0, 0,
1275 gdk_window_clear_area (GdkWindow *window,
1281 GdkWindowObject *private = (GdkWindowObject *)window;
1283 g_return_if_fail (window != NULL);
1284 g_return_if_fail (GDK_IS_WINDOW (window));
1286 if (private->paint_stack)
1287 gdk_window_clear_backing_rect (window, x, y, width, height);
1289 _gdk_windowing_window_clear_area (window, x, y, width, height);
1293 gdk_window_clear_area_e (GdkWindow *window,
1299 GdkWindowObject *private = (GdkWindowObject *)window;
1301 g_return_if_fail (window != NULL);
1302 g_return_if_fail (GDK_IS_WINDOW (window));
1304 if (private->paint_stack)
1305 gdk_window_clear_backing_rect (window, x, y, width, height);
1307 _gdk_windowing_window_clear_area_e (window, x, y, width, height);
1311 gdk_window_draw_image (GdkDrawable *drawable,
1321 GdkWindowObject *private = (GdkWindowObject *)drawable;
1325 if (GDK_WINDOW_DESTROYED (drawable))
1328 if (private->paint_stack)
1330 GdkWindowPaint *paint = private->paint_stack->data;
1331 gdk_draw_image (paint->pixmap, gc, image, xsrc, ysrc,
1332 xdest - x_offset, ydest - y_offset,
1337 gdk_draw_image (private->impl, gc, image, xsrc, ysrc,
1338 xdest - x_offset, ydest - y_offset,
1346 gdk_window_real_get_size (GdkDrawable *drawable,
1350 g_return_if_fail (GDK_IS_WINDOW (drawable));
1352 gdk_drawable_get_size (GDK_WINDOW_OBJECT (drawable)->impl,
1357 gdk_window_real_get_visual (GdkDrawable *drawable)
1359 GdkColormap *colormap;
1361 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
1363 colormap = gdk_drawable_get_colormap (drawable);
1364 return colormap ? gdk_colormap_get_visual (colormap) : NULL;
1368 gdk_window_real_get_depth (GdkDrawable *drawable)
1372 g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
1374 depth = ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
1378 g_print ("0 depth for type %s\n", g_type_name (G_OBJECT_TYPE (drawable)));
1386 gdk_window_real_set_colormap (GdkDrawable *drawable,
1389 g_return_if_fail (GDK_IS_WINDOW (drawable));
1391 if (GDK_WINDOW_DESTROYED (drawable))
1394 gdk_drawable_set_colormap (((GdkWindowObject*)drawable)->impl, cmap);
1398 gdk_window_real_get_colormap (GdkDrawable *drawable)
1400 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
1402 if (GDK_WINDOW_DESTROYED (drawable))
1405 return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
1408 /* Code for dirty-region queueing
1411 static GSList *update_windows = NULL;
1412 static guint update_idle = 0;
1415 gdk_window_process_updates_internal (GdkWindow *window)
1417 GdkWindowObject *private = (GdkWindowObject *)window;
1418 gboolean save_region = FALSE;
1420 /* If an update got queued during update processing, we can get a
1421 * window in the update queue that has an empty update_area.
1424 if (private->update_area)
1426 GdkRegion *update_area = private->update_area;
1427 private->update_area = NULL;
1432 GdkRectangle window_rect;
1435 gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
1439 window_rect.width = width;
1440 window_rect.height = height;
1442 save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
1444 event.expose.type = GDK_EXPOSE;
1445 event.expose.window = gdk_window_ref (window);
1446 event.expose.count = 0;
1448 gdk_region_get_clipbox (update_area, &event.expose.area);
1449 if (gdk_rectangle_intersect (&event.expose.area, &window_rect, &event.expose.area))
1451 (*gdk_event_func) (&event, gdk_event_data);
1454 gdk_window_unref (window);
1458 gdk_region_destroy (update_area);
1463 gdk_window_process_all_updates (void)
1465 GSList *old_update_windows = update_windows;
1466 GSList *tmp_list = update_windows;
1469 g_source_remove (update_idle);
1471 update_windows = NULL;
1476 gdk_window_process_updates_internal (tmp_list->data);
1477 tmp_list = tmp_list->next;
1480 g_slist_free (old_update_windows);
1486 gdk_window_update_idle (gpointer data)
1488 gdk_window_process_all_updates ();
1494 gdk_window_process_updates (GdkWindow *window,
1495 gboolean update_children)
1497 GdkWindowObject *private = (GdkWindowObject *)window;
1499 g_return_if_fail (window != NULL);
1500 g_return_if_fail (GDK_IS_WINDOW (window));
1502 if (private->update_area)
1504 gdk_window_process_updates_internal (window);
1505 update_windows = g_slist_remove (update_windows, window);
1508 if (update_children)
1510 GList *tmp_list = private->children;
1513 gdk_window_process_updates (tmp_list->data, TRUE);
1514 tmp_list = tmp_list->next;
1520 gdk_window_invalidate_rect (GdkWindow *window,
1522 gboolean invalidate_children)
1524 GdkRectangle window_rect;
1525 GdkWindowObject *private = (GdkWindowObject *)window;
1527 g_return_if_fail (window != NULL);
1528 g_return_if_fail (GDK_IS_WINDOW (window));
1530 if (GDK_WINDOW_DESTROYED (window))
1537 gdk_drawable_get_size (GDK_DRAWABLE (window),
1539 &window_rect.height);
1540 rect = &window_rect;
1543 if (private->update_area)
1545 gdk_region_union_with_rect (private->update_area, rect);
1549 update_windows = g_slist_prepend (update_windows, window);
1550 private->update_area = gdk_region_rectangle (rect);
1552 if (!private->update_freeze_count && !update_idle)
1553 update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
1554 gdk_window_update_idle, NULL, NULL);
1558 if (invalidate_children)
1561 GdkRectangle child_rect, new_rect;
1563 tmp_list = private->children;
1566 GdkWindowObject *child = tmp_list->data;
1567 tmp_list = tmp_list->next;
1569 if (!child->input_only)
1573 gdk_drawable_get_size (GDK_DRAWABLE (child),
1576 child_rect.x = child->x;
1577 child_rect.y = child->y;
1578 child_rect.width = width;
1579 child_rect.height = height;
1581 if (gdk_rectangle_intersect (rect, &child_rect, &new_rect))
1583 new_rect.x -= child_rect.x;
1584 new_rect.y -= child_rect.y;
1586 gdk_window_invalidate_rect ((GdkWindow *)child, &new_rect, TRUE);
1594 gdk_window_invalidate_region (GdkWindow *window,
1596 gboolean invalidate_children)
1598 GdkWindowObject *private = (GdkWindowObject *)window;
1600 g_return_if_fail (window != NULL);
1601 g_return_if_fail (GDK_IS_WINDOW (window));
1603 if (GDK_WINDOW_DESTROYED (window))
1606 if (private->input_only)
1609 if (private->update_area)
1611 gdk_region_union (private->update_area, region);
1615 update_windows = g_slist_prepend (update_windows, window);
1616 private->update_area = gdk_region_copy (region);
1618 if (!private->update_freeze_count && !update_idle)
1619 update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
1620 gdk_window_update_idle, NULL, NULL);
1623 if (invalidate_children)
1626 GdkRectangle child_rect;
1627 GdkRegion *child_region;
1629 tmp_list = private->children;
1632 GdkWindowObject *child = tmp_list->data;
1633 tmp_list = tmp_list->next;
1635 if (child->input_only)
1639 gdk_drawable_get_size (GDK_DRAWABLE (child),
1642 child_rect.x = child->x;
1643 child_rect.y = child->y;
1644 child_rect.width = width;
1645 child_rect.height = height;
1647 child_region = gdk_region_rectangle (&child_rect);
1648 gdk_region_intersect (child_region, region);
1650 if (!gdk_region_empty (child_region))
1652 gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
1653 gdk_window_invalidate_region ((GdkWindow *)child, child_region, TRUE);
1656 gdk_region_destroy (child_region);
1663 gdk_window_get_update_area (GdkWindow *window)
1665 GdkWindowObject *private = (GdkWindowObject *)window;
1666 GdkRegion *tmp_region;
1668 g_return_val_if_fail (window != NULL, NULL);
1669 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1671 if (private->update_area)
1673 tmp_region = private->update_area;
1674 private->update_area = NULL;
1676 update_windows = g_slist_remove (update_windows, window);
1685 * _gdk_window_clear_update_area:
1686 * @window: a #GdkWindow.
1688 * Internal function to clear the update area for a window. This
1689 * is called when the window is hidden or destroyed.
1692 _gdk_window_clear_update_area (GdkWindow *window)
1694 GdkWindowObject *private = (GdkWindowObject *)window;
1696 g_return_if_fail (window != NULL);
1697 g_return_if_fail (GDK_IS_WINDOW (window));
1699 if (private->update_area)
1701 update_windows = g_slist_remove (update_windows, window);
1703 gdk_region_destroy (private->update_area);
1704 private->update_area = NULL;
1709 gdk_window_freeze_updates (GdkWindow *window)
1711 GdkWindowObject *private = (GdkWindowObject *)window;
1713 g_return_if_fail (window != NULL);
1714 g_return_if_fail (GDK_IS_WINDOW (window));
1716 private->update_freeze_count++;
1720 gdk_window_thaw_updates (GdkWindow *window)
1722 GdkWindowObject *private = (GdkWindowObject *)window;
1724 g_return_if_fail (window != NULL);
1725 g_return_if_fail (GDK_IS_WINDOW (window));
1726 g_return_if_fail (private->update_freeze_count > 0);
1728 private->update_freeze_count--;
1729 if (!private->update_freeze_count && private->update_area && !update_idle)
1730 update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
1731 gdk_window_update_idle, NULL, NULL);