]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkviewport.c
Deprecate widget flag: GTK_WIDGET_MAPPED
[~andy/gtk] / gtk / gtkviewport.c
index ed8c202b2f2402856d2d8ea6f71ce82023ac74d5..d9e35fb0d2b3ab58c149e971dd5360b994d377a0 100644 (file)
@@ -2,34 +2,60 @@
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
-#include "gtksignal.h"
-#include "gtkviewport.h"
 
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
 
-static void gtk_viewport_class_init               (GtkViewportClass *klass);
-static void gtk_viewport_init                     (GtkViewport      *viewport);
-static void gtk_viewport_finalize                 (GtkObject        *object);
-static void gtk_viewport_map                      (GtkWidget        *widget);
-static void gtk_viewport_unmap                    (GtkWidget        *widget);
+#include "config.h"
+#include "gtkviewport.h"
+#include "gtkintl.h"
+#include "gtkmarshalers.h"
+#include "gtkprivate.h"
+#include "gtkalias.h"
+
+enum {
+  PROP_0,
+  PROP_HADJUSTMENT,
+  PROP_VADJUSTMENT,
+  PROP_SHADOW_TYPE
+};
+
+
+static void gtk_viewport_finalize                 (GObject          *object);
+static void gtk_viewport_destroy                  (GtkObject        *object);
+static void gtk_viewport_set_property             (GObject         *object,
+                                                  guint            prop_id,
+                                                  const GValue    *value,
+                                                  GParamSpec      *pspec);
+static void gtk_viewport_get_property             (GObject         *object,
+                                                  guint            prop_id,
+                                                  GValue          *value,
+                                                  GParamSpec      *pspec);
+static void gtk_viewport_set_scroll_adjustments          (GtkViewport      *viewport,
+                                                  GtkAdjustment    *hadjustment,
+                                                  GtkAdjustment    *vadjustment);
 static void gtk_viewport_realize                  (GtkWidget        *widget);
 static void gtk_viewport_unrealize                (GtkWidget        *widget);
 static void gtk_viewport_paint                    (GtkWidget        *widget,
                                                   GdkRectangle     *area);
