? - ? .xvpics ? gtk-fade-in-2001-12-10.diff ? gtk-fade-in-2001-12-10b.diff ? gtk-fade-in-2001-12-10c.diff ? gtk-fade-in-2001-12-10d.diff ? gtk-fade-in.diff ? gtk-fade-in.png Index: ChangeLog =================================================================== RCS file: /cvs/gnome/gtk+/ChangeLog,v retrieving revision 1.2687 diff -u -p -r1.2687 ChangeLog --- ChangeLog 2001/12/10 03:43:04 1.2687 +++ ChangeLog 2001/12/10 06:37:05 @@ -55,7 +55,6 @@ Sat Dec 8 20:57:24 2001 Kristian Rietv * gtk/gtkliststore.c (gtk_list_store_remove): nuke the stamp++, per jrb's request ->>>>>>> 1.2684 2001-12-08 Anders Carlsson * tests/testgtk.c (layout_expose_handler): Don't return TRUE Index: gdk/gdkdraw.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkdraw.c,v retrieving revision 1.28 diff -u -p -r1.28 gdkdraw.c --- gdk/gdkdraw.c 2001/10/03 18:19:45 1.28 +++ gdk/gdkdraw.c 2001/12/10 06:37:05 @@ -26,7 +26,10 @@ #include "gdkdrawable.h" #include "gdkinternals.h" +#include "gdkpixmap.h" #include "gdkwindow.h" +#include "gdk-pixbuf-private.h" +#include "gdkpixbuf.h" static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable, gint x, @@ -35,6 +38,14 @@ static GdkDrawable* gdk_drawable_real_ge gint height, gint *composite_x_offset, gint *composite_y_offset); +void gdk_real_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint dest_x, + gint dest_y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride); static GdkRegion * gdk_drawable_real_get_visible_region (GdkDrawable *drawable); static void gdk_drawable_class_init (GdkDrawableClass *klass); @@ -74,6 +85,7 @@ gdk_drawable_class_init (GdkDrawableClas /* Default implementation for clip and visible region is the same */ klass->get_clip_region = gdk_drawable_real_get_visible_region; klass->get_visible_region = gdk_drawable_real_get_visible_region; + klass->draw_rgba_image = gdk_real_draw_rgba_image; } /* Manipulation of drawables @@ -775,4 +787,149 @@ gdk_drawable_real_get_visible_region (Gd gdk_drawable_get_size (drawable, &rect.width, &rect.height); return gdk_region_rectangle (&rect); +} + +void +gdk_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (rgb_buf != 0); + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_rgba_image (drawable, gc, + x, y, width, height, + rgb_buf, rowstride); +} + +void +gdk_real_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint dest_x, + gint dest_y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride) +{ + GdkBitmap *bitmap = NULL; + GdkPixbuf *composited = NULL; + gint dwidth, dheight; + GdkRegion *clip; + GdkRegion *drect; + GdkRectangle tmp_rect; + GdkPixbufAlphaMode alpha_mode = GDK_PIXBUF_ALPHA_FULL; + gint alpha_threshold = 0x80; + gint x_dither = 0; + gint y_dither = 0; + GdkRgbDither dither = GDK_RGB_DITHER_NORMAL; + gint src_x = 0; + gint src_y = 0; + + /* Clip to the drawable; this is required for get_from_drawable() so + * can't be done implicitly + */ + + if (dest_x < 0) + { + src_x -= dest_x; + width += dest_x; + dest_x = 0; + } + + if (dest_y < 0) + { + src_y -= dest_y; + height += dest_y; + dest_y = 0; + } + + gdk_drawable_get_size (drawable, &dwidth, &dheight); + + if ((dest_x + width) > dwidth) + width = dwidth - dest_x; + + if ((dest_y + height) > dheight) + height = dheight - dest_y; + + if (width <= 0 || height <= 0) + return; + + /* Clip to the clip region; this avoids getting more + * image data from the server than we need to. + */ + + tmp_rect.x = dest_x; + tmp_rect.y = dest_y; + tmp_rect.width = width; + tmp_rect.height = height; + + drect = gdk_region_rectangle (&tmp_rect); + clip = gdk_drawable_get_clip_region (drawable); + + gdk_region_intersect (drect, clip); + + gdk_region_get_clipbox (drect, &tmp_rect); + + gdk_region_destroy (drect); + gdk_region_destroy (clip); + + if (tmp_rect.width == 0 || + tmp_rect.height == 0) + return; + + /* Actually draw */ + + if (alpha_mode == GDK_PIXBUF_ALPHA_FULL) + { + composited = gdk_pixbuf_get_from_drawable (NULL, + drawable, + NULL, + dest_x, dest_y, + 0, 0, + width, height); + + if (composited) + { + guchar *subbuf = rgb_buf + src_y * rowstride + src_x * 4; + GdkPixbuf *sub = gdk_pixbuf_new_from_data (subbuf, GDK_COLORSPACE_RGB, + TRUE, 8, width, height, + rowstride, NULL, NULL); + + gdk_pixbuf_composite (sub, + composited, + 0, 0, + width, height, + 0, 0, + 1.0, 1.0, + GDK_INTERP_BILINEAR, + 255); + + g_object_unref (G_OBJECT (sub)); + } + } + + if (composited) + { + gdk_pixbuf_render_to_drawable (composited, + drawable, gc, + 0, 0, + dest_x, dest_y, + width, height, + dither, + x_dither, y_dither); + } + + if (bitmap) + gdk_bitmap_unref (bitmap); + + if (composited) + g_object_unref (G_OBJECT (composited)); + } Index: gdk/gdkdrawable.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkdrawable.h,v retrieving revision 1.17 diff -u -p -r1.17 gdkdrawable.h --- gdk/gdkdrawable.h 2001/11/30 22:55:27 1.17 +++ gdk/gdkdrawable.h 2001/12/10 06:37:05 @@ -130,7 +130,15 @@ struct _GdkDrawableClass gint height, gint *composite_x_offset, gint *composite_y_offset); - + void (*draw_rgba_image) (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride); + void (*_gdk_reserved1) (void); void (*_gdk_reserved2) (void); void (*_gdk_reserved3) (void); @@ -240,6 +248,14 @@ void gdk_draw_image (GdkDrawable gint ydest, gint width, gint height); +void gdk_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride); void gdk_draw_points (GdkDrawable *drawable, GdkGC *gc, GdkPoint *points, Index: gdk/gdkinternals.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkinternals.h,v retrieving revision 1.12 diff -u -p -r1.12 gdkinternals.h --- gdk/gdkinternals.h 2001/11/18 02:15:48 1.12 +++ gdk/gdkinternals.h 2001/12/10 06:37:05 @@ -231,6 +231,26 @@ void _gdk_windowing_window_destroy (GdkW gboolean recursing, gboolean foreign_destroy); +void _gdk_windowing_window_show_unraised (GdkWindow *window); +void _gdk_windowing_window_hide (GdkWindow *window); +void _gdk_windowing_window_move (GdkWindow *window, + gint x, + gint y); +void _gdk_windowing_window_resize (GdkWindow *window, + gint width, + gint height); +void _gdk_windowing_window_move_resize (GdkWindow *window, + gint x, + gint y, + gint width, + gint height); +void _gdk_windowing_window_raise (GdkWindow *window); +void _gdk_windowing_window_lower (GdkWindow *window); +void _gdk_windowing_window_scroll (GdkWindow *window, + gint dx, + gint dy); + + /* Implementation types */ GType _gdk_window_impl_get_type (void) G_GNUC_CONST; GType _gdk_pixmap_impl_get_type (void) G_GNUC_CONST; Index: gdk/gdkpixbuf-render.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkpixbuf-render.c,v retrieving revision 1.25 diff -u -p -r1.25 gdkpixbuf-render.c --- gdk/gdkpixbuf-render.c 2001/09/19 20:13:16 1.25 +++ gdk/gdkpixbuf-render.c 2001/12/10 06:37:05 @@ -273,13 +273,7 @@ gdk_pixbuf_render_to_drawable_alpha (Gdk GdkRgbDither dither, int x_dither, int y_dither) { - GdkBitmap *bitmap = NULL; GdkGC *gc; - GdkPixbuf *composited = NULL; - gint dwidth, dheight; - GdkRegion *clip; - GdkRegion *drect; - GdkRectangle tmp_rect; g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB); @@ -297,123 +291,14 @@ gdk_pixbuf_render_to_drawable_alpha (Gdk g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width); g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height); - /* Clip to the drawable; this is required for get_from_drawable() so - * can't be done implicitly - */ - - if (dest_x < 0) - { - src_x -= dest_x; - width += dest_x; - dest_x = 0; - } - - if (dest_y < 0) - { - src_y -= dest_y; - height += dest_y; - dest_y = 0; - } - - gdk_drawable_get_size (drawable, &dwidth, &dheight); - - if ((dest_x + width) > dwidth) - width = dwidth - dest_x; - - if ((dest_y + height) > dheight) - height = dheight - dest_y; - - if (width <= 0 || height <= 0) - return; - - /* Clip to the clip region; this avoids getting more - * image data from the server than we need to. - */ - - tmp_rect.x = dest_x; - tmp_rect.y = dest_y; - tmp_rect.width = width; - tmp_rect.height = height; - - drect = gdk_region_rectangle (&tmp_rect); - clip = gdk_drawable_get_clip_region (drawable); - - gdk_region_intersect (drect, clip); - - gdk_region_get_clipbox (drect, &tmp_rect); - - gdk_region_destroy (drect); - gdk_region_destroy (clip); - - if (tmp_rect.width == 0 || - tmp_rect.height == 0) - return; - - /* Actually draw */ - gc = gdk_gc_new (drawable); if (pixbuf->has_alpha) { - if (alpha_mode == GDK_PIXBUF_ALPHA_FULL) - { - GdkPixbuf *sub = NULL; - - composited = gdk_pixbuf_get_from_drawable (NULL, - drawable, - NULL, - dest_x, dest_y, - 0, 0, - width, height); - - if (composited) - { - if (src_x != 0 || src_y != 0) - { - sub = gdk_pixbuf_new_subpixbuf (pixbuf, src_x, src_y, - width, height); - } - - gdk_pixbuf_composite (sub ? sub : pixbuf, - composited, - 0, 0, - width, height, - 0, 0, - 1.0, 1.0, - GDK_INTERP_BILINEAR, - 255); - - if (sub) - g_object_unref (G_OBJECT (sub)); - } - else - alpha_mode = GDK_PIXBUF_ALPHA_BILEVEL; /* fall back */ - } - - if (alpha_mode == GDK_PIXBUF_ALPHA_BILEVEL) - { - bitmap = gdk_pixmap_new (NULL, width, height, 1); - gdk_pixbuf_render_threshold_alpha (pixbuf, bitmap, - src_x, src_y, - 0, 0, - width, height, - alpha_threshold); - - gdk_gc_set_clip_mask (gc, bitmap); - gdk_gc_set_clip_origin (gc, dest_x, dest_y); - } + char *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4; + gdk_draw_rgba_image (drawable, gc, dest_x, dest_y, width, height, + buf, pixbuf->rowstride); } - - if (composited) - { - gdk_pixbuf_render_to_drawable (composited, - drawable, gc, - 0, 0, - dest_x, dest_y, - width, height, - dither, - x_dither, y_dither); - } else { gdk_pixbuf_render_to_drawable (pixbuf, @@ -424,14 +309,9 @@ gdk_pixbuf_render_to_drawable_alpha (Gdk dither, x_dither, y_dither); } - - if (bitmap) - gdk_bitmap_unref (bitmap); - - if (composited) - g_object_unref (G_OBJECT (composited)); - + gdk_gc_unref (gc); + } /** Index: gdk/gdkpixmap.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkpixmap.c,v retrieving revision 1.38 diff -u -p -r1.38 gdkpixmap.c --- gdk/gdkpixmap.c 2001/02/23 13:35:16 1.38 +++ gdk/gdkpixmap.c 2001/12/10 06:37:05 @@ -102,6 +102,14 @@ static void gdk_pixmap_draw_image gint ydest, gint width, gint height); +static void gdk_pixmap_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride); static void gdk_pixmap_real_get_size (GdkDrawable *drawable, gint *width, @@ -182,6 +190,7 @@ gdk_pixmap_class_init (GdkPixmapObjectCl drawable_class->draw_lines = gdk_pixmap_draw_lines; drawable_class->draw_glyphs = gdk_pixmap_draw_glyphs; drawable_class->draw_image = gdk_pixmap_draw_image; + drawable_class->draw_rgba_image = gdk_pixmap_draw_rgba_image; drawable_class->get_depth = gdk_pixmap_real_get_depth; drawable_class->get_size = gdk_pixmap_real_get_size; drawable_class->set_colormap = gdk_pixmap_real_set_colormap; @@ -364,6 +373,21 @@ gdk_pixmap_draw_image (GdkDrawable * gdk_draw_image (private->impl, gc, image, xsrc, ysrc, xdest, ydest, width, height); +} + +static void +gdk_pixmap_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + gdk_draw_rgba_image (private->impl, gc, x, y, width, height, rgb_buf, rowstride); } static void Index: gdk/gdkwindow.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.c,v retrieving revision 1.127 diff -u -p -r1.127 gdkwindow.c --- gdk/gdkwindow.c 2001/11/29 23:08:35 1.127 +++ gdk/gdkwindow.c 2001/12/10 06:37:06 @@ -34,6 +34,7 @@ #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */ typedef struct _GdkWindowPaint GdkWindowPaint; +typedef struct _GdkRedirectInfo GdkRedirectInfo; struct _GdkWindowPaint { @@ -41,8 +42,16 @@ struct _GdkWindowPaint GdkPixmap *pixmap; gint x_offset; gint y_offset; + gboolean is_redirect; }; +struct _GdkRedirectInfo +{ + GdkWindowTransferFunc transfer_func; + gpointer transfer_data; + GDestroyNotify transfer_destroy; +}; + static const GdkPointerHooks default_pointer_hooks = { _gdk_windowing_window_get_pointer, _gdk_windowing_window_at_pointer @@ -125,6 +134,14 @@ static void gdk_window_draw_image gint ydest, gint width, gint height); +static void gdk_window_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride); static GdkImage* gdk_window_get_image (GdkDrawable *drawable, gint x, @@ -223,6 +240,7 @@ gdk_window_class_init (GdkWindowObjectCl drawable_class->draw_lines = gdk_window_draw_lines; drawable_class->draw_glyphs = gdk_window_draw_glyphs; drawable_class->draw_image = gdk_window_draw_image; + drawable_class->draw_rgba_image = gdk_window_draw_rgba_image; drawable_class->get_depth = gdk_window_real_get_depth; drawable_class->get_size = gdk_window_real_get_size; drawable_class->set_colormap = gdk_window_real_set_colormap; @@ -747,7 +765,7 @@ gdk_window_is_viewable (GdkWindow *windo (private != (GdkWindowObject *)_gdk_parent_root) && (GDK_WINDOW_TYPE (private) != GDK_WINDOW_FOREIGN)) { - if (!GDK_WINDOW_IS_MAPPED (window)) + if (!GDK_WINDOW_IS_MAPPED (private)) return FALSE; private = (GdkWindowObject *)private->parent; @@ -918,10 +936,18 @@ gdk_window_begin_paint_region (GdkWindow return; paint = g_new (GdkWindowPaint, 1); - + + paint->is_redirect = FALSE; paint->region = gdk_region_copy (region); - init_region = gdk_region_copy (region); + if (private->paint_stack) + { + GdkWindowPaint *redirect_paint = g_slist_last (private->paint_stack)->data; + if (redirect_paint->is_redirect) + gdk_region_intersect (paint->region, redirect_paint->region); + } + + init_region = gdk_region_copy (paint->region); gdk_region_get_clipbox (paint->region, &clip_box); if (private->paint_stack) @@ -958,12 +984,16 @@ gdk_window_begin_paint_region (GdkWindow while (tmp_list) { tmp_paint = tmp_list->data; - gdk_region_subtract (init_region, tmp_paint->region); - tmp_paint->pixmap = paint->pixmap; - tmp_paint->x_offset = paint->x_offset; - tmp_paint->y_offset = paint->y_offset; - + if (!tmp_paint->is_redirect) + { + gdk_region_subtract (init_region, tmp_paint->region); + + tmp_paint->pixmap = paint->pixmap; + tmp_paint->x_offset = paint->x_offset; + tmp_paint->y_offset = paint->y_offset; + } + tmp_list = tmp_list->next; } } @@ -977,8 +1007,10 @@ gdk_window_begin_paint_region (GdkWindow while (tmp_list) { tmp_paint = tmp_list->data; - gdk_region_subtract (init_region, tmp_paint->region); + if (!tmp_paint->is_redirect) + gdk_region_subtract (init_region, tmp_paint->region); + tmp_list = tmp_list->next; } } @@ -1018,6 +1050,7 @@ gdk_window_end_paint (GdkWindow *window) #ifdef USE_BACKING_STORE GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowPaint *paint; + GdkWindowPaint *redirect_paint; GdkGC *tmp_gc; GdkRectangle clip_box; gint x_offset, y_offset; @@ -1035,23 +1068,9 @@ gdk_window_end_paint (GdkWindow *window) } paint = private->paint_stack->data; - private->paint_stack = g_slist_delete_link (private->paint_stack, private->paint_stack); - - gdk_region_get_clipbox (paint->region, &clip_box); - - tmp_gc = gdk_gc_new (window); + redirect_paint = g_slist_last (private->paint_stack)->data; - _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset); - - gdk_gc_set_clip_region (tmp_gc, paint->region); - gdk_gc_set_clip_origin (tmp_gc, -x_offset, -y_offset); - - gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, - clip_box.x - paint->x_offset, - clip_box.y - paint->y_offset, - clip_box.x - x_offset, clip_box.y - y_offset, - clip_box.width, clip_box.height); - gdk_gc_unref (tmp_gc); + private->paint_stack = g_slist_delete_link (private->paint_stack, private->paint_stack); if (private->paint_stack) { @@ -1059,12 +1078,61 @@ gdk_window_end_paint (GdkWindow *window) while (tmp_list) { GdkWindowPaint *tmp_paint = tmp_list->data; - gdk_region_subtract (tmp_paint->region, paint->region); + + if (!tmp_paint->is_redirect) + gdk_region_subtract (tmp_paint->region, paint->region); tmp_list = tmp_list->next; } } + + if (!redirect_paint->is_redirect) + { + tmp_gc = gdk_gc_new (window); + + gdk_region_get_clipbox (paint->region, &clip_box); + + _gdk_windowing_window_get_offsets (window, &x_offset, &y_offset); + + gdk_gc_set_clip_region (tmp_gc, paint->region); + gdk_gc_set_clip_origin (tmp_gc, -x_offset, -y_offset); + + gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, + clip_box.x - paint->x_offset, + clip_box.y - paint->y_offset, + clip_box.x - x_offset, clip_box.y - y_offset, + clip_box.width, clip_box.height); + gdk_gc_unref (tmp_gc); + } else + { + GdkWindowObject *parent = private->parent; + GdkWindowPaint *parent_redirect_paint; + GdkRedirectInfo *redirect_info; + + while (parent) + { + if (!parent->paint_stack) + break; + + parent_redirect_paint = g_slist_last (parent->paint_stack)->data; + if (!parent_redirect_paint->is_redirect) + break; + + private = parent; + parent = private->parent; + } + + redirect_info = g_object_get_data (G_OBJECT (private), "gdk-redirect-info"); + gdk_region_intersect (paint->region, redirect_paint->region); + gdk_region_offset (paint->region, - paint->x_offset, - paint->y_offset); + + if (redirect_info->transfer_func) + redirect_info->transfer_func ((GdkWindow *)private, paint->pixmap, paint->region, 0, 0, + redirect_info->transfer_data); + } + + if (!private->paint_stack) gdk_drawable_unref (paint->pixmap); gdk_region_destroy (paint->region); @@ -1720,7 +1788,7 @@ gdk_window_draw_glyphs (GdkDrawable } else gdk_draw_glyphs (private->impl, gc, font, - x - x_offset, y - y_offset, glyphs); + x - x_offset, y - y_offset, glyphs); RESTORE_GC (gc); } @@ -1864,6 +1932,37 @@ gdk_window_draw_image (GdkDrawable *draw static void +gdk_window_draw_rgba_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + guchar *rgb_buf, + gint rowstride) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + + OFFSET_GC (gc); + + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + gdk_draw_rgba_image (paint->pixmap, gc, + x - x_offset, y - y_offset, + width, height, + rgb_buf, rowstride); + } + else + gdk_draw_rgba_image (private->impl, gc, + x - x_offset, y - y_offset, + width, height, + rgb_buf, rowstride); + + RESTORE_GC (gc); +} + +static void gdk_window_real_get_size (GdkDrawable *drawable, gint *width, gint *height) @@ -1974,7 +2073,7 @@ gdk_window_process_updates_internal (Gdk GdkRegion *update_area = private->update_area; private->update_area = NULL; - if (_gdk_event_func && gdk_window_is_viewable (window)) + if (_gdk_event_func /* && gdk_window_is_viewable (window) */) { GdkEvent event; GdkRectangle window_rect; @@ -2133,7 +2232,7 @@ gdk_window_invalidate_rect (GdkWindow if (GDK_WINDOW_DESTROYED (window)) return; - if (private->input_only || !GDK_WINDOW_IS_MAPPED (window)) + if (private->input_only /* || !GDK_WINDOW_IS_MAPPED (window) */) return; if (!rect) @@ -2191,7 +2290,7 @@ gdk_window_invalidate_maybe_recurse (Gdk if (GDK_WINDOW_DESTROYED (window)) return; - if (private->input_only || !GDK_WINDOW_IS_MAPPED (window)) + if (private->input_only /* || !GDK_WINDOW_IS_MAPPED (window) */) return; visible_region = gdk_drawable_get_visible_region (window); @@ -2654,3 +2753,565 @@ gdk_get_default_root_window (void) return _gdk_parent_root; } +/* Handle persistant redirection of drawing operations from a window to + * an offscreen pixmap. This is rather different from begin_paint() + * end_paint() in that we redirect on all children, rather just on + * on this window; it is intended for things like thumbnailing the + * contents of a possibly obscured window + */ +static GdkWindowPaint * +get_redirect_paint (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + + if (paint->is_redirect) + return paint; + } + + return NULL; +} + +static void +compute_redirect (GdkWindow *window, + GdkPixmap *pixmap, + gint x_offset, + gint y_offset, + GdkRegion *clip) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GList *children = gdk_window_peek_children (window); + GdkWindowPaint *paint; + + if (private->paint_stack) + { + paint = private->paint_stack->data; + g_return_if_fail (paint->is_redirect); + gdk_region_destroy (paint->region); + } + else + { + paint = g_new (GdkWindowPaint, 1); + private->paint_stack = g_slist_prepend (private->paint_stack, paint); + paint->pixmap = pixmap; + paint->is_redirect = TRUE; + } + + while (children) + { + GdkWindow *child = children->data; + + if (!((GdkWindowObject*)child)->input_only && gdk_window_is_visible (child)) + { + GdkRectangle child_rect; + GdkRegion *child_region; + GdkRegion *child_clip; + + child_clip = gdk_region_copy (clip); + + gdk_window_get_position (child, &child_rect.x, &child_rect.y); + child_rect.x += x_offset; + child_rect.y += y_offset; + + gdk_window_get_size (child, &child_rect.width, &child_rect.height); + + child_region = gdk_region_rectangle (&child_rect); + + gdk_region_intersect (child_clip, child_region); + gdk_region_subtract (clip, child_region); + + compute_redirect (child, pixmap, child_rect.x, child_rect.y, child_clip); + + gdk_region_destroy (child_region); + } + + children = children->next; + } + + gdk_region_offset (clip, - x_offset, - y_offset); + paint->region = clip; + + paint->x_offset = - x_offset; + paint->y_offset = - y_offset; +} + +/* Recompute the redirect paint information for a window after a child + * of the window is change + */ +static void +recompute_redirect (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowPaint *paint; + GdkWindowObject *parent_private; + GdkRectangle window_rect; + GdkRegion *clip; + + paint = get_redirect_paint (window); + if (!paint) + return; + + /* First, we need to compute the clip rectangle for this window clipped + * by parents and siblings of parents, but not by children + */ + window_rect.x = paint->x_offset; + window_rect.y = paint->y_offset; + gdk_window_get_size (window, &window_rect.width, &window_rect.height); + clip = gdk_region_rectangle (&window_rect); + + parent_private = private->parent; + while (parent_private) + { + GdkWindowPaint *parent_paint = get_redirect_paint ((GdkWindow *)private->parent); + if (parent_paint) + { + GList *children = gdk_window_peek_children ((GdkWindow *)parent_private); + + while (children) + { + GdkWindow *child = children->data; + + if (child == (GdkWindow *)private) + break; + + if (!((GdkWindowObject*)child)->input_only && gdk_window_is_visible (child)) + { + GdkRectangle child_rect; + GdkRegion *child_region; + + gdk_window_get_position (child, &child_rect.x, &child_rect.y); + child_rect.x += parent_paint->x_offset; + child_rect.y += parent_paint->y_offset; + + gdk_window_get_size (child, &child_rect.width, &child_rect.height); + + child_region = gdk_region_rectangle (&child_rect); + gdk_region_subtract (clip, child_region); + gdk_region_destroy (child_region); + } + + children = children->next; + } + } + + private = parent_private; + parent_private = private->parent; + } + + /* Now we compute the clip for this window and it's descendents + */ + compute_redirect (window, paint->pixmap, - paint->x_offset, - paint->y_offset, clip); +} + +static void +recompute_parent_redirect (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + if (private->parent) + recompute_redirect ((GdkWindow *)private->parent); +} + +GdkPixmap * +gdk_window_begin_redirect_paint (GdkWindow *window, + GdkWindowTransferFunc transfer_func, + gpointer transfer_data, + GDestroyNotify transfer_destroy) +{ + GdkPixmap *pixmap; + GdkRegion *clip; + GdkRectangle clip_rect; + gint width, height; + GdkRedirectInfo *redirect_info; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + g_return_val_if_fail (!((GdkWindowObject*)window)->input_only, NULL); + + redirect_info = g_new (GdkRedirectInfo, 1); + redirect_info->transfer_func = transfer_func; + redirect_info->transfer_data = transfer_data; + redirect_info->transfer_destroy = transfer_destroy; + g_object_set_data (G_OBJECT (window), "gdk-redirect-info", redirect_info); + + gdk_window_get_size (window, &width, &height); + + pixmap = gdk_pixmap_new (window, width, height, -1); + + clip_rect.x = 0; + clip_rect.y = 0; + clip_rect.width = width; + clip_rect.height = height; + clip = gdk_region_rectangle (&clip_rect); + + compute_redirect (window, pixmap, 0, 0, clip); + + return pixmap; +} + +static void +end_redirect_paint_recurse (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GList *children = gdk_window_peek_children (window); + GdkWindowPaint *paint; + + g_return_if_fail (private->paint_stack); + + while (children) + { + GdkWindow *child = children->data; + + if (!((GdkWindowObject*)child)->input_only && gdk_window_is_visible (child)) + end_redirect_paint_recurse (child); + + children = children->next; + } + + paint = private->paint_stack->data; + private->paint_stack = g_slist_delete_link (private->paint_stack, private->paint_stack); + gdk_region_destroy (paint->region); + g_free (paint); +} + +void +gdk_window_end_redirect_paint (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowPaint *paint; + GdkRedirectInfo *redirect_info; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + paint = private->paint_stack->data; + g_object_unref (paint->pixmap); + + redirect_info = g_object_get_data (G_OBJECT (window), "gdk-redirect-info"); + if (redirect_info->transfer_destroy) + redirect_info->transfer_destroy (redirect_info->transfer_data); + + end_redirect_paint_recurse (window); +} + +/** + * gdk_window_show: + * @window: a #GdkWindow + * + * Like gdk_window_show_unraised(), but also raises the window to the + * top of the window stack (moves the window to the front of the + * Z-order). + * + * This function maps a window so it's visible onscreen. Its opposite + * is gdk_window_hide(). + * + * When implementing a #GtkWidget, you should call this function on the widget's + * #GdkWindow as part of the "map" method. + * + **/ +void +gdk_window_show (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + _gdk_windowing_window_raise (window); + gdk_window_show_unraised (window); +} + +/** + * gdk_window_show_unraised: + * @window: a #GdkWindow + * + * Shows a #GdkWindow onscreen, but does not modify its stacking + * order. In contrast, gdk_window_show() will raise the window + * to the top of the window stack. + * + * On the X11 platform, in Xlib terms, this function calls + * XMapWindow() (it also updates some internal GDK state, which means + * that you can't really use XMapWindow() directly on a GDK window). + **/ +void +gdk_window_show_unraised (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + _gdk_windowing_window_show_unraised (window); + + recompute_parent_redirect (window); +} + +/** + * gdk_window_hide: + * @window: a #GdkWindow + * + * For toplevel windows, withdraws them, so they will no longer be + * known to the window manager; for all windows, unmaps them, so + * they won't be displayed. Normally done automatically as + * part of gtk_widget_hide(). + **/ +void +gdk_window_hide (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + _gdk_windowing_window_hide (window); + + recompute_parent_redirect (window); +} + +void +real_move_resize (GdkWindow *window, + gint x, + gint y, + gint width, + gint height, + gboolean is_move, + gboolean is_resize) +{ + GdkWindowPaint *paint = NULL; + GdkRegion *old_clip = NULL; + gint old_x, old_y; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + gdk_window_get_position (window, &old_x, &old_y); + + if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) + { + gint old_width, old_height; + + gdk_window_get_position (window, &old_width, &old_height); + if (old_width == width && old_height == height) + is_resize = FALSE; + } + + if (x != old_x || y != old_y) + { + paint = get_redirect_paint (window); + if (paint) + old_clip = gdk_region_copy (paint->region); + } + else + { + if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) + is_move = FALSE; + } + + if (is_move && is_resize) + _gdk_windowing_window_move_resize (window, x, y, width, height); + else if (is_move) + _gdk_windowing_window_move (window, x, y); + else if (is_resize) + _gdk_windowing_window_resize (window, width, height); + else + return; + + recompute_parent_redirect (window); + + if (paint) + { + GdkRectangle bounding; + GdkGC *gc; + + paint = get_redirect_paint (window); + gdk_region_offset (old_clip, x - old_x, y - old_y); + gdk_region_intersect (old_clip, paint->region); + + gc = gdk_gc_new (paint->pixmap); + gdk_gc_set_clip_region (gc, old_clip); + gdk_region_destroy (old_clip); + + gdk_region_get_clipbox (old_clip, &bounding); + + gdk_draw_drawable (paint->pixmap, gc, paint->pixmap, + bounding.x + old_x - x, bounding.y + old_y - y, + bounding.x, bounding.y, + bounding.width, bounding.height); + + g_object_unref (gc); + } +} + +/** + * gdk_window_move: + * @window: a #GdkWindow + * @x: X coordinate relative to window's parent + * @y: Y coordinate relative to window's parent + * + * Repositions a window relative to its parent window. + * For toplevel windows, window managers may ignore or modify the move; + * you should probably use gtk_window_move() on a #GtkWindow widget + * anyway, instead of using GDK functions. For child windows, + * the move will reliably succeed. + * + * If you're also planning to resize the window, use gdk_window_move_resize() + * to both move and resize simultaneously, for a nicer visual effect. + **/ +void +gdk_window_move (GdkWindow *window, + gint x, + gint y) +{ + gint width, height; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + gdk_window_get_size (window, &width, &height); + real_move_resize (window, x, y, width, height, TRUE, FALSE); +} + +/** + * gdk_window_resize: + * @window: a #GdkWindow + * @width: new width of the window + * @height: new height of the window + * + * Resizes @window; for toplevel windows, asks the window manager to resize + * the window. The window manager may not allow the resize. When using GTK+, + * use gtk_window_resize() instead of this low-level GDK function. + * + * Windows may not be resized below 1x1. + * + * If you're also planning to move the window, use gdk_window_move_resize() + * to both move and resize simultaneously, for a nicer visual effect. + * + **/ +void +gdk_window_resize (GdkWindow *window, + gint width, + gint height) +{ + gint x, y; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + gdk_window_get_position (window, &x, &y); + real_move_resize (window, x, y, width, height, FALSE, TRUE); +} + +/** + * gdk_window_move_resize: + * @window: a #GdkWindow + * @x: new X position relative to window's parent + * @y: new Y position relative to window's parent + * @width: new width + * @height: new height + * + * Equivalent to calling gdk_window_move() and gdk_window_resize(), + * except that both operations are performed at once, avoiding strange + * visual effects. (i.e. the user may be able to see the window first + * move, then resize, if youu don't use gdk_window_move_resize().) + **/ +void +gdk_window_move_resize (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + real_move_resize (window, x, y, width, height, TRUE, TRUE); +} + +/** + * gdk_window_raise: + * @window: a #GdkWindow + * + * Raises @window to the top of the Z-order (stacking order), so that + * other windows with the same parent window appear below @window. + * If @window is a toplevel, the window manager may choose to deny the + * request to move the window in the Z-order, gdk_window_raise() only + * requests the restack, does not guarantee it. + * + **/ +void +gdk_window_raise (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + g_return_if_fail (GDK_IS_WINDOW (window)); + + _gdk_windowing_window_raise (window); + + recompute_parent_redirect (window); +} + +/** + * gdk_window_lower: + * @window: a #GdkWindow + * + * Lowers @window to the bottom of the Z-order (stacking order), so that + * other windows with the same parent window appear above @window. + * If @window is a toplevel, the window manager may choose to deny the + * request to move the window in the Z-order, gdk_window_lower() only + * requests the restack, does not guarantee it. + * + * Note that gdk_window_show() raises the window again, so don't call this + * function before gdk_window_show(). (Try gdk_window_show_unraised().) + * + **/ +void +gdk_window_lower (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + _gdk_windowing_window_lower (window); + + recompute_parent_redirect (window); +} + +/** + * gdk_window_scroll: + * @window: a #GdkWindow + * @dx: Amount to scroll in the X direction + * @dy: Amount to scroll in the Y direction + * + * Scroll the contents of @window, both pixels and children, by the given + * amount. @window itself does not move. Portions of the window that the scroll + * operation brings in from offscreen areas are invalidated. The invalidated + * region may be bigger than what would strictly be necessary. (For X11, a + * minimum area will be invalidated if the window has no subwindows, or if the + * edges of the window's parent do not extend beyond the edges of the window. In + * other cases, a multi-step process is used to scroll the window which may + * produce temporary visual artifacts and unnecessary invalidations.) + **/ +void +gdk_window_scroll (GdkWindow *window, + gint dx, + gint dy) +{ + GdkWindowPaint *paint; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + _gdk_windowing_window_scroll (window, dx, dy); + + paint = get_redirect_paint (window); + if (paint) + { + GdkRegion *old_clip = gdk_region_copy (paint->region); + GdkRectangle bounding; + GdkGC *gc; + + paint = get_redirect_paint (window); + gdk_region_offset (old_clip, dx, dy); + gdk_region_intersect (old_clip, paint->region); + + gc = gdk_gc_new (paint->pixmap); + gdk_gc_set_clip_region (gc, old_clip); + gdk_region_destroy (old_clip); + + gdk_region_get_clipbox (old_clip, &bounding); + + gdk_draw_drawable (paint->pixmap, gc, paint->pixmap, + bounding.x - dx, bounding.y - dy, + bounding.x, bounding.y, + bounding.width, bounding.height); + + g_object_unref (gc); + } + + recompute_redirect (window); +} Index: gdk/gdkwindow.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.h,v retrieving revision 1.37 diff -u -p -r1.37 gdkwindow.h --- gdk/gdkwindow.h 2001/12/06 21:37:50 1.37 +++ gdk/gdkwindow.h 2001/12/10 06:37:06 @@ -538,6 +538,19 @@ GdkPointerHooks *gdk_set_pointer_hooks ( GdkWindow *gdk_get_default_root_window (); +typedef void (*GdkWindowTransferFunc) (GdkWindow *window, + GdkPixmap *pixmap, + GdkRegion *region, + gint x_offset, + gint y_offset, + gpointer data); + +GdkPixmap *gdk_window_begin_redirect_paint (GdkWindow *window, + GdkWindowTransferFunc transfer_func, + gpointer transfer_data, + GDestroyNotify transfer_destroy); +void gdk_window_end_redirect_paint (GdkWindow *window); + #ifndef GDK_DISABLE_DEPRECATED #define GDK_ROOT_PARENT() (gdk_get_default_root_window ()) #define gdk_window_get_size gdk_drawable_get_size Index: gdk/x11/gdkdrawable-x11.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdrawable-x11.c,v retrieving revision 1.11 diff -u -p -r1.11 gdkdrawable-x11.c --- gdk/x11/gdkdrawable-x11.c 2001/11/05 17:48:58 1.11 +++ gdk/x11/gdkdrawable-x11.c 2001/12/10 06:37:07 @@ -204,10 +204,11 @@ gdk_drawable_impl_x11_finalize (GObject } #ifdef HAVE_XFT -static Picture +Picture gdk_x11_drawable_get_picture (GdkDrawable *drawable) { - GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); + GdkWindowObject *obj = (GdkWindowObject *)drawable; + GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (obj->impl); if (impl->picture == None) { @@ -231,27 +232,29 @@ gdk_x11_drawable_get_picture (GdkDrawabl return impl->picture; } -static void -gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable, - GdkGC *gc) -{ - GdkGCX11 *gc_private = GDK_GC_X11 (gc); - GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); - Picture picture = gdk_x11_drawable_get_picture (drawable); +void +gdk_x11_drawable_set_picture_clip (GdkDrawable *drawable, + GdkRegion *clip_region, + gint clip_x_origin, + gint clip_y_origin) +{ + GdkWindowObject *obj = (GdkWindowObject *)drawable; + GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (obj->impl); + Picture picture = gdk_x11_drawable_get_picture (impl->wrapper); - if (gc_private->clip_region) + if (clip_region) { - GdkRegionBox *boxes = gc_private->clip_region->rects; - gint n_boxes = gc_private->clip_region->numRects; + GdkRegionBox *boxes = clip_region->rects; + gint n_boxes = clip_region->numRects; XRectangle *rects = g_new (XRectangle, n_boxes); int i; for (i=0; i < n_boxes; i++) { - rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT); - rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT); - rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x; - rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y; + rects[i].x = CLAMP (boxes[i].x1 + clip_x_origin, G_MINSHORT, G_MAXSHORT); + rects[i].y = CLAMP (boxes[i].y1 + clip_y_origin, G_MINSHORT, G_MAXSHORT); + rects[i].width = CLAMP (boxes[i].x2 + clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x; + rects[i].height = CLAMP (boxes[i].y2 + clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y; } XRenderSetPictureClipRectangles (impl->xdisplay, picture, 0, 0, rects, n_boxes); @@ -264,6 +267,18 @@ gdk_x11_drawable_update_picture_clip (Gd pa.clip_mask = None; XRenderChangePicture (impl->xdisplay, picture, CPClipMask, &pa); } + +} + +static void +gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable, + GdkGC *gc) +{ + GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); + GdkGCX11 *gc_private = GDK_GC_X11 (gc); + + gdk_x11_drawable_set_picture_clip (impl->wrapper, gc_private->clip_region, + gc->clip_x_origin, gc->clip_y_origin); } #endif @@ -666,7 +681,7 @@ gdk_x11_draw_glyphs (GdkDrawable *d src_picture = _gdk_x11_gc_get_fg_picture (gc); gdk_x11_drawable_update_picture_clip (drawable, gc); - dest_picture = gdk_x11_drawable_get_picture (drawable); + dest_picture = gdk_x11_drawable_get_picture (impl->wrapper); pango_xft_picture_render (impl->xdisplay, src_picture, dest_picture, font, glyphs, x, y); } Index: gdk/x11/gdkdrawable-x11.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdrawable-x11.h,v retrieving revision 1.5 diff -u -p -r1.5 gdkdrawable-x11.h --- gdk/x11/gdkdrawable-x11.h 2001/11/05 17:48:58 1.5 +++ gdk/x11/gdkdrawable-x11.h 2001/12/10 06:37:07 @@ -77,6 +77,14 @@ struct _GdkDrawableImplX11Class GType _gdk_drawable_impl_x11_get_type (void); +#ifdef HAVE_XFT +Picture gdk_x11_drawable_get_picture (GdkDrawable *drawable); +void gdk_x11_drawable_set_picture_clip (GdkDrawable *drawable, + GdkRegion *clip_region, + gint clip_x_origin, + gint clip_y_origin); +#endif /* HAVE_XFT */ + #ifdef __cplusplus } #endif /* __cplusplus */ Index: gdk/x11/gdkgeometry-x11.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkgeometry-x11.c,v retrieving revision 1.13 diff -u -p -r1.13 gdkgeometry-x11.c --- gdk/x11/gdkgeometry-x11.c 2001/11/26 02:20:06 1.13 +++ gdk/x11/gdkgeometry-x11.c 2001/12/10 06:37:07 @@ -180,12 +180,13 @@ static void gdk_window_postmove static void gdk_window_queue_translation (GdkWindow *window, gint dx, gint dy); -static void gdk_window_tmp_unset_bg (GdkWindow *window); -static void gdk_window_tmp_reset_bg (GdkWindow *window); static void gdk_window_clip_changed (GdkWindow *window, GdkRectangle *old_clip, GdkRectangle *new_clip); +static void tmp_unset_bg (GdkWindow *window); +static void tmp_reset_bg (GdkWindow *window); + static GSList *translate_queue = NULL; void @@ -329,7 +330,7 @@ gdk_window_guffaw_scroll (GdkWindow * parent_pos.x11_y += new_info.y; parent_pos.clip_rect = new_info.clip_rect; - gdk_window_tmp_unset_bg (window); + tmp_unset_bg (window); if (d_xoffset < 0 || d_yoffset < 0) gdk_window_queue_translation (window, MIN (d_xoffset, 0), MIN (d_yoffset, 0)); @@ -366,7 +367,7 @@ gdk_window_guffaw_scroll (GdkWindow * impl->position_info.width, impl->position_info.height); if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + tmp_reset_bg (window); impl->position_info = new_info; @@ -378,25 +379,10 @@ gdk_window_guffaw_scroll (GdkWindow * } } -/** - * gdk_window_scroll: - * @window: a #GdkWindow - * @dx: Amount to scroll in the X direction - * @dy: Amount to scroll in the Y direction - * - * Scroll the contents of @window, both pixels and children, by the given - * amount. @window itself does not move. Portions of the window that the scroll - * operation brings in from offscreen areas are invalidated. The invalidated - * region may be bigger than what would strictly be necessary. (For X11, a - * minimum area will be invalidated if the window has no subwindows, or if the - * edges of the window's parent do not extend beyond the edges of the window. In - * other cases, a multi-step process is used to scroll the window which may - * produce temporary visual artifacts and unnecessary invalidations.) - **/ void -gdk_window_scroll (GdkWindow *window, - gint dx, - gint dy) +_gdk_windowing_window_scroll (GdkWindow *window, + gint dx, + gint dy) { gboolean can_guffaw_scroll = FALSE; GdkRegion *invalidate_region; @@ -542,7 +528,7 @@ _gdk_window_move_resize_child (GdkWindow new_info.x, new_info.y, new_info.width, new_info.height); if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + tmp_reset_bg (window); if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); @@ -588,7 +574,7 @@ _gdk_window_move_resize_child (GdkWindow } if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + tmp_reset_bg (window); if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) XMapWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); @@ -848,7 +834,7 @@ gdk_window_postmove (GdkWindow XMapWindow (GDK_DRAWABLE_XDISPLAY (window), GDK_DRAWABLE_XID (window)); if (impl->position_info.no_bg) - gdk_window_tmp_reset_bg (window); + tmp_reset_bg (window); impl->position_info = new_info; @@ -945,7 +931,7 @@ _gdk_window_process_expose (GdkWindow } static void -gdk_window_tmp_unset_bg (GdkWindow *window) +tmp_unset_bg (GdkWindow *window) { GdkWindowImplX11 *impl; GdkWindowObject *obj; @@ -954,14 +940,11 @@ gdk_window_tmp_unset_bg (GdkWindow *wind impl = GDK_WINDOW_IMPL_X11 (obj->impl); impl->position_info.no_bg = TRUE; - - if (obj->bg_pixmap != GDK_NO_BG) - XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), - GDK_DRAWABLE_XID (window), None); + _gdk_window_tmp_unset_bg (window); } static void -gdk_window_tmp_reset_bg (GdkWindow *window) +tmp_reset_bg (GdkWindow *window) { GdkWindowImplX11 *impl; GdkWindowObject *obj; @@ -970,28 +953,7 @@ gdk_window_tmp_reset_bg (GdkWindow *wind impl = GDK_WINDOW_IMPL_X11 (obj->impl); impl->position_info.no_bg = FALSE; - - if (obj->bg_pixmap == GDK_NO_BG) - return; - - if (obj->bg_pixmap) - { - Pixmap xpixmap; - - if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG) - xpixmap = ParentRelative; - else - xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap); - - XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), - GDK_DRAWABLE_XID (window), xpixmap); - } - else - { - XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window), - GDK_DRAWABLE_XID (window), - obj->bg_color.pixel); - } + _gdk_window_tmp_unset_bg (window); } static void @@ -1026,7 +988,7 @@ gdk_window_clip_changed (GdkWindow *wind gdk_region_subtract (new_clip_region, old_clip_region); if (!gdk_region_empty (new_clip_region)) { - gdk_window_tmp_unset_bg (window); + tmp_unset_bg (window); gdk_window_invalidate_region (window, new_clip_region, FALSE); } Index: gdk/x11/gdkprivate-x11.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkprivate-x11.h,v retrieving revision 1.17 diff -u -p -r1.17 gdkprivate-x11.h --- gdk/x11/gdkprivate-x11.h 2001/11/05 17:48:58 1.17 +++ gdk/x11/gdkprivate-x11.h 2001/12/10 06:37:07 @@ -142,6 +142,9 @@ void _gdk_window_process_expose (GdkW gulong serial, GdkRectangle *area); +void _gdk_window_tmp_unset_bg (GdkWindow *window); +void _gdk_window_tmp_reset_bg (GdkWindow *window); + void _gdk_selection_window_destroyed (GdkWindow *window); gboolean _gdk_selection_filter_clear_event (XSelectionClearEvent *event); Index: gdk/x11/gdkwindow-x11.c =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v retrieving revision 1.138 diff -u -p -r1.138 gdkwindow-x11.c --- gdk/x11/gdkwindow-x11.c 2001/11/25 22:19:22 1.138 +++ gdk/x11/gdkwindow-x11.c 2001/12/10 06:37:08 @@ -93,6 +93,8 @@ static void gdk_window_impl_x11_init static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass); static void gdk_window_impl_x11_finalize (GObject *object); +static void gdk_window_fade_in_end (GdkWindow *window); + static gpointer parent_class = NULL; GType @@ -423,6 +425,8 @@ gdk_window_new (GdkWindow *parent, xattributes.override_redirect = (attributes->override_redirect == FALSE)?False:True; xattributes_mask |= CWOverrideRedirect; + if (xattributes.override_redirect) + impl->override_redirect = TRUE; } else xattributes.override_redirect = False; @@ -502,6 +506,8 @@ gdk_window_new (GdkWindow *parent, { xattributes.save_under = True; xattributes.override_redirect = True; + impl->override_redirect = TRUE; + xattributes.cursor = None; xattributes_mask |= CWSaveUnder | CWOverrideRedirect; } @@ -878,9 +884,8 @@ set_initial_hints (GdkWindow *window) } } -static void -show_window_internal (GdkWindow *window, - gboolean raise) +void +_gdk_windowing_window_show_unraised (GdkWindow *window) { GdkWindowObject *private; @@ -889,10 +894,6 @@ show_window_internal (GdkWindow *window, private = (GdkWindowObject*) window; if (!private->destroyed) { - if (raise) - XRaiseWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); - if (!GDK_WINDOW_IS_MAPPED (window)) { set_initial_hints (window); @@ -910,63 +911,9 @@ show_window_internal (GdkWindow *window, } } -/** - * gdk_window_show_unraised: - * @window: a #GdkWindow - * - * Shows a #GdkWindow onscreen, but does not modify its stacking - * order. In contrast, gdk_window_show() will raise the window - * to the top of the window stack. - * - * On the X11 platform, in Xlib terms, this function calls - * XMapWindow() (it also updates some internal GDK state, which means - * that you can't really use XMapWindow() directly on a GDK window). - * - **/ -void -gdk_window_show_unraised (GdkWindow *window) -{ - g_return_if_fail (GDK_IS_WINDOW (window)); - - show_window_internal (window, FALSE); -} - -/** - * gdk_window_show: - * @window: a #GdkWindow - * - * Like gdk_window_show_unraised(), but also raises the window to the - * top of the window stack (moves the window to the front of the - * Z-order). - * - * This function maps a window so it's visible onscreen. Its opposite - * is gdk_window_hide(). - * - * When implementing a #GtkWidget, you should call this function on the widget's - * #GdkWindow as part of the "map" method. - * - **/ void -gdk_window_show (GdkWindow *window) +_gdk_windowing_window_hide (GdkWindow *window) { - g_return_if_fail (GDK_IS_WINDOW (window)); - - show_window_internal (window, TRUE); -} - -/** - * gdk_window_hide: - * @window: a #GdkWindow - * - * For toplevel windows, withdraws them, so they will no longer be - * known to the window manager; for all windows, unmaps them, so - * they won't be displayed. Normally done automatically as - * part of gtk_widget_hide(). - * - **/ -void -gdk_window_hide (GdkWindow *window) -{ GdkWindowObject *private; g_return_if_fail (window != NULL); @@ -989,6 +936,8 @@ gdk_window_hide (GdkWindow *window) break; } + gdk_window_fade_in_end (window); + if (!private->destroyed) { if (GDK_WINDOW_IS_MAPPED (window)) @@ -1020,6 +969,8 @@ gdk_window_withdraw (GdkWindow *window) g_return_if_fail (window != NULL); + gdk_window_fade_in_end (window); + private = (GdkWindowObject*) window; if (!private->destroyed) { @@ -1035,26 +986,10 @@ gdk_window_withdraw (GdkWindow *window) } } -/** - * gdk_window_move: - * @window: a #GdkWindow - * @x: X coordinate relative to window's parent - * @y: Y coordinate relative to window's parent - * - * Repositions a window relative to its parent window. - * For toplevel windows, window managers may ignore or modify the move; - * you should probably use gtk_window_move() on a #GtkWindow widget - * anyway, instead of using GDK functions. For child windows, - * the move will reliably succeed. - * - * If you're also planning to resize the window, use gdk_window_move_resize() - * to both move and resize simultaneously, for a nicer visual effect. - * - **/ void -gdk_window_move (GdkWindow *window, - gint x, - gint y) +_gdk_windowing_window_move (GdkWindow *window, + gint x, + gint y) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplX11 *impl; @@ -1078,26 +1013,10 @@ gdk_window_move (GdkWindow *window, } } -/** - * gdk_window_resize: - * @window: a #GdkWindow - * @width: new width of the window - * @height: new height of the window - * - * Resizes @window; for toplevel windows, asks the window manager to resize - * the window. The window manager may not allow the resize. When using GTK+, - * use gtk_window_resize() instead of this low-level GDK function. - * - * Windows may not be resized below 1x1. - * - * If you're also planning to move the window, use gdk_window_move_resize() - * to both move and resize simultaneously, for a nicer visual effect. - * - **/ void -gdk_window_resize (GdkWindow *window, - gint width, - gint height) +_gdk_windowing_window_resize (GdkWindow *window, + gint width, + gint height) { GdkWindowObject *private; @@ -1126,30 +1045,22 @@ gdk_window_resize (GdkWindow *window, XResizeWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), width, height); + + if (impl->override_redirect) + { + impl->width = width; + impl->height = height; + } } } } -/** - * gdk_window_move_resize: - * @window: a #GdkWindow - * @x: new X position relative to window's parent - * @y: new Y position relative to window's parent - * @width: new width - * @height: new height - * - * Equivalent to calling gdk_window_move() and gdk_window_resize(), - * except that both operations are performed at once, avoiding strange - * visual effects. (i.e. the user may be able to see the window first - * move, then resize, if youu don't use gdk_window_move_resize().) - * - **/ void -gdk_window_move_resize (GdkWindow *window, - gint x, - gint y, - gint width, - gint height) +_gdk_windowing_window_move_resize (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) { GdkWindowObject *private; @@ -1160,7 +1071,7 @@ gdk_window_move_resize (GdkWindow *windo width = 1; if (height < 1) height = 1; - + private = (GdkWindowObject*) window; if (!GDK_WINDOW_DESTROYED (window)) @@ -1177,6 +1088,12 @@ gdk_window_move_resize (GdkWindow *windo XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), x, y, width, height); + + if (impl->override_redirect) + { + impl->width = width; + impl->height = height; + } } } } @@ -1301,19 +1218,8 @@ _gdk_windowing_window_clear_area_e (GdkW } -/** - * gdk_window_raise: - * @window: a #GdkWindow - * - * Raises @window to the top of the Z-order (stacking order), so that - * other windows with the same parent window appear below @window. - * If @window is a toplevel, the window manager may choose to deny the - * request to move the window in the Z-order, gdk_window_raise() only - * requests the restack, does not guarantee it. - * - **/ void -gdk_window_raise (GdkWindow *window) +_gdk_windowing_window_raise (GdkWindow *window) { g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1322,22 +1228,8 @@ gdk_window_raise (GdkWindow *window) XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); } -/** - * gdk_window_lower: - * @window: a #GdkWindow - * - * Lowers @window to the bottom of the Z-order (stacking order), so that - * other windows with the same parent window appear above @window. - * If @window is a toplevel, the window manager may choose to deny the - * request to move the window in the Z-order, gdk_window_lower() only - * requests the restack, does not guarantee it. - * - * Note that gdk_window_show() raises the window again, so don't call this - * function before gdk_window_show(). (Try gdk_window_show_unraised().) - * - **/ void -gdk_window_lower (GdkWindow *window) +_gdk_windowing_window_lower (GdkWindow *window) { g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); @@ -1951,11 +1843,16 @@ gdk_window_set_background (GdkWindow *wi g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); - + if (!GDK_WINDOW_DESTROYED (window)) - XSetWindowBackground (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), color->pixel); + { + GdkWindowImplX11 *window_impl = GDK_WINDOW_IMPL_X11 (private->impl); + if (!window_impl->unset_bg_count) + XSetWindowBackground (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), color->pixel); + } + private->bg_color = *color; if (private->bg_pixmap && @@ -2029,8 +1926,13 @@ gdk_window_set_back_pixmap (GdkWindow *w } if (!GDK_WINDOW_DESTROYED (window)) - XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), xpixmap); + { + GdkWindowImplX11 *window_impl = GDK_WINDOW_IMPL_X11 (private->impl); + + if (!window_impl->unset_bg_count) + XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), xpixmap); + } } /** @@ -2746,7 +2648,11 @@ gdk_window_set_override_redirect (GdkWin if (GDK_WINDOW_DESTROYED (window)) { + GdkWindowObject *private = (GdkWindowObject*) window; + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); + attr.override_redirect = (override_redirect == FALSE)?False:True; + impl->override_redirect = (override_redirect == FALSE) ? FALSE : TRUE; XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), CWOverrideRedirect, @@ -4529,4 +4435,350 @@ gdk_window_begin_move_drag (GdkWindow *w root_x, root_y, timestamp); else emulate_move_drag (window, button, root_x, root_y, timestamp); +} + +void +_gdk_window_tmp_unset_bg (GdkWindow *window) +{ + GdkWindowImplX11 *impl; + GdkWindowObject *obj; + + obj = (GdkWindowObject *) window; + impl = GDK_WINDOW_IMPL_X11 (obj->impl); + + impl->position_info.no_bg = TRUE; + + if (impl->unset_bg_count == 0) + { + if (obj->bg_pixmap != GDK_NO_BG) + XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), + GDK_DRAWABLE_XID (window), None); + } + + impl->unset_bg_count++; +} + +void +_gdk_window_tmp_reset_bg (GdkWindow *window) +{ + GdkWindowImplX11 *impl; + GdkWindowObject *obj; + + obj = (GdkWindowObject *) window; + impl = GDK_WINDOW_IMPL_X11 (obj->impl); + + impl->position_info.no_bg = FALSE; + + impl->unset_bg_count--; + + if (impl->unset_bg_count == 0) + { + if (obj->bg_pixmap == GDK_NO_BG) + return; + + if (obj->bg_pixmap) + { + Pixmap xpixmap; + + if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG) + xpixmap = ParentRelative; + else + xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap); + + XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window), + GDK_DRAWABLE_XID (window), xpixmap); + } + else + { + XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window), + GDK_DRAWABLE_XID (window), + obj->bg_color.pixel); + } + } +} + +typedef struct _FadeInInfo FadeInInfo; + +struct _FadeInInfo +{ + GdkWindow *window; + GdkWindow *pixmap; + GdkPixmap *offscreen; + GdkPixmap *underneath; + guint timeout; + + gint total_time; + GTimeVal start_time; + + gint alpha; /* 0 - 255 */ +}; + +static XRenderPictFormat * +get_alpha_format (Display *xdisplay) +{ + XRenderPictFormat pf; + + pf.type = PictTypeDirect; + pf.depth = 8; + pf.direct.alphaMask = 0xff; + + return XRenderFindFormat (xdisplay, + (PictFormatType | + PictFormatDepth | + PictFormatAlphaMask), + &pf, + 0); +} + +static void +fade_in_update (GdkWindow *window, + GdkPixmap *pixmap, + GdkRegion *region, + gint x_offset, + gint y_offset, + FadeInInfo *info, + gboolean is_new) +{ + GdkRectangle clip_box; + + if (!GDK_WINDOW_IS_MAPPED (window) && !is_new) + return; + + gdk_region_get_clipbox (region, &clip_box); + + if (clip_box.width != 0 && clip_box.height != 0) + { + Display *xdisplay = GDK_WINDOW_XDISPLAY (window); + GdkPixmap *intermediate; + Picture source; + Picture dest; + GdkGCValues gc_values; + GdkGC *gc; + XRenderColor alpha_color = { 0, }; + XRenderPictFormat *alpha_format = get_alpha_format (xdisplay); + XRenderPictureAttributes alpha_attr; + Pixmap alpha_pix; + Picture alpha_pict; + + gc_values.subwindow_mode = GDK_INCLUDE_INFERIORS; + gc = gdk_gc_new_with_values (window, &gc_values, GDK_GC_SUBWINDOW); + + if (is_new) + { + gdk_gc_set_clip_region (gc, region); + XCopyArea (GDK_WINDOW_XDISPLAY (window), GDK_PIXMAP_XID (pixmap), GDK_PIXMAP_XID (info->offscreen), + GDK_GC_GET_XGC (gc), + clip_box.x, clip_box.y, clip_box.width, clip_box.height, clip_box.x, clip_box.y); + gdk_gc_set_clip_region (gc, NULL); + } + + if (!GDK_WINDOW_IS_MAPPED (window)) + { + g_object_unref (gc); + return; + } + + intermediate = gdk_pixmap_new (window, clip_box.width, clip_box.height, -1); + source = gdk_x11_drawable_get_picture (info->offscreen); + dest = gdk_x11_drawable_get_picture (intermediate); + + XCopyArea (GDK_WINDOW_XDISPLAY (window), GDK_PIXMAP_XID (info->underneath), GDK_PIXMAP_XID (intermediate), + GDK_GC_GET_XGC (gc), + clip_box.x, clip_box.y, clip_box.width, clip_box.height, 0, 0); + + alpha_pix = XCreatePixmap (xdisplay, GDK_WINDOW_XID (window), 1, 1, 8); + + alpha_attr.repeat = True; + alpha_pict = XRenderCreatePicture (xdisplay, alpha_pix, alpha_format, CPRepeat, &alpha_attr); + + alpha_color.alpha = 0x101 * info->alpha; + XRenderFillRectangle (xdisplay, PictOpSrc, alpha_pict, &alpha_color, 0, 0, 1, 1); + + gdk_x11_drawable_set_picture_clip (intermediate, region, - clip_box.x, - clip_box.y); + XRenderComposite (xdisplay, PictOpOver, source, alpha_pict, dest, + clip_box.x, clip_box.y, + 0, 0, + 0, 0, + clip_box.width, clip_box.height); + + gdk_gc_set_clip_region (gc, region); + XCopyArea (GDK_WINDOW_XDISPLAY (window), GDK_PIXMAP_XID (intermediate), GDK_WINDOW_XID (window), + GDK_GC_GET_XGC (gc), + 0, 0, clip_box.width, clip_box.height, clip_box.x, clip_box.y); + + XRenderFreePicture (xdisplay, alpha_pict); + XFreePixmap (xdisplay, alpha_pix); + g_object_unref (intermediate); + g_object_unref (gc); + } +} + +static void +fade_in_transfer (GdkWindow *window, + GdkPixmap *pixmap, + GdkRegion *region, + gint x_offset, + gint y_offset, + gpointer data) +{ + FadeInInfo *info = data; + + fade_in_update (window, pixmap, region, x_offset, y_offset, info, TRUE); +} + +static void +fade_in_destroy (gpointer data, + GObject *where_the_object_was) +{ + FadeInInfo *info = data; + + g_object_unref (info->underneath); + g_object_unref (info->offscreen); + g_source_remove (info->timeout); + g_free (info); +} + +void +reset_bg_recurse (GdkWindow *window) +{ + GList *children = gdk_window_peek_children (window); + + _gdk_window_tmp_reset_bg (window); + + while (children) + { + GdkWindow *child = children->data; + + if (!((GdkWindowObject*)child)->input_only) + reset_bg_recurse (child); + + children = children->next; + } +} + +static void +gdk_window_fade_in_end (GdkWindow *window) +{ + FadeInInfo *info = g_object_get_data (G_OBJECT (window), "gdk-fade-in-info"); + if (info) + { + gdk_window_end_redirect_paint (info->window); + reset_bg_recurse (info->window); + g_object_weak_unref (G_OBJECT (info->window), fade_in_destroy, info); + g_object_set_data (G_OBJECT (window), "gdk-fade-in-info", NULL); + fade_in_destroy (info, NULL); + } +} + +static gboolean +fade_in_timeout (gpointer data) +{ + FadeInInfo *info = data; + GTimeVal now; + gdouble msecs; + GdkRectangle clip_rect; + GdkRegion *clip; + + gdk_flush (); + + g_get_current_time (&now); + + msecs = (now.tv_sec - info->start_time.tv_sec) * 1000. + (now.tv_usec - info->start_time.tv_usec) / 1000.; + + info->alpha = MIN (255 * (msecs / info->total_time), 255); + + clip_rect.x = 0; + clip_rect.y = 0; + gdk_drawable_get_size (info->pixmap, &clip_rect.width, &clip_rect.height); + clip = gdk_region_rectangle (&clip_rect); + + fade_in_update (info->window, info->pixmap, clip, 0, 0, info, FALSE); + + gdk_region_destroy (clip); + + if (info->alpha == 255) + { + gdk_window_end_redirect_paint (info->window); + reset_bg_recurse (info->window); + g_object_weak_unref (G_OBJECT (info->window), fade_in_destroy, info); + g_object_set_data (G_OBJECT (info->window), "gdk-fade-in-info", NULL); + fade_in_destroy (info, NULL); + return FALSE; + } + else + return TRUE; +} + +void +unset_bg_recurse (GdkWindow *window) +{ + GList *children = gdk_window_peek_children (window); + + _gdk_window_tmp_unset_bg (window); + + while (children) + { + GdkWindow *child = children->data; + + if (!((GdkWindowObject*)child)->input_only) + unset_bg_recurse (child); + + children = children->next; + } +} + +void +gdk_window_fade_in (GdkWindow *window, + gint msecs) +{ + FadeInInfo *info; + gint x, y; + gint width, height; + GdkGCValues gc_values; + GdkGC *gc; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (msecs >= 0); + + if (GDK_WINDOW_IS_MAPPED (window)) + return; + + if (msecs == 0) + { + gdk_window_show (window); + return; + } + + info = g_new (FadeInInfo, 1); + + info->window = window; + info->timeout = g_timeout_add (MIN (msecs / 256, 30), fade_in_timeout, info); + info->total_time = msecs; + g_get_current_time (&info->start_time); + + info->alpha = 0; + + gdk_drawable_get_size (window, &width, &height); + + info->offscreen = gdk_pixmap_new (window, width, height,-1); + info->underneath = gdk_pixmap_new (window, width, height,-1); + + gc_values.subwindow_mode = GDK_INCLUDE_INFERIORS; + gc = gdk_gc_new_with_values (window, &gc_values, GDK_GC_SUBWINDOW); + + gdk_window_get_origin (window, &x, &y); + XCopyArea (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (gdk_get_default_root_window ()), GDK_WINDOW_XID (info->underneath), + GDK_GC_GET_XGC (gc), + x, y, width, height, 0, 0); + + unset_bg_recurse (window); + info->pixmap = gdk_window_begin_redirect_paint (window, fade_in_transfer, info, NULL); + gdk_window_invalidate_rect (window, NULL, TRUE); + gdk_window_process_updates (window, TRUE); + + g_object_set_data (G_OBJECT (window), "gdk-fade-in-info", info); + g_object_weak_ref (G_OBJECT (window), fade_in_destroy, info); + + gdk_window_show (window); } Index: gdk/x11/gdkwindow-x11.h =================================================================== RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.h,v retrieving revision 1.4 diff -u -p -r1.4 gdkwindow-x11.h --- gdk/x11/gdkwindow-x11.h 2001/04/18 17:57:36 1.4 +++ gdk/x11/gdkwindow-x11.h 2001/12/10 06:37:08 @@ -82,6 +82,9 @@ struct _GdkWindowImplX11 * manager is running. */ guint has_pointer_focus : 1; + guint override_redirect : 1; /* Set if override redirect */ + + gushort unset_bg_count; /* We use an extra X window for toplevel windows that we XSetInputFocus() * to in order to avoid getting keyboard events redirected to subwindows Index: gtk/gtkmenu.c =================================================================== RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v retrieving revision 1.78 diff -u -p -r1.78 gtkmenu.c --- gtk/gtkmenu.c 2001/11/29 20:36:12 1.78 +++ gtk/gtkmenu.c 2001/12/10 06:37:09 @@ -339,6 +339,8 @@ gtk_menu_init (GtkMenu *menu) "signal::event", gtk_menu_window_event, menu, "signal::destroy", gtk_widget_destroyed, &menu->toplevel, NULL); + gtk_window_set_fade_in_time (GTK_WINDOW (menu->toplevel), 250); + gtk_window_set_policy (GTK_WINDOW (menu->toplevel), FALSE, FALSE, TRUE); gtk_window_set_mnemonic_modifier (GTK_WINDOW (menu->toplevel), 0); Index: gtk/gtktooltips.c =================================================================== RCS file: /cvs/gnome/gtk+/gtk/gtktooltips.c,v retrieving revision 1.42 diff -u -p -r1.42 gtktooltips.c --- gtk/gtktooltips.c 2001/08/19 11:48:31 1.42 +++ gtk/gtktooltips.c 2001/12/10 06:37:09 @@ -172,8 +172,9 @@ gtk_tooltips_force_window (GtkTooltips * if (!tooltips->tip_window) { tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_fade_in_time (GTK_WINDOW (tooltips->tip_window), 250); gtk_widget_set_app_paintable (tooltips->tip_window, TRUE); - gtk_window_set_policy (GTK_WINDOW (tooltips->tip_window), FALSE, FALSE, TRUE); + gtk_window_set_policy (GTK_WINDOW (tooltips->tip_window), FALSE, FALSE, FALSE); gtk_widget_set_name (tooltips->tip_window, "gtk-tooltips"); gtk_container_set_border_width (GTK_CONTAINER (tooltips->tip_window), 4); Index: gtk/gtkwindow.c =================================================================== RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v retrieving revision 1.174 diff -u -p -r1.174 gtkwindow.c --- gtk/gtkwindow.c 2001/12/05 00:06:29 1.174 +++ gtk/gtkwindow.c 2001/12/10 06:37:11 @@ -2986,7 +2986,7 @@ gtk_window_show (GtkWidget *widget) &configure_request, &new_geometry, &new_flags); - + /* We update this because we are going to go ahead * and gdk_window_resize() below, rather than * queuing it. @@ -3020,8 +3020,8 @@ gtk_window_show (GtkWidget *widget) */ if (!was_realized) gdk_window_resize (widget->window, - configure_request.width, - configure_request.height); + configure_request.width, + configure_request.height); } gtk_container_check_resize (container); @@ -3048,11 +3048,24 @@ gtk_window_hide (GtkWidget *widget) gtk_grab_remove (widget); } +void gdk_window_fade_in (GdkWindow *window, gint msecs); + +void +gtk_window_set_fade_in_time (GtkWindow *window, + gint fade_in_msecs) +{ + g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_if_fail (fade_in_msecs >= 0); + + g_object_set_data (G_OBJECT (window), "gtk-fade-in-time", GINT_TO_POINTER (fade_in_msecs)); +} + static void gtk_window_map (GtkWidget *widget) { GtkWindow *window; GdkWindow *toplevel; + gint fade_in_msecs; g_return_if_fail (GTK_IS_WINDOW (widget)); @@ -3088,8 +3101,9 @@ gtk_window_map (GtkWidget *widget) /* No longer use the default settings */ window->need_default_size = FALSE; window->need_default_position = FALSE; - - gdk_window_show (widget->window); + + fade_in_msecs = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "gtk-fade-in-time")); + gdk_window_fade_in (widget->window, fade_in_msecs); if (window->frame) gdk_window_show (window->frame); Index: gtk/gtkwindow.h =================================================================== RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.h,v retrieving revision 1.56 diff -u -p -r1.56 gtkwindow.h --- gtk/gtkwindow.h 2001/11/20 23:43:03 1.56 +++ gtk/gtkwindow.h 2001/12/10 06:37:11 @@ -99,7 +99,7 @@ struct _GtkWindow GdkWindowTypeHint type_hint : 3; GdkGravity gravity : 5; - + guint frame_left; guint frame_top; guint frame_right; @@ -297,6 +297,9 @@ gboolean gtk_window_parse_geometry (Gt /* Ignore this unless you are writing a GUI builder */ void gtk_window_reshow_with_initial_size (GtkWindow *window); + +void gtk_window_set_fade_in_time (GtkWindow *window, + gint fade_in_msecs); /* Window groups */ Index: tests/testgtk.c =================================================================== RCS file: /cvs/gnome/gtk+/tests/testgtk.c,v retrieving revision 1.288 diff -u -p -r1.288 testgtk.c --- tests/testgtk.c 2001/12/08 15:44:45 1.288 +++ tests/testgtk.c 2001/12/10 06:37:14 @@ -10980,6 +10980,28 @@ struct { }; int nbuttons = sizeof (buttons) / sizeof (buttons[0]); +static void +do_fade_in (GtkWidget *child, + GtkWidget *toplevel) +{ + GdkPixmap *pixmap; + GtkWidget *displayer; + + g_object_ref (pixmap); + + gdk_window_invalidate_rect (toplevel->window, NULL, TRUE); + gdk_window_process_updates (toplevel->window, TRUE); + gdk_window_end_redirect_paint (toplevel->window); + + displayer = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_app_paintable (displayer, TRUE); + gtk_widget_set_usize (displayer, toplevel->allocation.width,toplevel->allocation.height); + + gtk_widget_realize (displayer); + gdk_window_set_back_pixmap (displayer->window, pixmap, FALSE); + gtk_widget_show (displayer); +} + void create_main_window (void) { @@ -11074,6 +11096,9 @@ create_main_window (void) GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_grab_default (button); + /* g_signal_connect (GTK_BIN (window)->child, "map", + G_CALLBACK (do_fade_in), window);*/ + gtk_widget_show_all (window); }