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/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
@@ -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);
 }
@@ -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);
 }
 