-static void gtk_viewport_draw                     (GtkWidget        *widget,
-                                                  GdkRectangle     *area);
 static gint gtk_viewport_expose                   (GtkWidget        *widget,
                                                   GdkEventExpose   *event);
 static void gtk_viewport_add                      (GtkContainer     *container,
@@ -38,71 +64,150 @@ static void gtk_viewport_size_request             (GtkWidget        *widget,
                                                   GtkRequisition   *requisition);
 static void gtk_viewport_size_allocate            (GtkWidget        *widget,
                                                   GtkAllocation    *allocation);
-static gint gtk_viewport_need_resize              (GtkContainer     *container);
-static void gtk_viewport_adjustment_changed       (GtkAdjustment    *adjustment,
-                                                  gpointer          data);
 static void gtk_viewport_adjustment_value_changed (GtkAdjustment    *adjustment,
                                                   gpointer          data);
+static void gtk_viewport_style_set                (GtkWidget *widget,
+                                                  GtkStyle  *previous_style);
 
-static GtkBinClass *parent_class;
-
-guint
-gtk_viewport_get_type ()
-{
-  static guint viewport_type = 0;
-
-  if (!viewport_type)
-    {
-      GtkTypeInfo viewport_info =
-      {
-       "GtkViewport",
-       sizeof (GtkViewport),
-       sizeof (GtkViewportClass),
-       (GtkClassInitFunc) gtk_viewport_class_init,
-       (GtkObjectInitFunc) gtk_viewport_init,
-       (GtkArgSetFunc) NULL,
-        (GtkArgGetFunc) NULL,
-      };
-
-      viewport_type = gtk_type_unique (gtk_bin_get_type (), &viewport_info);
-    }
-
-  return viewport_type;
-}
+G_DEFINE_TYPE (GtkViewport, gtk_viewport, GTK_TYPE_BIN)
 
 static void
 gtk_viewport_class_init (GtkViewportClass *class)
 {
   GtkObjectClass *object_class;
+  GObjectClass   *gobject_class;
   GtkWidgetClass *widget_class;
   GtkContainerClass *container_class;
 
   object_class = (GtkObjectClass*) class;
+  gobject_class = G_OBJECT_CLASS (class);
   widget_class = (GtkWidgetClass*) class;
   container_class = (GtkContainerClass*) class;
-  parent_class = (GtkBinClass*) gtk_type_class (gtk_bin_get_type ());
 
-  object_class->finalize = gtk_viewport_finalize;
+  gobject_class->finalize = gtk_viewport_finalize;
+  gobject_class->set_property = gtk_viewport_set_property;
+  gobject_class->get_property = gtk_viewport_get_property;
+  object_class->destroy = gtk_viewport_destroy;
   
-  widget_class->map = gtk_viewport_map;
-  widget_class->unmap = gtk_viewport_unmap;
   widget_class->realize = gtk_viewport_realize;
   widget_class->unrealize = gtk_viewport_unrealize;
-  widget_class->draw = gtk_viewport_draw;
   widget_class->expose_event = gtk_viewport_expose;
   widget_class->size_request = gtk_viewport_size_request;
   widget_class->size_allocate = gtk_viewport_size_allocate;
-
+  widget_class->style_set = gtk_viewport_style_set;
+  
   container_class->add = gtk_viewport_add;
-  container_class->need_resize = gtk_viewport_need_resize;
+
+  class->set_scroll_adjustments = gtk_viewport_set_scroll_adjustments;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_HADJUSTMENT,
+                                   g_param_spec_object ("hadjustment",
+                                                       P_("Horizontal adjustment"),
+                                                       P_("The GtkAdjustment that determines the values of the horizontal position for this viewport"),
+                                                        GTK_TYPE_ADJUSTMENT,
+                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_VADJUSTMENT,
+                                   g_param_spec_object ("vadjustment",
+                                                       P_("Vertical adjustment"),
+                                                       P_("The GtkAdjustment that determines the values of the vertical position for this viewport"),
+                                                        GTK_TYPE_ADJUSTMENT,
+                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_SHADOW_TYPE,
+                                   g_param_spec_enum ("shadow-type",
+                                                     P_("Shadow type"),
+                                                     P_("Determines how the shadowed box around the viewport is drawn"),
+                                                     GTK_TYPE_SHADOW_TYPE,
+                                                     GTK_SHADOW_IN,
+                                                     GTK_PARAM_READWRITE));
+
+  /**
+   * GtkViewport::set-scroll-adjustments
+   * @horizontal: the horizontal #GtkAdjustment
+   * @vertical: the vertical #GtkAdjustment
+   *
+   * Set the scroll adjustments for the viewport. Usually scrolled containers
+   * like #GtkScrolledWindow will emit this signal to connect two instances
+   * of #GtkScrollbar to the scroll directions of the #GtkViewport.
+   */
+  widget_class->set_scroll_adjustments_signal =
+    g_signal_new (I_("set-scroll-adjustments"),
+                 G_OBJECT_CLASS_TYPE (gobject_class),
+                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                 G_STRUCT_OFFSET (GtkViewportClass, set_scroll_adjustments),
+                 NULL, NULL,
+                 _gtk_marshal_VOID__OBJECT_OBJECT,
+                 G_TYPE_NONE, 2,
+                 GTK_TYPE_ADJUSTMENT,
+                 GTK_TYPE_ADJUSTMENT);
+}
+
+static void
+gtk_viewport_set_property (GObject         *object,
+                          guint            prop_id,
+                          const GValue    *value,
+                          GParamSpec      *pspec)
+{
+  GtkViewport *viewport;
+
+  viewport = GTK_VIEWPORT (object);
+
+  switch (prop_id)
+    {
+    case PROP_HADJUSTMENT:
+      gtk_viewport_set_hadjustment (viewport, g_value_get_object (value));
+      break;
+    case PROP_VADJUSTMENT:
+      gtk_viewport_set_vadjustment (viewport, g_value_get_object (value));
+      break;
+    case PROP_SHADOW_TYPE:
+      gtk_viewport_set_shadow_type (viewport, g_value_get_enum (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_viewport_get_property (GObject         *object,
+                          guint            prop_id,
+                          GValue          *value,
+                          GParamSpec      *pspec)
+{
+  GtkViewport *viewport;
+
+  viewport = GTK_VIEWPORT (object);
+
+  switch (prop_id)
+    {
+    case PROP_HADJUSTMENT:
+      g_value_set_object (value, viewport->hadjustment);
+      break;
+    case PROP_VADJUSTMENT:
+      g_value_set_object (value, viewport->vadjustment);
+      break;
+    case PROP_SHADOW_TYPE:
+      g_value_set_enum (value, viewport->shadow_type);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 static void
 gtk_viewport_init (GtkViewport *viewport)
 {
   GTK_WIDGET_UNSET_FLAGS (viewport, GTK_NO_WINDOW);
-  GTK_WIDGET_SET_FLAGS (viewport, GTK_BASIC);
 
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (viewport), FALSE);
+  gtk_container_set_resize_mode (GTK_CONTAINER (viewport), GTK_RESIZE_QUEUE);
+  
   viewport->shadow_type = GTK_SHADOW_IN;
   viewport->view_window = NULL;
   viewport->bin_window = NULL;
@@ -110,197 +215,394 @@ gtk_viewport_init (GtkViewport *viewport)
   viewport->vadjustment = NULL;
 }
 
+/**
+ * gtk_viewport_new:
+ * @hadjustment: horizontal adjustment.
+ * @vadjustment: vertical adjustment.
+ * @returns: a new #GtkViewport.
+ *
+ * Creates a new #GtkViewport with the given adjustments.
+ *
+ **/
 GtkWidget*
 gtk_viewport_new (GtkAdjustment *hadjustment,
                  GtkAdjustment *vadjustment)
 {
-  GtkViewport *viewport;
+  GtkWidget *viewport;
 
-  viewport = gtk_type_new (gtk_viewport_get_type ());
+  viewport = g_object_new (GTK_TYPE_VIEWPORT,
+                            "hadjustment", hadjustment,
+                            "vadjustment", vadjustment,
+                            NULL);
 
-  if (!hadjustment)
-    hadjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+  return viewport;
+}
 
-  if (!vadjustment)
-    vadjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+#define ADJUSTMENT_POINTER(viewport, orientation)         \
+  (((orientation) == GTK_ORIENTATION_HORIZONTAL) ?        \
+     &(viewport)->hadjustment : &(viewport)->vadjustment)
 
-  gtk_viewport_set_hadjustment (viewport, hadjustment);
-  gtk_viewport_set_vadjustment (viewport, vadjustment);
+static void
+viewport_disconnect_adjustment (GtkViewport    *viewport,
+                               GtkOrientation  orientation)
+{
+  GtkAdjustment **adjustmentp = ADJUSTMENT_POINTER (viewport, orientation);
+
+  if (*adjustmentp)
+    {
+      g_signal_handlers_disconnect_by_func (*adjustmentp,
+                                           gtk_viewport_adjustment_value_changed,
+                                           viewport);
+      g_object_unref (*adjustmentp);
+      *adjustmentp = NULL;
+    }
+}
+
+static void
+gtk_viewport_finalize (GObject *object)
+{
+  GtkViewport *viewport = GTK_VIEWPORT (object);
 
-  return GTK_WIDGET (viewport);
+  viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL);
+  viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL);
+
+  G_OBJECT_CLASS (gtk_viewport_parent_class)->finalize (object);
 }
 
 static void
-gtk_viewport_finalize (GtkObject *object)
+gtk_viewport_destroy (GtkObject *object)
 {
   GtkViewport *viewport = GTK_VIEWPORT (object);
 
-  gtk_object_unref (GTK_OBJECT (viewport->hadjustment));
-  gtk_object_unref (GTK_OBJECT (viewport->vadjustment));
+  viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL);
+  viewport_disconnect_adjustment (viewport, GTK_ORIENTATION_VERTICAL);
 
-  GTK_OBJECT_CLASS(parent_class)->finalize (object);
+  GTK_OBJECT_CLASS (gtk_viewport_parent_class)->destroy (object);
 }
 
+/**
+ * gtk_viewport_get_hadjustment:
+ * @viewport: a #GtkViewport.
+ * 
+ * Returns the horizontal adjustment of the viewport.
+ *
+ * Return value: the horizontal adjustment of @viewport.
+ **/
 GtkAdjustment*
 gtk_viewport_get_hadjustment (GtkViewport *viewport)
 {
-  g_return_val_if_fail (viewport != NULL, NULL);
   g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
 
+  if (!viewport->hadjustment)
+    gtk_viewport_set_hadjustment (viewport, NULL);
+
   return viewport->hadjustment;
 }
 
+/**
+ * gtk_viewport_get_vadjustment:
+ * @viewport: a #GtkViewport.
+ * 
+ * Returns the vertical adjustment of the viewport.
+ *
+ * Return value: the vertical adjustment of @viewport.
+ **/
 GtkAdjustment*
 gtk_viewport_get_vadjustment (GtkViewport *viewport)
 {
-  g_return_val_if_fail (viewport != NULL, NULL);
   g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
 
+  if (!viewport->vadjustment)
+    gtk_viewport_set_vadjustment (viewport, NULL);
+
   return viewport->vadjustment;
 }
 
+static void
+viewport_get_view_allocation (GtkViewport   *viewport,
+                             GtkAllocation *view_allocation)
+{
+  GtkWidget *widget = GTK_WIDGET (viewport);
+  GtkAllocation *allocation = &widget->allocation;
+  gint border_width = GTK_CONTAINER (viewport)->border_width;
+  
+  view_allocation->x = 0;
+  view_allocation->y = 0;
+
+  if (viewport->shadow_type != GTK_SHADOW_NONE)
+    {
+      view_allocation->x = widget->style->xthickness;
+      view_allocation->y = widget->style->ythickness;
+    }
+
+  view_allocation->width = MAX (1, allocation->width - view_allocation->x * 2 - border_width * 2);
+  view_allocation->height = MAX (1, allocation->height - view_allocation->y * 2 - border_width * 2);
+}
+
+static void
+viewport_reclamp_adjustment (GtkAdjustment *adjustment,
+                            gboolean      *value_changed)
+{
+  gdouble value = adjustment->value;
+  
+  value = CLAMP (value, 0, adjustment->upper - adjustment->page_size);
+  if (value != adjustment->value)
+    {
+      adjustment->value = value;
+      if (value_changed)
+       *value_changed = TRUE;
+    }
+  else if (value_changed)
+    *value_changed = FALSE;
+}
+
+static void
+viewport_set_hadjustment_values (GtkViewport *viewport,
+                                gboolean    *value_changed)
+{
+  GtkBin *bin = GTK_BIN (viewport);
+  GtkAllocation view_allocation;
+  GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
+  gdouble old_page_size;
+  gdouble old_upper;
+  gdouble old_value;
+  
+  viewport_get_view_allocation (viewport, &view_allocation);  
+
+  old_page_size = hadjustment->page_size;
+  old_upper = hadjustment->upper;
+  old_value = hadjustment->value;
+  hadjustment->page_size = view_allocation.width;
+  hadjustment->step_increment = view_allocation.width * 0.1;
+  hadjustment->page_increment = view_allocation.width * 0.9;
+  
+  hadjustment->lower = 0;
+
+  if (bin->child && gtk_widget_get_visible (bin->child))
+    {
+      GtkRequisition child_requisition;
+      
+      gtk_widget_get_child_requisition (bin->child, &child_requisition);
+      hadjustment->upper = MAX (child_requisition.width, view_allocation.width);
+    }
+  else
+    hadjustment->upper = view_allocation.width;
+
+  if (gtk_widget_get_direction (GTK_WIDGET (viewport)) == GTK_TEXT_DIR_RTL) 
+    {
+      gdouble dist = old_upper - (old_value + old_page_size);
+      hadjustment->value = hadjustment->upper - dist - hadjustment->page_size;
+      viewport_reclamp_adjustment (hadjustment, value_changed);
+      *value_changed = (old_value != hadjustment->value);
+    }
+  else
+    viewport_reclamp_adjustment (hadjustment, value_changed);
+}
+
+static void
+viewport_set_vadjustment_values (GtkViewport *viewport,
+                                gboolean    *value_changed)
+{
+  GtkBin *bin = GTK_BIN (viewport);
+  GtkAllocation view_allocation;
+  GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
+
+  viewport_get_view_allocation (viewport, &view_allocation);  
+
+  vadjustment->page_size = view_allocation.height;
+  vadjustment->step_increment = view_allocation.height * 0.1;
+  vadjustment->page_increment = view_allocation.height * 0.9;
+  
+  vadjustment->lower = 0;
+
+  if (bin->child && gtk_widget_get_visible (bin->child))
+    {
+      GtkRequisition child_requisition;
+      
+      gtk_widget_get_child_requisition (bin->child, &child_requisition);
+      vadjustment->upper = MAX (child_requisition.height, view_allocation.height);
+    }
+  else
+    vadjustment->upper = view_allocation.height;
+
+  viewport_reclamp_adjustment (vadjustment, value_changed);
+}
+
+static void
+viewport_set_adjustment (GtkViewport    *viewport,
+                        GtkOrientation  orientation,
+                        GtkAdjustment  *adjustment)
+{
+  GtkAdjustment **adjustmentp = ADJUSTMENT_POINTER (viewport, orientation);
+  gboolean value_changed;
+
+  if (adjustment && adjustment == *adjustmentp)
+    return;
+
+  if (!adjustment)
+    adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0,
+                                                    0.0, 0.0, 0.0));
+  viewport_disconnect_adjustment (viewport, orientation);
+  *adjustmentp = adjustment;
+  g_object_ref_sink (adjustment);
+
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    viewport_set_hadjustment_values (viewport, &value_changed);
+  else
+    viewport_set_vadjustment_values (viewport, &value_changed);
+
+  g_signal_connect (adjustment, "value-changed",
+                   G_CALLBACK (gtk_viewport_adjustment_value_changed),
+                   viewport);
+
+  gtk_adjustment_changed (adjustment);
+  
+  if (value_changed)
+    gtk_adjustment_value_changed (adjustment);
+  else
+    gtk_viewport_adjustment_value_changed (adjustment, viewport);
+}
+
+/**
+ * gtk_viewport_set_hadjustment:
+ * @viewport: a #GtkViewport.
+ * @adjustment: (allow-none): a #GtkAdjustment.
+ *
+ * Sets the horizontal adjustment of the viewport.
+ **/
 void
 gtk_viewport_set_hadjustment (GtkViewport   *viewport,
                              GtkAdjustment *adjustment)
 {
-  g_return_if_fail (viewport != NULL);
   g_return_if_fail (GTK_IS_VIEWPORT (viewport));
-  g_return_if_fail (adjustment != NULL);
+  if (adjustment)
+    g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
 
-  if (viewport->hadjustment != adjustment)
-    {
-      if (viewport->hadjustment)
-       {
-         gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->hadjustment),
-                                        (gpointer) viewport);
-         gtk_object_unref (GTK_OBJECT (viewport->hadjustment));
-       }
+  viewport_set_adjustment (viewport, GTK_ORIENTATION_HORIZONTAL, adjustment);
 
-      viewport->hadjustment = adjustment;
-      gtk_object_ref (GTK_OBJECT (viewport->hadjustment));
-      gtk_object_sink (GTK_OBJECT (viewport->hadjustment));
-      
-      gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
-                         (GtkSignalFunc) gtk_viewport_adjustment_changed,
-                         (gpointer) viewport);
-      gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
-                         (GtkSignalFunc)gtk_viewport_adjustment_value_changed,
-                         (gpointer) viewport);
-
-      gtk_viewport_adjustment_changed (adjustment, (gpointer) viewport);
-    }
+  g_object_notify (G_OBJECT (viewport), "hadjustment");
 }
 
