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 Lesser 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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-2000. 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;
177 window->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
181 gdk_window_class_init (GdkWindowObjectClass *klass)
183 GObjectClass *object_class = G_OBJECT_CLASS (klass);
184 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
186 parent_class = g_type_class_peek_parent (klass);
188 object_class->finalize = gdk_window_finalize;
190 drawable_class->create_gc = gdk_window_create_gc;
191 drawable_class->draw_rectangle = gdk_window_draw_rectangle;
192 drawable_class->draw_arc = gdk_window_draw_arc;
193 drawable_class->draw_polygon = gdk_window_draw_polygon;
194 drawable_class->draw_text = gdk_window_draw_text;
195 drawable_class->draw_text_wc = gdk_window_draw_text_wc;
196 drawable_class->draw_drawable = gdk_window_draw_drawable;
197 drawable_class->draw_points = gdk_window_draw_points;
198 drawable_class->draw_segments = gdk_window_draw_segments;
199 drawable_class->draw_lines = gdk_window_draw_lines;
200 drawable_class->draw_glyphs = gdk_window_draw_glyphs;
201 drawable_class->draw_image = gdk_window_draw_image;
202 drawable_class->get_depth = gdk_window_real_get_depth;
203 drawable_class->get_size = gdk_window_real_get_size;
204 drawable_class->set_colormap = gdk_window_real_set_colormap;
205 drawable_class->get_colormap = gdk_window_real_get_colormap;
206 drawable_class->get_visual = gdk_window_real_get_visual;
210 gdk_window_finalize (GObject *object)
212 GdkWindow *window = GDK_WINDOW (object);
213 GdkWindowObject *obj = (GdkWindowObject *) object;
215 if (!GDK_WINDOW_DESTROYED (window))
217 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
219 g_warning ("losing last reference to undestroyed window\n");
220 _gdk_window_destroy (window, FALSE);
223 /* We use TRUE here, to keep us from actually calling
224 * XDestroyWindow() on the window
226 _gdk_window_destroy (window, TRUE);
229 g_object_unref (G_OBJECT (obj->impl));
232 G_OBJECT_CLASS (parent_class)->finalize (object);
236 * _gdk_window_destroy_hierarchy:
237 * @window: a #GdkWindow
238 * @recursing: If TRUE, then this is being called because a parent
239 * was destroyed. This generally means that the call to the windowing system
240 * to destroy the window can be omitted, since it will be destroyed as a result
241 * of the parent being destroyed. Unless @foreign_destroy
243 * foreign_destroy: If TRUE, the window or a parent was destroyed by some external
244 * agency. The window has already been destroyed and no windowing
245 * system calls should be made. (This may never happen for some
246 * windowing systems.)
248 * Internal function to destroy a window. Like gdk_window_destroy(), but does not
249 * drop the reference count created by gdk_window_new().
252 _gdk_window_destroy_hierarchy (GdkWindow *window,
254 gboolean foreign_destroy)
256 GdkWindowObject *private;
257 GdkWindowObject *temp_private;
258 GdkWindow *temp_window;
262 g_return_if_fail (window != NULL);
264 private = (GdkWindowObject*) window;
266 switch (GDK_WINDOW_TYPE (window))
268 case GDK_WINDOW_TOPLEVEL:
269 case GDK_WINDOW_CHILD:
270 case GDK_WINDOW_DIALOG:
271 case GDK_WINDOW_TEMP:
272 case GDK_WINDOW_FOREIGN:
273 if (!GDK_WINDOW_DESTROYED (window))
275 private->mapped = FALSE;
276 private->destroyed = TRUE;
278 _gdk_windowing_window_destroy (window, recursing, foreign_destroy);
282 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
283 if (parent_private->children)
284 parent_private->children = g_list_remove (parent_private->children, window);
287 _gdk_window_clear_update_area (window);
288 gdk_window_free_paint_stack (window);
290 if (private->bg_pixmap &&
291 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
292 private->bg_pixmap != GDK_NO_BG)
294 gdk_pixmap_unref (private->bg_pixmap);
295 private->bg_pixmap = NULL;
298 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
300 children = tmp = private->children;
301 private->children = NULL;
305 temp_window = tmp->data;
308 temp_private = (GdkWindowObject*) temp_window;
310 _gdk_window_destroy_hierarchy (temp_window, TRUE, foreign_destroy);
313 g_list_free (children);
316 if (private->filters)
318 tmp = private->filters;
326 g_list_free (private->filters);
327 private->filters = NULL;
330 gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL);
334 case GDK_WINDOW_ROOT:
335 g_error ("attempted to destroy root window");
341 * _gdk_window_destroy:
342 * @window: a #GdkWindow
343 * foreign_destroy: If TRUE, the window or a parent was destroyed by some external
344 * agency. The window has already been destroyed and no windowing
345 * system calls should be made. (This may never happen for some
346 * windowing systems.)
348 * Internal function to destroy a window. Like gdk_window_destroy(), but does not
349 * drop the reference count created by gdk_window_new().
352 _gdk_window_destroy (GdkWindow *window,
353 gboolean foreign_destroy)
355 _gdk_window_destroy_hierarchy (window, FALSE, foreign_destroy);
359 gdk_window_destroy (GdkWindow *window)
361 _gdk_window_destroy_hierarchy (window, FALSE, FALSE);
362 gdk_drawable_unref (window);
366 gdk_window_set_user_data (GdkWindow *window,
369 g_return_if_fail (window != NULL);
371 ((GdkWindowObject*)window)->user_data = user_data;
375 gdk_window_get_user_data (GdkWindow *window,
378 g_return_if_fail (window != NULL);
380 *data = ((GdkWindowObject*)window)->user_data;
384 gdk_window_get_window_type (GdkWindow *window)
386 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
388 return GDK_WINDOW_TYPE (window);
392 gdk_window_get_position (GdkWindow *window,
396 GdkWindowObject *obj;
398 g_return_if_fail (GDK_IS_WINDOW (window));
400 obj = (GdkWindowObject*) window;
409 gdk_window_get_parent (GdkWindow *window)
411 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
413 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
417 gdk_window_get_toplevel (GdkWindow *window)
419 GdkWindowObject *obj;
421 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
423 obj = (GdkWindowObject *)window;
424 while (GDK_WINDOW_TYPE (obj) == GDK_WINDOW_CHILD)
425 obj = (GdkWindowObject *)obj->parent;
427 return GDK_WINDOW (obj);
431 gdk_window_get_children (GdkWindow *window)
433 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
435 if (GDK_WINDOW_DESTROYED (window))
438 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
442 gdk_window_peek_children (GdkWindow *window)
444 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
446 if (GDK_WINDOW_DESTROYED (window))
449 return GDK_WINDOW_OBJECT (window)->children;
453 gdk_window_add_filter (GdkWindow *window,
454 GdkFilterFunc function,
457 GdkWindowObject *private;
459 GdkEventFilter *filter;
461 g_return_if_fail (window != NULL);
462 g_return_if_fail (GDK_IS_WINDOW (window));
464 private = (GdkWindowObject*) window;
465 if (private && GDK_WINDOW_DESTROYED (window))
469 tmp_list = private->filters;
471 tmp_list = gdk_default_filters;
475 filter = (GdkEventFilter *)tmp_list->data;
476 if ((filter->function == function) && (filter->data == data))
478 tmp_list = tmp_list->next;
481 filter = g_new (GdkEventFilter, 1);
482 filter->function = function;
486 private->filters = g_list_append (private->filters, filter);
488 gdk_default_filters = g_list_append (gdk_default_filters, filter);
492 gdk_window_remove_filter (GdkWindow *window,
493 GdkFilterFunc function,
496 GdkWindowObject *private;
497 GList *tmp_list, *node;
498 GdkEventFilter *filter;
500 g_return_if_fail (window != NULL);
501 g_return_if_fail (GDK_IS_WINDOW (window));
503 private = (GdkWindowObject*) window;
506 tmp_list = private->filters;
508 tmp_list = gdk_default_filters;
512 filter = (GdkEventFilter *)tmp_list->data;
514 tmp_list = tmp_list->next;
516 if ((filter->function == function) && (filter->data == data))
519 private->filters = g_list_remove_link (private->filters, node);
521 gdk_default_filters = g_list_remove_link (gdk_default_filters, node);
522 g_list_free_1 (node);
531 gdk_window_get_toplevels (void)
533 GList *new_list = NULL;
536 tmp_list = ((GdkWindowObject *)gdk_parent_root)->children;
539 new_list = g_list_prepend (new_list, tmp_list->data);
540 tmp_list = tmp_list->next;
546 /*************************************************************
547 * gdk_window_is_visible:
548 * Check if the given window is mapped.
552 * is the window mapped
553 *************************************************************/
556 gdk_window_is_visible (GdkWindow *window)
558 GdkWindowObject *private = (GdkWindowObject *)window;
560 g_return_val_if_fail (window != NULL, FALSE);
561 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
563 return private->mapped;
566 /*************************************************************
567 * gdk_window_is_viewable:
568 * Check if the window and all ancestors of the window
569 * are mapped. (This is not necessarily "viewable" in
570 * the X sense, since we only check as far as we have
571 * GDK window parents, not to the root window)
575 * is the window viewable
576 *************************************************************/
579 gdk_window_is_viewable (GdkWindow *window)
581 GdkWindowObject *private = (GdkWindowObject *)window;
583 g_return_val_if_fail (window != NULL, FALSE);
584 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
587 (private != (GdkWindowObject *)gdk_parent_root) &&
588 (GDK_WINDOW_TYPE (private) != GDK_WINDOW_FOREIGN))
590 if (!private->mapped)
593 private = (GdkWindowObject *)private->parent;
600 gdk_window_begin_paint_rect (GdkWindow *window,
601 GdkRectangle *rectangle)
605 g_return_if_fail (window != NULL);
606 g_return_if_fail (GDK_IS_WINDOW (window));
608 region = gdk_region_rectangle (rectangle);
609 gdk_window_begin_paint_region (window, region);
610 gdk_region_destroy (region);
614 gdk_window_get_bg_gc (GdkWindow *window, GdkWindowPaint *paint)
616 GdkWindowObject *private = (GdkWindowObject *)window;
619 GdkGCValues gc_values;
621 if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent)
623 GdkWindowPaint tmp_paint = *paint;
624 tmp_paint.x_offset += private->x;
625 tmp_paint.y_offset += private->y;
627 return gdk_window_get_bg_gc (GDK_WINDOW (private->parent), &tmp_paint);
629 else if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && private->bg_pixmap != GDK_NO_BG)
631 gc_values.fill = GDK_TILED;
632 gc_values.tile = private->bg_pixmap;
633 gc_values.ts_x_origin = - paint->x_offset;
634 gc_values.ts_y_origin = - paint->y_offset;
636 gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN;
640 gc_values.foreground = private->bg_color;
641 gc_mask = GDK_GC_FOREGROUND;
644 return gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask);
648 gdk_window_paint_init_bg (GdkWindow *window,
649 GdkWindowPaint *paint,
650 GdkRegion *init_region)
654 tmp_gc = gdk_window_get_bg_gc (window, paint);
655 gdk_draw_rectangle (paint->pixmap, tmp_gc, TRUE, 0, 0, -1, -1);
656 gdk_gc_unref (tmp_gc);
660 gdk_window_begin_paint_region (GdkWindow *window,
663 #ifdef USE_BACKING_STORE
664 GdkWindowObject *private = (GdkWindowObject *)window;
665 GdkRectangle clip_box;
666 GdkWindowPaint *paint;
667 GdkRegion *init_region;
670 g_return_if_fail (window != NULL);
671 g_return_if_fail (GDK_IS_WINDOW (window));
673 if (GDK_WINDOW_DESTROYED (window))
676 paint = g_new (GdkWindowPaint, 1);
678 paint->region = gdk_region_copy (region);
680 init_region = gdk_region_copy (region);
681 gdk_region_get_clipbox (paint->region, &clip_box);
683 if (private->paint_stack)
685 gint old_width, old_height;
686 GdkWindowPaint *tmp_paint = private->paint_stack->data;
687 GdkRectangle old_rect, new_rect;
690 gdk_drawable_get_size (tmp_paint->pixmap, &old_width, &old_height);
691 old_rect.x = tmp_paint->x_offset;
692 old_rect.y = tmp_paint->y_offset;
693 old_rect.width = old_width;
694 old_rect.height = old_height;
696 gdk_rectangle_union (&clip_box, &old_rect, &new_rect);
698 if (new_rect.width > old_rect.width || new_rect.height > old_rect.height)
700 paint->pixmap = gdk_pixmap_new (window, new_rect.width, new_rect.height, -1);
701 tmp_gc = gdk_gc_new (paint->pixmap);
702 gdk_draw_drawable (paint->pixmap, tmp_gc, tmp_paint->pixmap,
703 0, 0, old_rect.width, old_rect.height,
704 old_rect.x - new_rect.x, old_rect.y - new_rect.y);
705 gdk_gc_unref (tmp_gc);
706 gdk_drawable_unref (tmp_paint->pixmap);
708 paint->x_offset = new_rect.x;
709 paint->y_offset = new_rect.y;
711 tmp_list = private->paint_stack;
714 tmp_paint = private->paint_stack->data;
715 gdk_region_subtract (init_region, tmp_paint->region);
717 tmp_paint->pixmap = paint->pixmap;
718 tmp_paint->x_offset = paint->x_offset;
719 tmp_paint->y_offset = paint->x_offset;
721 tmp_list = tmp_list->next;
726 paint->x_offset = tmp_paint->x_offset;
727 paint->y_offset = tmp_paint->y_offset;
728 paint->pixmap = tmp_paint->pixmap;
730 tmp_list = private->paint_stack;
733 tmp_paint = private->paint_stack->data;
734 gdk_region_subtract (init_region, tmp_paint->region);
736 tmp_list = tmp_list->next;
742 paint->x_offset = clip_box.x;
743 paint->y_offset = clip_box.y;
744 paint->pixmap = gdk_pixmap_new (window, clip_box.width, clip_box.height, -1);
747 if (!gdk_region_empty (init_region))
748 gdk_window_paint_init_bg (window, paint, init_region);
749 gdk_region_destroy (init_region);
751 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
752 #endif /* USE_BACKING_STORE */
756 gdk_window_end_paint (GdkWindow *window)
758 #ifdef USE_BACKING_STORE
759 GdkWindowObject *private = (GdkWindowObject *)window;
760 GdkWindowPaint *paint;
762 GdkRectangle clip_box;
763 gint x_offset, y_offset;
765 g_return_if_fail (window != NULL);
766 g_return_if_fail (GDK_IS_WINDOW (window));
768 if (GDK_WINDOW_DESTROYED (window))
771 g_return_if_fail (private->paint_stack != NULL);
773 paint = private->paint_stack->data;
774 private->paint_stack = g_slist_delete_link (private->paint_stack, private->paint_stack);
776 gdk_region_get_clipbox (paint->region, &clip_box);
778 tmp_gc = gdk_gc_new (window);
780 _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset);
782 gdk_gc_set_clip_region (tmp_gc, paint->region);
783 gdk_gc_set_clip_origin (tmp_gc, -x_offset, -y_offset);
785 gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap,
786 clip_box.x - paint->x_offset,
787 clip_box.y - paint->y_offset,
788 clip_box.x - x_offset, clip_box.y - y_offset,
789 clip_box.width, clip_box.height);
790 gdk_gc_unref (tmp_gc);
792 if (private->paint_stack)
794 GSList *tmp_list = private->paint_stack;
797 GdkWindowPaint *tmp_paint = tmp_list->data;
798 gdk_region_subtract (tmp_paint->region, paint->region);
800 tmp_list = tmp_list->next;
804 gdk_drawable_unref (paint->pixmap);
806 gdk_region_destroy (paint->region);
808 #endif /* USE_BACKING_STORE */
812 gdk_window_free_paint_stack (GdkWindow *window)
814 GdkWindowObject *private = (GdkWindowObject *)window;
816 if (private->paint_stack)
818 GSList *tmp_list = private->paint_stack;
822 GdkWindowPaint *paint = tmp_list->data;
824 if (tmp_list == private->paint_stack)
825 gdk_drawable_unref (paint->pixmap);
827 gdk_region_destroy (paint->region);
830 tmp_list = tmp_list->next;
833 g_slist_free (private->paint_stack);
834 private->paint_stack = NULL;
839 gdk_window_get_offsets (GdkWindow *window,
843 GdkWindowObject *private = (GdkWindowObject *)window;
845 if (private->paint_stack)
847 GdkWindowPaint *paint = private->paint_stack->data;
848 *x_offset = paint->x_offset;
849 *y_offset = paint->y_offset;
852 _gdk_windowing_window_get_offsets (window, x_offset, y_offset);
855 #define OFFSET_GC(gc) \
856 gint x_offset, y_offset; \
857 gint old_clip_x = gc->clip_x_origin; \
858 gint old_clip_y = gc->clip_y_origin; \
859 gint old_ts_x = gc->ts_x_origin; \
860 gint old_ts_y = gc->ts_y_origin; \
861 gdk_window_get_offsets (drawable, &x_offset, &y_offset); \
862 if (x_offset != 0 || y_offset != 0) \
864 gdk_gc_set_clip_origin (gc, old_clip_x - x_offset, \
865 old_clip_y - y_offset); \
866 gdk_gc_set_ts_origin (gc, old_ts_x - x_offset, \
867 old_ts_y - y_offset); \
870 #define RESTORE_GC(gc) \
871 if (x_offset != 0 || y_offset != 0) \
873 gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \
874 gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y); \
878 gdk_window_create_gc (GdkDrawable *drawable,
880 GdkGCValuesMask mask)
882 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
884 if (GDK_WINDOW_DESTROYED (drawable))
887 return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl,
892 gdk_window_draw_rectangle (GdkDrawable *drawable,
900 GdkWindowObject *private = (GdkWindowObject *)drawable;
903 if (GDK_WINDOW_DESTROYED (drawable))
906 if (private->paint_stack)
908 GdkWindowPaint *paint = private->paint_stack->data;
909 gdk_draw_rectangle (paint->pixmap, gc, filled,
910 x - x_offset, y - y_offset, width, height);
913 gdk_draw_rectangle (private->impl, gc, filled,
914 x - x_offset, y - y_offset, width, height);
920 gdk_window_draw_arc (GdkDrawable *drawable,
930 GdkWindowObject *private = (GdkWindowObject *)drawable;
933 if (GDK_WINDOW_DESTROYED (drawable))
936 if (private->paint_stack)
938 GdkWindowPaint *paint = private->paint_stack->data;
939 gdk_draw_arc (paint->pixmap, gc, filled,
940 x - x_offset, y_offset,
941 width, height, angle1, angle2);
944 gdk_draw_arc (private->impl, gc, filled,
945 x - x_offset, y - y_offset,
946 width, height, angle1, angle2);
951 gdk_window_draw_polygon (GdkDrawable *drawable,
957 GdkWindowObject *private = (GdkWindowObject *)drawable;
958 GdkPoint *new_points;
962 if (GDK_WINDOW_DESTROYED (drawable))
965 if (x_offset != 0 || y_offset != 0)
969 new_points = g_new (GdkPoint, npoints);
970 for (i=0; i<npoints; i++)
972 new_points[i].x = points[i].x - x_offset;
973 new_points[i].y = points[i].y - y_offset;
979 if (private->paint_stack)
981 GdkWindowPaint *paint = private->paint_stack->data;
982 gdk_draw_polygon (paint->pixmap, gc, filled, new_points, npoints);
986 gdk_draw_polygon (private->impl, gc, filled, new_points, npoints);
988 if (new_points != points)
995 gdk_window_draw_text (GdkDrawable *drawable,
1003 GdkWindowObject *private = (GdkWindowObject *)drawable;
1006 if (GDK_WINDOW_DESTROYED (drawable))
1009 if (private->paint_stack)
1011 GdkWindowPaint *paint = private->paint_stack->data;
1012 gdk_draw_text (paint->pixmap, font, gc,
1013 x - x_offset, y - y_offset, text, text_length);
1017 gdk_draw_text (private->impl, font, gc,
1018 x - x_offset, y - y_offset, text, text_length);
1024 gdk_window_draw_text_wc (GdkDrawable *drawable,
1029 const GdkWChar *text,
1032 GdkWindowObject *private = (GdkWindowObject *)drawable;
1035 if (GDK_WINDOW_DESTROYED (drawable))
1038 if (private->paint_stack)
1040 GdkWindowPaint *paint = private->paint_stack->data;
1041 gdk_draw_text_wc (paint->pixmap, font, gc,
1042 x - x_offset, y - y_offset, text, text_length);
1045 gdk_draw_text_wc (private->impl, font, gc,
1046 x - x_offset, y - y_offset, text, text_length);
1052 gdk_window_draw_drawable (GdkDrawable *drawable,
1062 GdkWindowObject *private = (GdkWindowObject *)drawable;
1065 if (GDK_WINDOW_DESTROYED (drawable))
1068 if (private->paint_stack)
1070 GdkWindowPaint *paint = private->paint_stack->data;
1071 gdk_draw_drawable (paint->pixmap, gc, src, xsrc, ysrc,
1072 xdest - x_offset, ydest - y_offset, width, height);
1076 gdk_draw_drawable (private->impl, gc, src, xsrc, ysrc,
1077 xdest - x_offset, ydest - y_offset,
1083 gdk_window_draw_points (GdkDrawable *drawable,
1088 GdkWindowObject *private = (GdkWindowObject *)drawable;
1089 GdkPoint *new_points;
1093 if (GDK_WINDOW_DESTROYED (drawable))
1096 if (x_offset != 0 || y_offset != 0)
1100 new_points = g_new (GdkPoint, npoints);
1101 for (i=0; i<npoints; i++)
1103 new_points[i].x = points[i].x - x_offset;
1104 new_points[i].y = points[i].y - y_offset;
1108 new_points = points;
1110 if (private->paint_stack)
1112 GdkWindowPaint *paint = private->paint_stack->data;
1113 gdk_draw_points (paint->pixmap, gc, new_points, npoints);
1116 gdk_draw_points (private->impl, gc, points, npoints);
1118 if (new_points != points)
1119 g_free (new_points);
1125 gdk_window_draw_segments (GdkDrawable *drawable,
1130 GdkWindowObject *private = (GdkWindowObject *)drawable;
1131 GdkSegment *new_segs;
1135 if (GDK_WINDOW_DESTROYED (drawable))
1138 if (x_offset != 0 || y_offset != 0)
1142 new_segs = g_new (GdkSegment, nsegs);
1143 for (i=0; i<nsegs; i++)
1145 new_segs[i].x1 = segs[i].x1 - x_offset;
1146 new_segs[i].y1 = segs[i].y1 - y_offset;
1147 new_segs[i].x2 = segs[i].x2 - x_offset;
1148 new_segs[i].y2 = segs[i].y2 - y_offset;
1154 if (private->paint_stack)
1156 GdkWindowPaint *paint = private->paint_stack->data;
1157 gdk_draw_segments (paint->pixmap, gc, new_segs, nsegs);
1160 gdk_draw_segments (private->impl, gc, new_segs, nsegs);
1162 if (new_segs != segs)
1169 gdk_window_draw_lines (GdkDrawable *drawable,
1174 GdkWindowObject *private = (GdkWindowObject *)drawable;
1175 GdkPoint *new_points;
1179 if (GDK_WINDOW_DESTROYED (drawable))
1182 if (x_offset != 0 || y_offset != 0)
1186 new_points = g_new (GdkPoint, npoints);
1187 for (i=0; i<npoints; i++)
1189 new_points[i].x = points[i].x - x_offset;
1190 new_points[i].y = points[i].y - y_offset;
1194 new_points = points;
1196 if (private->paint_stack)
1198 GdkWindowPaint *paint = private->paint_stack->data;
1199 gdk_draw_lines (paint->pixmap, gc, new_points, npoints);
1202 gdk_draw_lines (private->impl, gc, new_points, npoints);
1204 if (new_points != points)
1205 g_free (new_points);
1211 gdk_window_draw_glyphs (GdkDrawable *drawable,
1216 PangoGlyphString *glyphs)
1218 GdkWindowObject *private = (GdkWindowObject *)drawable;
1222 if (GDK_WINDOW_DESTROYED (drawable))
1225 if (private->paint_stack)
1227 GdkWindowPaint *paint = private->paint_stack->data;
1229 gdk_draw_glyphs (paint->pixmap, gc, font, x - x_offset, y - y_offset, glyphs);
1232 gdk_draw_glyphs (private->impl, gc, font,
1233 x - x_offset, y - y_offset, glyphs);
1238 /* Fixme - this is just like gdk_window_paint_init_bg */
1240 gdk_window_clear_backing_rect (GdkWindow *window,
1246 GdkWindowObject *private = (GdkWindowObject *)window;
1247 GdkWindowPaint *paint = private->paint_stack->data;
1250 if (GDK_WINDOW_DESTROYED (window))
1253 tmp_gc = gdk_window_get_bg_gc (window, paint);
1254 gdk_draw_rectangle (paint->pixmap, tmp_gc, TRUE,
1255 x - paint->x_offset, y - paint->y_offset, width, height);
1256 gdk_gc_unref (tmp_gc);
1260 gdk_window_clear (GdkWindow *window)
1264 g_return_if_fail (window != NULL);
1265 g_return_if_fail (GDK_IS_WINDOW (window));
1267 gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
1269 gdk_window_clear_area (window, 0, 0,
1274 gdk_window_clear_area (GdkWindow *window,
1280 GdkWindowObject *private = (GdkWindowObject *)window;
1282 g_return_if_fail (window != NULL);
1283 g_return_if_fail (GDK_IS_WINDOW (window));
1285 if (private->paint_stack)
1286 gdk_window_clear_backing_rect (window, x, y, width, height);
1288 _gdk_windowing_window_clear_area (window, x, y, width, height);
1292 gdk_window_clear_area_e (GdkWindow *window,
1298 GdkWindowObject *private = (GdkWindowObject *)window;
1300 g_return_if_fail (window != NULL);
1301 g_return_if_fail (GDK_IS_WINDOW (window));
1303 if (private->paint_stack)
1304 gdk_window_clear_backing_rect (window, x, y, width, height);
1306 _gdk_windowing_window_clear_area_e (window, x, y, width, height);
1310 gdk_window_draw_image (GdkDrawable *drawable,
1320 GdkWindowObject *private = (GdkWindowObject *)drawable;
1324 if (GDK_WINDOW_DESTROYED (drawable))
1327 if (private->paint_stack)
1329 GdkWindowPaint *paint = private->paint_stack->data;
1330 gdk_draw_image (paint->pixmap, gc, image, xsrc, ysrc,
1331 xdest - x_offset, ydest - y_offset,
1336 gdk_draw_image (private->impl, gc, image, xsrc, ysrc,
1337 xdest - x_offset, ydest - y_offset,
1345 gdk_window_real_get_size (GdkDrawable *drawable,
1349 g_return_if_fail (GDK_IS_WINDOW (drawable));
1351 gdk_drawable_get_size (GDK_WINDOW_OBJECT (drawable)->impl,
1356 gdk_window_real_get_visual (GdkDrawable *drawable)
1358 GdkColormap *colormap;
1360 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
1362 colormap = gdk_drawable_get_colormap (drawable);
1363 return colormap ? gdk_colormap_get_visual (colormap) : NULL;
1367 gdk_window_real_get_depth (GdkDrawable *drawable)
1371 g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0);
1373 depth = ((GdkWindowObject *)GDK_WINDOW (drawable))->depth;
1377 g_print ("0 depth for type %s\n", g_type_name (G_OBJECT_TYPE (drawable)));
1385 gdk_window_real_set_colormap (GdkDrawable *drawable,
1388 g_return_if_fail (GDK_IS_WINDOW (drawable));
1390 if (GDK_WINDOW_DESTROYED (drawable))
1393 gdk_drawable_set_colormap (((GdkWindowObject*)drawable)->impl, cmap);
1397 gdk_window_real_get_colormap (GdkDrawable *drawable)
1399 g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL);
1401 if (GDK_WINDOW_DESTROYED (drawable))
1404 return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl);
1407 /* Code for dirty-region queueing
1410 static GSList *update_windows = NULL;
1411 static guint update_idle = 0;
1414 gdk_window_process_updates_internal (GdkWindow *window)
1416 GdkWindowObject *private = (GdkWindowObject *)window;
1417 gboolean save_region = FALSE;
1419 /* If an update got queued during update processing, we can get a
1420 * window in the update queue that has an empty update_area.
1423 if (private->update_area)
1425 GdkRegion *update_area = private->update_area;
1426 private->update_area = NULL;
1428 if (gdk_event_func && gdk_window_is_viewable (window))
1431 GdkRectangle window_rect;
1434 gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
1438 window_rect.width = width;
1439 window_rect.height = height;
1441 save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
1443 event.expose.type = GDK_EXPOSE;
1444 event.expose.window = gdk_window_ref (window);
1445 event.expose.count = 0;
1447 gdk_region_get_clipbox (update_area, &event.expose.area);
1448 if (gdk_rectangle_intersect (&event.expose.area, &window_rect, &event.expose.area))
1450 (*gdk_event_func) (&event, gdk_event_data);
1453 gdk_window_unref (window);
1457 gdk_region_destroy (update_area);
1462 gdk_window_process_all_updates (void)
1464 GSList *old_update_windows = update_windows;
1465 GSList *tmp_list = update_windows;
1468 g_source_remove (update_idle);
1470 update_windows = NULL;
1475 gdk_window_process_updates_internal (tmp_list->data);
1476 tmp_list = tmp_list->next;
1479 g_slist_free (old_update_windows);
1485 gdk_window_update_idle (gpointer data)
1487 gdk_window_process_all_updates ();
1493 gdk_window_process_updates (GdkWindow *window,
1494 gboolean update_children)
1496 GdkWindowObject *private = (GdkWindowObject *)window;
1498 g_return_if_fail (window != NULL);
1499 g_return_if_fail (GDK_IS_WINDOW (window));
1501 if (private->update_area)
1503 gdk_window_process_updates_internal (window);
1504 update_windows = g_slist_remove (update_windows, window);
1507 if (update_children)
1509 GList *tmp_list = private->children;
1512 gdk_window_process_updates (tmp_list->data, TRUE);
1513 tmp_list = tmp_list->next;
1519 gdk_window_invalidate_rect (GdkWindow *window,
1521 gboolean invalidate_children)
1523 GdkRectangle window_rect;
1524 GdkWindowObject *private = (GdkWindowObject *)window;
1526 g_return_if_fail (window != NULL);
1527 g_return_if_fail (GDK_IS_WINDOW (window));
1529 if (GDK_WINDOW_DESTROYED (window))
1532 if (private->input_only || !private->mapped)
1539 gdk_drawable_get_size (GDK_DRAWABLE (window),
1541 &window_rect.height);
1542 rect = &window_rect;
1545 if (private->update_area)
1547 gdk_region_union_with_rect (private->update_area, rect);
1551 update_windows = g_slist_prepend (update_windows, window);
1552 private->update_area = gdk_region_rectangle (rect);
1554 if (!private->update_freeze_count && !update_idle)
1555 update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
1556 gdk_window_update_idle, NULL, NULL);
1560 if (invalidate_children)
1563 GdkRectangle child_rect, new_rect;
1565 tmp_list = private->children;
1568 GdkWindowObject *child = tmp_list->data;
1569 tmp_list = tmp_list->next;
1571 if (!child->input_only)
1575 gdk_drawable_get_size (GDK_DRAWABLE (child),
1578 child_rect.x = child->x;
1579 child_rect.y = child->y;
1580 child_rect.width = width;
1581 child_rect.height = height;
1583 if (gdk_rectangle_intersect (rect, &child_rect, &new_rect))
1585 new_rect.x -= child_rect.x;
1586 new_rect.y -= child_rect.y;
1588 gdk_window_invalidate_rect ((GdkWindow *)child, &new_rect, TRUE);
1596 gdk_window_invalidate_region (GdkWindow *window,
1598 gboolean invalidate_children)
1600 GdkWindowObject *private = (GdkWindowObject *)window;
1602 g_return_if_fail (window != NULL);
1603 g_return_if_fail (GDK_IS_WINDOW (window));
1605 if (GDK_WINDOW_DESTROYED (window))
1608 if (private->input_only || !private->mapped)
1611 if (private->update_area)
1613 gdk_region_union (private->update_area, region);
1617 update_windows = g_slist_prepend (update_windows, window);
1618 private->update_area = gdk_region_copy (region);
1620 if (!private->update_freeze_count && !update_idle)
1621 update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
1622 gdk_window_update_idle, NULL, NULL);
1625 if (invalidate_children)
1628 GdkRectangle child_rect;
1629 GdkRegion *child_region;
1631 tmp_list = private->children;
1634 GdkWindowObject *child = tmp_list->data;
1635 tmp_list = tmp_list->next;
1637 if (!child->input_only)
1641 gdk_drawable_get_size (GDK_DRAWABLE (child),
1644 child_rect.x = child->x;
1645 child_rect.y = child->y;
1646 child_rect.width = width;
1647 child_rect.height = height;
1649 child_region = gdk_region_rectangle (&child_rect);
1650 gdk_region_intersect (child_region, region);
1652 if (!gdk_region_empty (child_region))
1654 gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
1655 gdk_window_invalidate_region ((GdkWindow *)child, child_region, TRUE);
1658 gdk_region_destroy (child_region);
1665 gdk_window_get_update_area (GdkWindow *window)
1667 GdkWindowObject *private = (GdkWindowObject *)window;
1668 GdkRegion *tmp_region;
1670 g_return_val_if_fail (window != NULL, NULL);
1671 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1673 if (private->update_area)
1675 tmp_region = private->update_area;
1676 private->update_area = NULL;
1678 update_windows = g_slist_remove (update_windows, window);
1687 * _gdk_window_clear_update_area:
1688 * @window: a #GdkWindow.
1690 * Internal function to clear the update area for a window. This
1691 * is called when the window is hidden or destroyed.
1694 _gdk_window_clear_update_area (GdkWindow *window)
1696 GdkWindowObject *private = (GdkWindowObject *)window;
1698 g_return_if_fail (window != NULL);
1699 g_return_if_fail (GDK_IS_WINDOW (window));
1701 if (private->update_area)
1703 update_windows = g_slist_remove (update_windows, window);
1705 gdk_region_destroy (private->update_area);
1706 private->update_area = NULL;
1711 gdk_window_freeze_updates (GdkWindow *window)
1713 GdkWindowObject *private = (GdkWindowObject *)window;
1715 g_return_if_fail (window != NULL);
1716 g_return_if_fail (GDK_IS_WINDOW (window));
1718 private->update_freeze_count++;
1722 gdk_window_thaw_updates (GdkWindow *window)
1724 GdkWindowObject *private = (GdkWindowObject *)window;
1726 g_return_if_fail (window != NULL);
1727 g_return_if_fail (GDK_IS_WINDOW (window));
1728 g_return_if_fail (private->update_freeze_count > 0);
1730 private->update_freeze_count--;
1731 if (!private->update_freeze_count && private->update_area && !update_idle)
1732 update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
1733 gdk_window_update_idle, NULL, NULL);