+/**
+ * gtk_viewport_set_vadjustment:
+ * @viewport: a #GtkViewport.
+ * @adjustment: (allow-none): a #GtkAdjustment.
+ *
+ * Sets the vertical adjustment of the viewport.
+ **/
 void
 gtk_viewport_set_vadjustment (GtkViewport   *viewport,
                              GtkAdjustment *adjustment)
 {
-  g_return_if_fail (viewport != NULL);
   g_return_if_fail (GTK_IS_VIEWPORT (viewport));
-  g_return_if_fail (adjustment != NULL);
+  if (adjustment)
+    g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
 
-  if (viewport->vadjustment != adjustment)
-    {
-      if (viewport->vadjustment)
-       {
-         gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->vadjustment),
-                                        (gpointer) viewport);
-         gtk_object_unref (GTK_OBJECT (viewport->vadjustment));
-       }
+  viewport_set_adjustment (viewport, GTK_ORIENTATION_VERTICAL, adjustment);
 
-      viewport->vadjustment = adjustment;
-      gtk_object_ref (GTK_OBJECT (viewport->vadjustment));
-      gtk_object_sink (GTK_OBJECT (viewport->vadjustment));
-      
-      gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
-                         (GtkSignalFunc) gtk_viewport_adjustment_changed,
-                         (gpointer) viewport);
-      gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
-                         (GtkSignalFunc)gtk_viewport_adjustment_value_changed,
-                         (gpointer) viewport);
-
-      gtk_viewport_adjustment_changed (adjustment, (gpointer) viewport);
-    }
+  g_object_notify (G_OBJECT (viewport), "vadjustment");
 }
 
+static void
+gtk_viewport_set_scroll_adjustments (GtkViewport      *viewport,
+                                    GtkAdjustment    *hadjustment,
+                                    GtkAdjustment    *vadjustment)
+{
+  gtk_viewport_set_hadjustment (viewport, hadjustment);
+  gtk_viewport_set_vadjustment (viewport, vadjustment);
+}
+
+/** 
+ * gtk_viewport_set_shadow_type:
+ * @viewport: a #GtkViewport.
+ * @type: the new shadow type.
+ *
+ * Sets the shadow type of the viewport.
+ **/ 
 void
 gtk_viewport_set_shadow_type (GtkViewport   *viewport,
                              GtkShadowType  type)
 {
-  g_return_if_fail (viewport != NULL);
   g_return_if_fail (GTK_IS_VIEWPORT (viewport));
 
   if ((GtkShadowType) viewport->shadow_type != type)
     {
       viewport->shadow_type = type;
 
-      if (GTK_WIDGET_VISIBLE (viewport))
+      if (gtk_widget_get_visible (GTK_WIDGET (viewport)))
        {
          gtk_widget_size_allocate (GTK_WIDGET (viewport), &(GTK_WIDGET (viewport)->allocation));
          gtk_widget_queue_draw (GTK_WIDGET (viewport));
        }
+
+      g_object_notify (G_OBJECT (viewport), "shadow-type");
     }
 }
 
-
-static void
-gtk_viewport_map (GtkWidget *widget)
+/**
+ * gtk_viewport_get_shadow_type:
+ * @viewport: a #GtkViewport
+ *
+ * Gets the shadow type of the #GtkViewport. See
+ * gtk_viewport_set_shadow_type().
+ * Return value: the shadow type 
+ **/
+GtkShadowType
+gtk_viewport_get_shadow_type (GtkViewport *viewport)
 {
-  GtkBin *bin;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+  g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), GTK_SHADOW_NONE);
 
-  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
-  bin = GTK_BIN (widget);
-
-  gdk_window_show (widget->window);
-
-  if (bin->child &&
-      GTK_WIDGET_VISIBLE (bin->child) &&
-      !GTK_WIDGET_MAPPED (bin->child))
-    gtk_widget_map (bin->child);
+  return viewport->shadow_type;
 }
 
-static void
-gtk_viewport_unmap (GtkWidget *widget)
+/**
+ * gtk_viewport_get_bin_window:
+ * @viewport: a #GtkViewport
+ *
+ * Gets the bin window of the #GtkViewport.
+ *
+ * Return value: a #GdkWindow
+ *
+ * Since: 2.20
+ **/
+GdkWindow*
+gtk_viewport_get_bin_window (GtkViewport *viewport)
 {
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+  g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
 
-  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
-  
-  gdk_window_hide (widget->window);
+  return viewport->bin_window;
 }
 
 static void
 gtk_viewport_realize (GtkWidget *widget)
 {
-  GtkBin *bin;
-  GtkViewport *viewport;
+  GtkViewport *viewport = GTK_VIEWPORT (widget);
+  GtkBin *bin = GTK_BIN (widget);
+  GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
+  GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
+  gint border_width = GTK_CONTAINER (widget)->border_width;
+  
+  GtkAllocation view_allocation;
   GdkWindowAttr attributes;
-  GtkRequisition *child_requisition;
   gint attributes_mask;
   gint event_mask;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
-
-  bin = GTK_BIN (widget);
-  viewport = GTK_VIEWPORT (widget);
   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 
-  attributes.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
-  attributes.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
-  attributes.width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
-  attributes.height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;
+  attributes.x = widget->allocation.x + border_width;
+  attributes.y = widget->allocation.y + border_width;
+  attributes.width = widget->allocation.width - border_width * 2;
+  attributes.height = widget->allocation.height - border_width * 2;
   attributes.window_type = GDK_WINDOW_CHILD;
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (widget);
   attributes.colormap = gtk_widget_get_colormap (widget);
 
   event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
-  attributes.event_mask = event_mask;
+  /* We select on button_press_mask so that button 4-5 scrolls are trapped.
+   */
+  attributes.event_mask = event_mask | GDK_BUTTON_PRESS_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
@@ -308,35 +610,43 @@ gtk_viewport_realize (GtkWidget *widget)
                                   &attributes, attributes_mask);
   gdk_window_set_user_data (widget->window, viewport);
 
-  attributes.x += widget->style->klass->xthickness;
-  attributes.y += widget->style->klass->ythickness;
-  attributes.width -= widget->style->klass->xthickness * 2;
-  attributes.height -= widget->style->klass->ythickness * 2;
+  viewport_get_view_allocation (viewport, &view_allocation);
+  
+  attributes.x = view_allocation.x;
+  attributes.y = view_allocation.y;
+  attributes.width = view_allocation.width;
+  attributes.height = view_allocation.height;
   attributes.event_mask = 0;
 
   viewport->view_window = gdk_window_new (widget->window, &attributes, attributes_mask);
   gdk_window_set_user_data (viewport->view_window, viewport);
 
-  attributes.x = 0;
-  attributes.y = 0;
+  gdk_window_set_back_pixmap (viewport->view_window, NULL, FALSE);
+  
+  attributes.x = - hadjustment->value;
+  attributes.y = - vadjustment->value;
+  attributes.width = hadjustment->upper;
+  attributes.height = vadjustment->upper;
+  
   attributes.event_mask = event_mask;
 
   viewport->bin_window = gdk_window_new (viewport->view_window, &attributes, attributes_mask);
   gdk_window_set_user_data (viewport->bin_window, viewport);
 
   if (bin->child)
-    {
-      child_requisition = &GTK_WIDGET (GTK_BIN (viewport)->child)->requisition;
-      attributes.width = child_requisition->width;
-      attributes.height = child_requisition->height;
-
-      gtk_widget_set_parent_window (bin->child, viewport->bin_window);
-    }
+    gtk_widget_set_parent_window (bin->child, viewport->bin_window);
 
   widget->style = gtk_style_attach (widget->style, widget->window);
   gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
   gtk_style_set_background (widget->style, viewport->bin_window, GTK_STATE_NORMAL);
-  
+
+  /* Call paint here to allow a theme to set the background without flashing
+   */
+  gtk_paint_flat_box(widget->style, viewport->bin_window, GTK_STATE_NORMAL,
+                    GTK_SHADOW_NONE,
+                    NULL, widget, "viewportbin",
+                    0, 0, -1, -1);
+   
   gdk_window_show (viewport->bin_window);
   gdk_window_show (viewport->view_window);
 }
@@ -344,12 +654,7 @@ gtk_viewport_realize (GtkWidget *widget)
 static void
 gtk_viewport_unrealize (GtkWidget *widget)
 {
-  GtkViewport *viewport;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
-
-  viewport = GTK_VIEWPORT (widget);
+  GtkViewport *viewport = GTK_VIEWPORT (widget);
 
   gdk_window_set_user_data (viewport->view_window, NULL);
   gdk_window_destroy (viewport->view_window);
@@ -359,65 +664,21 @@ gtk_viewport_unrealize (GtkWidget *widget)
   gdk_window_destroy (viewport->bin_window);
   viewport->bin_window = NULL;
 
-  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
-    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+  GTK_WIDGET_CLASS (gtk_viewport_parent_class)->unrealize (widget);
 }
 
 static void
 gtk_viewport_paint (GtkWidget    *widget,
                    GdkRectangle *area)
 {
-  GtkViewport *viewport;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
-  g_return_if_fail (area != NULL);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      viewport = GTK_VIEWPORT (widget);
-
-      gtk_draw_shadow (widget->style, widget->window,
-                      GTK_STATE_NORMAL, viewport->shadow_type,
-                      0, 0, -1, -1);
-    }
-}
-
-static void
-gtk_viewport_draw (GtkWidget    *widget,
-                  GdkRectangle *area)
-{
-  GtkViewport *viewport;
-  GtkBin *bin;
-  GdkRectangle tmp_area;
-  GdkRectangle child_area;
-  gint border_width;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
-  g_return_if_fail (area != NULL);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
+  if (gtk_widget_is_drawable (widget))
     {
-      viewport = GTK_VIEWPORT (widget);
-      bin = GTK_BIN (widget);
-
-      border_width = GTK_CONTAINER (widget)->border_width;
-      
-      tmp_area = *area;
-      tmp_area.x -= border_width;
-      tmp_area.y -= border_width;
-      
-      gtk_viewport_paint (widget, &tmp_area);
-
-      if (bin->child)
-       {
-         tmp_area.x += viewport->hadjustment->value - widget->style->klass->xthickness;
-         tmp_area.y += viewport->vadjustment->value - widget->style->klass->ythickness;
+      GtkViewport *viewport = GTK_VIEWPORT (widget);
 
-         if (gtk_widget_intersect (bin->child, &tmp_area, &child_area))
-           gtk_widget_draw (bin->child, &child_area);
-       }
+      gtk_paint_shadow (widget->style, widget->window,
+                       GTK_STATE_NORMAL, viewport->shadow_type,
+                       area, widget, "viewport",
+                       0, 0, -1, -1);
     }
 }
 
@@ -426,27 +687,22 @@ gtk_viewport_expose (GtkWidget      *widget,
                     GdkEventExpose *event)
 {
   GtkViewport *viewport;
-  GtkBin *bin;
-  GdkEventExpose child_event;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_VIEWPORT (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
+  if (gtk_widget_is_drawable (widget))
     {
       viewport = GTK_VIEWPORT (widget);
-      bin = GTK_BIN (widget);
 
       if (event->window == widget->window)
        gtk_viewport_paint (widget, &event->area);
+      else if (event->window == viewport->bin_window)
+       {
+         gtk_paint_flat_box(widget->style, viewport->bin_window, 
+                            GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+                            &event->area, widget, "viewportbin",
+                            0, 0, -1, -1);
 
-      child_event = *event;
-      if ((event->window == viewport->bin_window) &&
-         (bin->child != NULL) &&
-         GTK_WIDGET_NO_WINDOW (bin->child) &&
-         gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-       gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+         GTK_WIDGET_CLASS (gtk_viewport_parent_class)->expose_event (widget, event);
+       }
     }
 
   return FALSE;
@@ -454,237 +710,144 @@ gtk_viewport_expose (GtkWidget      *widget,
 
 static void
 gtk_viewport_add (GtkContainer *container,
-                 GtkWidget    *widget)
+                 GtkWidget    *child)
 {
-  GtkBin *bin;
-
-  g_return_if_fail (container != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (container));
-  g_return_if_fail (widget != NULL);
+  GtkBin *bin = GTK_BIN (container);
 
-  bin = GTK_BIN (container);
-
-  if (!bin->child)
-    {
-      gtk_widget_set_parent (widget, GTK_WIDGET (container));
-      gtk_widget_set_parent_window (widget, GTK_VIEWPORT (container)->bin_window);
-      if (GTK_WIDGET_VISIBLE (widget->parent))
-       {
-         if (GTK_WIDGET_MAPPED (widget->parent) &&
-             !GTK_WIDGET_MAPPED (widget))
-           gtk_widget_map (widget);
-       }
+  g_return_if_fail (bin->child == NULL);
 
-      bin->child = widget;
+  gtk_widget_set_parent_window (child, GTK_VIEWPORT (bin)->bin_window);
 
-      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
-        gtk_widget_queue_resize (widget);
-    }
+  GTK_CONTAINER_CLASS (gtk_viewport_parent_class)->add (container, child);
 }
 
 static void
 gtk_viewport_size_request (GtkWidget      *widget,
                           GtkRequisition *requisition)
 {
-  GtkViewport *viewport;
-  GtkBin *bin;
+  GtkBin *bin = GTK_BIN (widget);
+  GtkRequisition child_requisition;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
-  g_return_if_fail (requisition != NULL);
+  requisition->width = GTK_CONTAINER (widget)->border_width;
 
-  viewport = GTK_VIEWPORT (widget);
-  bin = GTK_BIN (widget);
+  requisition->height = GTK_CONTAINER (widget)->border_width;
 
-  requisition->width = (GTK_CONTAINER (widget)->border_width +
-                       GTK_WIDGET (widget)->style->klass->xthickness) * 2 + 5;
-
-  requisition->height = (GTK_CONTAINER (widget)->border_width * 2 +
-                        GTK_WIDGET (widget)->style->klass->ythickness) * 2 + 5;
+  if (GTK_VIEWPORT (widget)->shadow_type != GTK_SHADOW_NONE)
+    {
+      requisition->width += 2 * widget->style->xthickness;
+      requisition->height += 2 * widget->style->ythickness;
+    }
 
-  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
-    gtk_widget_size_request (bin->child, &bin->child->requisition);
+  if (bin->child && gtk_widget_get_visible (bin->child))
+    {
+      gtk_widget_size_request (bin->child, &child_requisition);
+      requisition->width += child_requisition.width;
+      requisition->height += child_requisition.height;
+    }
 }
 
 static void
 gtk_viewport_size_allocate (GtkWidget     *widget,
                            GtkAllocation *allocation)
 {
-  GtkViewport *viewport;
-  GtkBin *bin;
+  GtkViewport *viewport = GTK_VIEWPORT (widget);
+  GtkBin *bin = GTK_BIN (widget);
+  gint border_width = GTK_CONTAINER (widget)->border_width;
+  gboolean hadjustment_value_changed, vadjustment_value_changed;
+  GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
+  GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
   GtkAllocation child_allocation;
-  gint hval, vval;
-  gint border_width;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (widget));
-  g_return_if_fail (allocation != NULL);
 
+  /* If our size changed, and we have a shadow, queue a redraw on widget->window to
+   * redraw the shadow correctly.
+   */
+  if (gtk_widget_get_mapped (widget) &&
+      viewport->shadow_type != GTK_SHADOW_NONE &&
+      (widget->allocation.width != allocation->width ||
+       widget->allocation.height != allocation->height))
+    gdk_window_invalidate_rect (widget->window, NULL, FALSE);
+  
   widget->allocation = *allocation;
-  viewport = GTK_VIEWPORT (widget);
-  bin = GTK_BIN (widget);
-
-  border_width = GTK_CONTAINER (widget)->border_width;
-
+  
+  viewport_set_hadjustment_values (viewport, &hadjustment_value_changed);
+  viewport_set_vadjustment_values (viewport, &vadjustment_value_changed);
+  
   child_allocation.x = 0;
   child_allocation.y = 0;
-
-  if (viewport->shadow_type != GTK_SHADOW_NONE)
-    {
-      child_allocation.x = GTK_WIDGET (viewport)->style->klass->xthickness;
-      child_allocation.y = GTK_WIDGET (viewport)->style->klass->ythickness;
-    }
-
-  child_allocation.width = allocation->width - child_allocation.x * 2 - border_width * 2;
-  child_allocation.height = allocation->height - child_allocation.y * 2 - border_width * 2;
-
+  child_allocation.width = hadjustment->upper;
+  child_allocation.height = vadjustment->upper;
   if (GTK_WIDGET_REALIZED (widget))
     {
+      GtkAllocation view_allocation;
       gdk_window_move_resize (widget->window,
                              allocation->x + border_width,
                              allocation->y + border_width,
                              allocation->width - border_width * 2,
                              allocation->height - border_width * 2);
-
+      
+      viewport_get_view_allocation (viewport, &view_allocation);
       gdk_window_move_resize (viewport->view_window,
-                             child_allocation.x,
-                             child_allocation.y,
-                             child_allocation.width,
-                             child_allocation.height);
-    }
-
-  viewport->hadjustment->page_size = child_allocation.width;
-  viewport->hadjustment->page_increment = viewport->hadjustment->page_size / 2;
-  viewport->hadjustment->step_increment = 10;
-
-  viewport->vadjustment->page_size = child_allocation.height;
-  viewport->vadjustment->page_increment = viewport->vadjustment->page_size / 2;
-  viewport->vadjustment->step_increment = 10;
-
-  hval = viewport->hadjustment->value;
-  vval = viewport->vadjustment->value;
-
-  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
-    {
-      viewport->hadjustment->lower = 0;
-      viewport->hadjustment->upper = MAX (bin->child->requisition.width,
-                                         child_allocation.width);
-
-      hval = CLAMP (hval, 0,
-                   viewport->hadjustment->upper -
-                   viewport->hadjustment->page_size);
-
-      viewport->vadjustment->lower = 0;
-      viewport->vadjustment->upper = MAX (bin->child->requisition.height,
-                                         child_allocation.height);
-
-      vval = CLAMP (vval, 0,
-                   viewport->vadjustment->upper -
-                   viewport->vadjustment->page_size);
-    }
-
-  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
-    {
-      child_allocation.x = 0;
-      child_allocation.y = 0;
-
-      child_allocation.width = viewport->hadjustment->upper;
-      child_allocation.height = viewport->vadjustment->upper;
-
-      if (!GTK_WIDGET_REALIZED (widget))
-        gtk_widget_realize (widget);
-
-      gdk_window_resize (viewport->bin_window,
-                        child_allocation.width,
-                        child_allocation.height);
-
-      child_allocation.x = 0;
-      child_allocation.y = 0;
-      gtk_widget_size_allocate (bin->child, &child_allocation);
-    }
-
-  gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "changed");
-  gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "changed");
-  if (viewport->hadjustment->value != hval)
-    {
-      viewport->hadjustment->value = hval;
-      gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "value_changed");
-    }
-  if (viewport->vadjustment->value != vval)
-    {
-      viewport->vadjustment->value = vval;
-      gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "value_changed");
+                             view_allocation.x,
+                             view_allocation.y,
+                             view_allocation.width,
+                             view_allocation.height);
+      gdk_window_move_resize (viewport->bin_window,
+                              - hadjustment->value,
+                              - vadjustment->value,
+                              child_allocation.width,
+                              child_allocation.height);
     }
+  if (bin->child && gtk_widget_get_visible (bin->child))
+    gtk_widget_size_allocate (bin->child, &child_allocation);
+
+  gtk_adjustment_changed (hadjustment);
+  gtk_adjustment_changed (vadjustment);
+  if (hadjustment_value_changed)
+    gtk_adjustment_value_changed (hadjustment);
+  if (vadjustment_value_changed)
+    gtk_adjustment_value_changed (vadjustment);
 }
 
-static gint
-gtk_viewport_need_resize (GtkContainer *container)
+static void
+gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
+                                      gpointer       data)
 {
-  GtkBin *bin;
-
-  g_return_val_if_fail (container != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_VIEWPORT (container), FALSE);
+  GtkViewport *viewport = GTK_VIEWPORT (data);
+  GtkBin *bin = GTK_BIN (data);
 
-  if (GTK_WIDGET_REALIZED (container))
+  if (bin->child && gtk_widget_get_visible (bin->child)  &&
+      GTK_WIDGET_REALIZED (viewport))
     {
-      bin = GTK_BIN (container);
+      GtkAdjustment *hadjustment = gtk_viewport_get_hadjustment (viewport);
+      GtkAdjustment *vadjustment = gtk_viewport_get_vadjustment (viewport);
+      gint old_x, old_y;
+      gint new_x, new_y;
 
-      gtk_widget_size_request (bin->child, &bin->child->requisition);
+      gdk_window_get_position (viewport->bin_window, &old_x, &old_y);
+      new_x = - hadjustment->value;
+      new_y = - vadjustment->value;
 
-      gtk_widget_size_allocate (GTK_WIDGET (container),
-                               &(GTK_WIDGET (container)->allocation));
+      if (new_x != old_x || new_y != old_y)
+       {
+         gdk_window_move (viewport->bin_window, new_x, new_y);
+         gdk_window_process_updates (viewport->bin_window, TRUE);
+       }
     }
-
-  return FALSE;
 }
 
 static void
-gtk_viewport_adjustment_changed (GtkAdjustment *adjustment,
-                                gpointer       data)
+gtk_viewport_style_set (GtkWidget *widget,
+                       GtkStyle  *previous_style)
 {
-  GtkViewport *viewport;
-
-  g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (data));
-
-  viewport = GTK_VIEWPORT (data);
+   if (GTK_WIDGET_REALIZED (widget) &&
+       gtk_widget_get_has_window (widget))
+     {
+       GtkViewport *viewport = GTK_VIEWPORT (widget);
+
+       gtk_style_set_background (widget->style, viewport->bin_window, GTK_STATE_NORMAL);
+       gtk_style_set_background (widget->style, widget->window, widget->state);
+     }
 }
 
-static void
-gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
-                                      gpointer       data)
-{
-  GtkViewport *viewport;
-  GtkBin *bin;
-  GtkAllocation child_allocation;
-  gint width, height;
-
-  g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
-  g_return_if_fail (GTK_IS_VIEWPORT (data));
-
-  viewport = GTK_VIEWPORT (data);
-  bin = GTK_BIN (data);
-
-  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
-    {
-      gdk_window_get_size (viewport->view_window, &width, &height);
-
-      child_allocation.x = 0;
-      child_allocation.y = 0;
-
-      if (viewport->hadjustment->lower != (viewport->hadjustment->upper -
-                                          viewport->hadjustment->page_size))
-       child_allocation.x =  viewport->hadjustment->lower - viewport->hadjustment->value;
-
-      if (viewport->vadjustment->lower != (viewport->vadjustment->upper -
-                                          viewport->vadjustment->page_size))
-       child_allocation.y = viewport->vadjustment->lower - viewport->vadjustment->value;
-
-      if (GTK_WIDGET_REALIZED (viewport))
-       gdk_window_move (viewport->bin_window,
-                        child_allocation.x,
-                        child_allocation.y);
-    }
-}
+#define __GTK_VIEWPORT_C__
+#include "gtkaliasdef.c"