]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkclist.c
Replace a lot of idle and timeout calls by the new gdk_threads api.
[~andy/gtk] / gtk / gtkclist.c
index ef9922b19ceeaf753054c52ee1553c6b8a5d90ae..652c2e9ff91ae23994495fa9beb2e6d06709b51d 100644 (file)
@@ -3,44 +3,49 @@
  * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org>  
  *
  * 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
+ * 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.
  */
 
 /*
- * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * 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/. 
  */
 
+#undef GDK_DISABLE_DEPRECATED
+#undef GTK_DISABLE_DEPRECATED
+
+#include <config.h>
+
 #include <stdlib.h>
 #include <string.h>
-#include "config.h"
+
 #include "gtkmain.h"
+#include "gtkobject.h"
 #include "gtkclist.h"
 #include "gtkbindings.h"
 #include "gtkdnd.h"
-#include "gdkx.h"
+#include "gtkmarshalers.h"
+#include "gtkintl.h"
 #include <gdk/gdkkeysyms.h>
+#include "gtkalias.h"
 
 /* length of button_actions array */
 #define MAX_BUTTON 5
 
-/* the number rows memchunk expands at a time */
-#define CLIST_OPTIMUM_SIZE 64
-
 /* the width of the column resize windows */
 #define DRAG_WIDTH  6
 
@@ -123,19 +128,22 @@ LIST_WIDTH (GtkCList * clist)
   return 0;
 }
 
-#define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (((GtkObject*) (_widget_))->klass)
+/* returns the GList item for the nth row */
+#define        ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \
+                                (clist)->row_list_end : \
+                                g_list_nth ((clist)->row_list, (row)))
+
 
 /* redraw the list if it's not frozen */
 #define CLIST_UNFROZEN(clist)     (((GtkCList*) (clist))->freeze_count == 0)
 #define        CLIST_REFRESH(clist)    G_STMT_START { \
   if (CLIST_UNFROZEN (clist)) \
-    GTK_CLIST_CLASS_FW (clist)->refresh ((GtkCList*) (clist)); \
+    GTK_CLIST_GET_CLASS (clist)->refresh ((GtkCList*) (clist)); \
 } G_STMT_END
 
 
 /* Signals */
-enum
-{
+enum {
   SELECT_ROW,
   UNSELECT_ROW,
   ROW_MOVE,
@@ -155,8 +163,7 @@ enum
   LAST_SIGNAL
 };
 
-enum
-{
+enum {
   SYNC_REMOVE,
   SYNC_INSERT
 };
@@ -169,16 +176,20 @@ enum {
   ARG_ROW_HEIGHT,
   ARG_TITLES_ACTIVE,
   ARG_REORDERABLE,
-  ARG_USE_DRAG_ICONS
+  ARG_USE_DRAG_ICONS,
+  ARG_SORT_TYPE
 };
 
 /* GtkCList Methods */
-static void gtk_clist_class_init (GtkCListClass *klass);
-static void gtk_clist_init       (GtkCList      *clist);
+static void     gtk_clist_class_init  (GtkCListClass         *klass);
+static void     gtk_clist_init        (GtkCList              *clist);
+static GObject* gtk_clist_constructor (GType                  type,
+                                      guint                  n_construct_properties,
+                                      GObjectConstructParam *construct_params);
 
 /* GtkObject Methods */
 static void gtk_clist_destroy  (GtkObject *object);
-static void gtk_clist_finalize (GtkObject *object);
+static void gtk_clist_finalize (GObject   *object);
 static void gtk_clist_set_arg  (GtkObject *object,
                                GtkArg    *arg,
                                guint      arg_id);
@@ -194,12 +205,8 @@ static void gtk_clist_realize         (GtkWidget        *widget);
 static void gtk_clist_unrealize       (GtkWidget        *widget);
 static void gtk_clist_map             (GtkWidget        *widget);
 static void gtk_clist_unmap           (GtkWidget        *widget);
-static void gtk_clist_draw            (GtkWidget        *widget,
-                                      GdkRectangle     *area);
 static gint gtk_clist_expose          (GtkWidget        *widget,
                                       GdkEventExpose   *event);
-static gint gtk_clist_key_press       (GtkWidget        *widget,
-                                      GdkEventKey      *event);
 static gint gtk_clist_button_press    (GtkWidget        *widget,
                                       GdkEventButton   *event);
 static gint gtk_clist_button_release  (GtkWidget        *widget,
@@ -215,8 +222,10 @@ static gint gtk_clist_focus_in        (GtkWidget        *widget,
                                       GdkEventFocus    *event);
 static gint gtk_clist_focus_out       (GtkWidget        *widget,
                                       GdkEventFocus    *event);
-static gint gtk_clist_focus           (GtkContainer     *container,
+static gint gtk_clist_focus           (GtkWidget        *widget,
                                       GtkDirectionType  direction);
+static void gtk_clist_set_focus_child (GtkContainer     *container,
+                                      GtkWidget        *child);
 static void gtk_clist_style_set       (GtkWidget        *widget,
                                       GtkStyle         *previous_style);
 static void gtk_clist_drag_begin      (GtkWidget        *widget,
@@ -250,8 +259,6 @@ static void gtk_clist_drag_data_received (GtkWidget        *widget,
                                          guint             time);
 
 /* GtkContainer Methods */
-static void gtk_clist_set_focus_child (GtkContainer  *container,
-                                      GtkWidget     *child);
 static void gtk_clist_forall          (GtkContainer  *container,
                                       gboolean       include_internals,
                                       GtkCallback    callback,
@@ -357,7 +364,6 @@ static void column_button_clicked     (GtkWidget      *widget,
 /* Adjustments */
 static void adjust_adjustments        (GtkCList       *clist,
                                       gboolean        block_resize);
-static void check_exposures           (GtkCList       *clist);
 static void vadjustment_changed       (GtkAdjustment  *adjustment,
                                       gpointer        data);
 static void vadjustment_value_changed (GtkAdjustment  *adjustment,
@@ -438,21 +444,28 @@ static GList *gtk_clist_mergesort  (GtkCList      *clist,
                                    GList         *list,
                                    gint           num);
 /* Misc */
-static gboolean title_focus           (GtkCList  *clist,
-                                      gint       dir);
+static gboolean title_focus_in   (GtkCList *clist,
+                                 gint      dir);
+static gboolean title_focus_move (GtkCList *clist,
+                                 gint      dir);
+
 static void real_row_move             (GtkCList  *clist,
                                       gint       source_row,
                                       gint       dest_row);
 static gint column_title_passive_func (GtkWidget *widget, 
                                       GdkEvent  *event,
                                       gpointer   data);
+static void drag_dest_cell            (GtkCList         *clist,
+                                      gint              x,
+                                      gint              y,
+                                      GtkCListDestInfo *dest_info);
 
 
 
 static GtkContainerClass *parent_class = NULL;
 static guint clist_signals[LAST_SIGNAL] = {0};
 
-static GtkTargetEntry clist_target_table = { "gtk-clist-drag-reorder", 0, 0};
+static const GtkTargetEntry clist_target_table = { "gtk-clist-drag-reorder", 0, 0};
 
 GtkType
 gtk_clist_get_type (void)
@@ -473,6 +486,7 @@ gtk_clist_get_type (void)
        (GtkClassInitFunc) NULL,
       };
 
+      I_("GtkCList");
       clist_type = gtk_type_unique (GTK_TYPE_CONTAINER, &clist_info);
     }
 
@@ -482,243 +496,251 @@ gtk_clist_get_type (void)
 static void
 gtk_clist_class_init (GtkCListClass *klass)
 {
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GtkObjectClass *object_class;
   GtkWidgetClass *widget_class;
   GtkContainerClass *container_class;
   GtkBindingSet *binding_set;
 
+  gobject_class->constructor = gtk_clist_constructor;
+
   object_class = (GtkObjectClass *) klass;
   widget_class = (GtkWidgetClass *) klass;
   container_class = (GtkContainerClass *) klass;
 
   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
 
-  gtk_object_add_arg_type ("GtkCList::n_columns",
+  gobject_class->finalize = gtk_clist_finalize;
+  
+  object_class->set_arg = gtk_clist_set_arg;
+  object_class->get_arg = gtk_clist_get_arg;
+  object_class->destroy = gtk_clist_destroy;
+  
+
+  widget_class->realize = gtk_clist_realize;
+  widget_class->unrealize = gtk_clist_unrealize;
+  widget_class->map = gtk_clist_map;
+  widget_class->unmap = gtk_clist_unmap;
+  widget_class->button_press_event = gtk_clist_button_press;
+  widget_class->button_release_event = gtk_clist_button_release;
+  widget_class->motion_notify_event = gtk_clist_motion;
+  widget_class->expose_event = gtk_clist_expose;
+  widget_class->size_request = gtk_clist_size_request;
+  widget_class->size_allocate = gtk_clist_size_allocate;
+  widget_class->focus_in_event = gtk_clist_focus_in;
+  widget_class->focus_out_event = gtk_clist_focus_out;
+  widget_class->style_set = gtk_clist_style_set;
+  widget_class->drag_begin = gtk_clist_drag_begin;
+  widget_class->drag_end = gtk_clist_drag_end;
+  widget_class->drag_motion = gtk_clist_drag_motion;
+  widget_class->drag_leave = gtk_clist_drag_leave;
+  widget_class->drag_drop = gtk_clist_drag_drop;
+  widget_class->drag_data_get = gtk_clist_drag_data_get;
+  widget_class->drag_data_received = gtk_clist_drag_data_received;
+  widget_class->focus = gtk_clist_focus;
+  
+  /* container_class->add = NULL; use the default GtkContainerClass warning */
+  /* container_class->remove=NULL; use the default GtkContainerClass warning */
+
+  container_class->forall = gtk_clist_forall;
+  container_class->set_focus_child = gtk_clist_set_focus_child;
+
+  klass->set_scroll_adjustments = gtk_clist_set_scroll_adjustments;
+  klass->refresh = clist_refresh;
+  klass->select_row = real_select_row;
+  klass->unselect_row = real_unselect_row;
+  klass->row_move = real_row_move;
+  klass->undo_selection = real_undo_selection;
+  klass->resync_selection = resync_selection;
+  klass->selection_find = selection_find;
+  klass->click_column = NULL;
+  klass->resize_column = real_resize_column;
+  klass->draw_row = draw_row;
+  klass->draw_drag_highlight = draw_drag_highlight;
+  klass->insert_row = real_insert_row;
+  klass->remove_row = real_remove_row;
+  klass->clear = real_clear;
+  klass->sort_list = real_sort_list;
+  klass->select_all = real_select_all;
+  klass->unselect_all = real_unselect_all;
+  klass->fake_unselect_all = fake_unselect_all;
+  klass->scroll_horizontal = scroll_horizontal;
+  klass->scroll_vertical = scroll_vertical;
+  klass->extend_selection = extend_selection;
+  klass->toggle_focus_row = toggle_focus_row;
+  klass->toggle_add_mode = toggle_add_mode;
+  klass->start_selection = start_selection;
+  klass->end_selection = end_selection;
+  klass->abort_column_resize = abort_column_resize;
+  klass->set_cell_contents = set_cell_contents;
+  klass->cell_size_request = cell_size_request;
+
+  gtk_object_add_arg_type ("GtkCList::n-columns",
                           GTK_TYPE_UINT,
-                          GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY,
+                          GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME,
                           ARG_N_COLUMNS);
-  gtk_object_add_arg_type ("GtkCList::shadow_type",
+  gtk_object_add_arg_type ("GtkCList::shadow-type",
                           GTK_TYPE_SHADOW_TYPE,
-                          GTK_ARG_READWRITE,
+                          GTK_ARG_READWRITE | G_PARAM_STATIC_NAME,
                           ARG_SHADOW_TYPE);
-  gtk_object_add_arg_type ("GtkCList::selection_mode",
+  gtk_object_add_arg_type ("GtkCList::selection-mode",
                           GTK_TYPE_SELECTION_MODE,
-                          GTK_ARG_READWRITE,
+                          GTK_ARG_READWRITE | G_PARAM_STATIC_NAME,
                           ARG_SELECTION_MODE);
-  gtk_object_add_arg_type ("GtkCList::row_height",
+  gtk_object_add_arg_type ("GtkCList::row-height",
                           GTK_TYPE_UINT,
-                          GTK_ARG_READWRITE,
+                          GTK_ARG_READWRITE | G_PARAM_STATIC_NAME,
                           ARG_ROW_HEIGHT);
   gtk_object_add_arg_type ("GtkCList::reorderable",
                           GTK_TYPE_BOOL,
-                          GTK_ARG_READWRITE,
+                          GTK_ARG_READWRITE | G_PARAM_STATIC_NAME,
                           ARG_REORDERABLE);
-  gtk_object_add_arg_type ("GtkCList::titles_active",
+  gtk_object_add_arg_type ("GtkCList::titles-active",
                           GTK_TYPE_BOOL,
-                          GTK_ARG_READWRITE,
+                          GTK_ARG_READWRITE | G_PARAM_STATIC_NAME,
                           ARG_TITLES_ACTIVE);
-  gtk_object_add_arg_type ("GtkCList::use_drag_icons",
+  gtk_object_add_arg_type ("GtkCList::use-drag-icons",
                           GTK_TYPE_BOOL,
-                          GTK_ARG_READWRITE,
+                          GTK_ARG_READWRITE | G_PARAM_STATIC_NAME,
                           ARG_USE_DRAG_ICONS);
-  
-  object_class->set_arg = gtk_clist_set_arg;
-  object_class->get_arg = gtk_clist_get_arg;
-  object_class->destroy = gtk_clist_destroy;
-  object_class->finalize = gtk_clist_finalize;
-
+  gtk_object_add_arg_type ("GtkCList::sort-type",
+                          GTK_TYPE_SORT_TYPE,
+                          GTK_ARG_READWRITE | G_PARAM_STATIC_NAME,
+                          ARG_SORT_TYPE);  
 
   widget_class->set_scroll_adjustments_signal =
-    gtk_signal_new ("set_scroll_adjustments",
+    gtk_signal_new (I_("set_scroll_adjustments"),
                    GTK_RUN_LAST,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, set_scroll_adjustments),
-                   gtk_marshal_NONE__POINTER_POINTER,
+                   _gtk_marshal_VOID__OBJECT_OBJECT,
                    GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
 
   clist_signals[SELECT_ROW] =
-    gtk_signal_new ("select_row",
+    gtk_signal_new (I_("select_row"),
                    GTK_RUN_FIRST,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, select_row),
-                   gtk_marshal_NONE__INT_INT_POINTER,
+                   _gtk_marshal_VOID__INT_INT_BOXED,
                    GTK_TYPE_NONE, 3,
                    GTK_TYPE_INT,
                    GTK_TYPE_INT,
-                   GTK_TYPE_GDK_EVENT);
+                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
   clist_signals[UNSELECT_ROW] =
-    gtk_signal_new ("unselect_row",
+    gtk_signal_new (I_("unselect_row"),
                    GTK_RUN_FIRST,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, unselect_row),
-                   gtk_marshal_NONE__INT_INT_POINTER,
+                   _gtk_marshal_VOID__INT_INT_BOXED,
                    GTK_TYPE_NONE, 3, GTK_TYPE_INT,
-                   GTK_TYPE_INT, GTK_TYPE_GDK_EVENT);
+                   GTK_TYPE_INT, GDK_TYPE_EVENT);
   clist_signals[ROW_MOVE] =
-    gtk_signal_new ("row_move",
+    gtk_signal_new (I_("row_move"),
                    GTK_RUN_LAST,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, row_move),
-                   gtk_marshal_NONE__INT_INT,
+                   _gtk_marshal_VOID__INT_INT,
                    GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
   clist_signals[CLICK_COLUMN] =
-    gtk_signal_new ("click_column",
+    gtk_signal_new (I_("click_column"),
                    GTK_RUN_FIRST,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, click_column),
-                   gtk_marshal_NONE__INT,
+                   _gtk_marshal_VOID__INT,
                    GTK_TYPE_NONE, 1, GTK_TYPE_INT);
   clist_signals[RESIZE_COLUMN] =
-    gtk_signal_new ("resize_column",
+    gtk_signal_new (I_("resize_column"),
                    GTK_RUN_LAST,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, resize_column),
-                   gtk_marshal_NONE__INT_INT,
+                   _gtk_marshal_VOID__INT_INT,
                    GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
 
   clist_signals[TOGGLE_FOCUS_ROW] =
-    gtk_signal_new ("toggle_focus_row",
+    gtk_signal_new (I_("toggle_focus_row"),
                     GTK_RUN_LAST | GTK_RUN_ACTION,
-                    object_class->type,
+                    GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkCListClass, toggle_focus_row),
-                    gtk_marshal_NONE__NONE,
+                    _gtk_marshal_VOID__VOID,
                     GTK_TYPE_NONE, 0);
   clist_signals[SELECT_ALL] =
-    gtk_signal_new ("select_all",
+    gtk_signal_new (I_("select_all"),
                     GTK_RUN_LAST | GTK_RUN_ACTION,
-                    object_class->type,
+                    GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkCListClass, select_all),
-                    gtk_marshal_NONE__NONE,
+                    _gtk_marshal_VOID__VOID,
                     GTK_TYPE_NONE, 0);
   clist_signals[UNSELECT_ALL] =
-    gtk_signal_new ("unselect_all",
+    gtk_signal_new (I_("unselect_all"),
                     GTK_RUN_LAST | GTK_RUN_ACTION,
-                    object_class->type,
+                    GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkCListClass, unselect_all),
-                    gtk_marshal_NONE__NONE,
+                    _gtk_marshal_VOID__VOID,
                     GTK_TYPE_NONE, 0);
   clist_signals[UNDO_SELECTION] =
-    gtk_signal_new ("undo_selection",
+    gtk_signal_new (I_("undo_selection"),
                    GTK_RUN_LAST | GTK_RUN_ACTION,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, undo_selection),
-                   gtk_marshal_NONE__NONE,
+                   _gtk_marshal_VOID__VOID,
                    GTK_TYPE_NONE, 0);
   clist_signals[START_SELECTION] =
-    gtk_signal_new ("start_selection",
+    gtk_signal_new (I_("start_selection"),
                    GTK_RUN_LAST | GTK_RUN_ACTION,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, start_selection),
-                   gtk_marshal_NONE__NONE,
+                   _gtk_marshal_VOID__VOID,
                    GTK_TYPE_NONE, 0);
   clist_signals[END_SELECTION] =
-    gtk_signal_new ("end_selection",
+    gtk_signal_new (I_("end_selection"),
                    GTK_RUN_LAST | GTK_RUN_ACTION,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, end_selection),
-                   gtk_marshal_NONE__NONE,
+                   _gtk_marshal_VOID__VOID,
                    GTK_TYPE_NONE, 0);
   clist_signals[TOGGLE_ADD_MODE] =
-    gtk_signal_new ("toggle_add_mode",
+    gtk_signal_new (I_("toggle_add_mode"),
                    GTK_RUN_LAST | GTK_RUN_ACTION,
-                   object_class->type,
+                   GTK_CLASS_TYPE (object_class),
                    GTK_SIGNAL_OFFSET (GtkCListClass, toggle_add_mode),
-                   gtk_marshal_NONE__NONE,
+                   _gtk_marshal_VOID__VOID,
                    GTK_TYPE_NONE, 0);
   clist_signals[EXTEND_SELECTION] =
-    gtk_signal_new ("extend_selection",
+    gtk_signal_new (I_("extend_selection"),
                     GTK_RUN_LAST | GTK_RUN_ACTION,
-                    object_class->type,
+                    GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkCListClass, extend_selection),
-                    gtk_marshal_NONE__ENUM_FLOAT_BOOL,
+                    _gtk_marshal_VOID__ENUM_FLOAT_BOOLEAN,
                     GTK_TYPE_NONE, 3,
                    GTK_TYPE_SCROLL_TYPE, GTK_TYPE_FLOAT, GTK_TYPE_BOOL);
   clist_signals[SCROLL_VERTICAL] =
-    gtk_signal_new ("scroll_vertical",
+    gtk_signal_new (I_("scroll_vertical"),
                     GTK_RUN_LAST | GTK_RUN_ACTION,
-                    object_class->type,
+                    GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkCListClass, scroll_vertical),
-                    gtk_marshal_NONE__ENUM_FLOAT,
+                    _gtk_marshal_VOID__ENUM_FLOAT,
                     GTK_TYPE_NONE, 2, GTK_TYPE_SCROLL_TYPE, GTK_TYPE_FLOAT);
   clist_signals[SCROLL_HORIZONTAL] =
-    gtk_signal_new ("scroll_horizontal",
+    gtk_signal_new (I_("scroll_horizontal"),
                     GTK_RUN_LAST | GTK_RUN_ACTION,
-                    object_class->type,
+                    GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkCListClass, scroll_horizontal),
-                    gtk_marshal_NONE__ENUM_FLOAT,
+                    _gtk_marshal_VOID__ENUM_FLOAT,
                     GTK_TYPE_NONE, 2, GTK_TYPE_SCROLL_TYPE, GTK_TYPE_FLOAT);
   clist_signals[ABORT_COLUMN_RESIZE] =
-    gtk_signal_new ("abort_column_resize",
+    gtk_signal_new (I_("abort_column_resize"),
                     GTK_RUN_LAST | GTK_RUN_ACTION,
-                    object_class->type,
+                    GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkCListClass, abort_column_resize),
-                    gtk_marshal_NONE__NONE,
+                    _gtk_marshal_VOID__VOID,
                     GTK_TYPE_NONE, 0);
-  gtk_object_class_add_signals (object_class, clist_signals, LAST_SIGNAL);
-
-  widget_class->realize = gtk_clist_realize;
-  widget_class->unrealize = gtk_clist_unrealize;
-  widget_class->map = gtk_clist_map;
-  widget_class->unmap = gtk_clist_unmap;
-  widget_class->draw = gtk_clist_draw;
-  widget_class->button_press_event = gtk_clist_button_press;
-  widget_class->button_release_event = gtk_clist_button_release;
-  widget_class->motion_notify_event = gtk_clist_motion;
-  widget_class->expose_event = gtk_clist_expose;
-  widget_class->size_request = gtk_clist_size_request;
-  widget_class->size_allocate = gtk_clist_size_allocate;
-  widget_class->key_press_event = gtk_clist_key_press;
-  widget_class->focus_in_event = gtk_clist_focus_in;
-  widget_class->focus_out_event = gtk_clist_focus_out;
-  widget_class->draw_focus = gtk_clist_draw_focus;
-  widget_class->style_set = gtk_clist_style_set;
-  widget_class->drag_begin = gtk_clist_drag_begin;
-  widget_class->drag_end = gtk_clist_drag_end;
-  widget_class->drag_motion = gtk_clist_drag_motion;
-  widget_class->drag_leave = gtk_clist_drag_leave;
-  widget_class->drag_drop = gtk_clist_drag_drop;
-  widget_class->drag_data_get = gtk_clist_drag_data_get;
-  widget_class->drag_data_received = gtk_clist_drag_data_received;
-
-  /* container_class->add = NULL; use the default GtkContainerClass warning */
-  /* container_class->remove=NULL; use the default GtkContainerClass warning */
-
-  container_class->forall = gtk_clist_forall;
-  container_class->focus = gtk_clist_focus;
-  container_class->set_focus_child = gtk_clist_set_focus_child;
-
-  klass->set_scroll_adjustments = gtk_clist_set_scroll_adjustments;
-  klass->refresh = clist_refresh;
-  klass->select_row = real_select_row;
-  klass->unselect_row = real_unselect_row;
-  klass->row_move = real_row_move;
-  klass->undo_selection = real_undo_selection;
-  klass->resync_selection = resync_selection;
-  klass->selection_find = selection_find;
-  klass->click_column = NULL;
-  klass->resize_column = real_resize_column;
-  klass->draw_row = draw_row;
-  klass->draw_drag_highlight = draw_drag_highlight;
-  klass->insert_row = real_insert_row;
-  klass->remove_row = real_remove_row;
-  klass->clear = real_clear;
-  klass->sort_list = real_sort_list;
-  klass->select_all = real_select_all;
-  klass->unselect_all = real_unselect_all;
-  klass->fake_unselect_all = fake_unselect_all;
-  klass->scroll_horizontal = scroll_horizontal;
-  klass->scroll_vertical = scroll_vertical;
-  klass->extend_selection = extend_selection;
-  klass->toggle_focus_row = toggle_focus_row;
-  klass->toggle_add_mode = toggle_add_mode;
-  klass->start_selection = start_selection;
-  klass->end_selection = end_selection;
-  klass->abort_column_resize = abort_column_resize;
-  klass->set_cell_contents = set_cell_contents;
-  klass->cell_size_request = cell_size_request;
 
   binding_set = gtk_binding_set_by_class (klass);
   gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
+                               "scroll_vertical", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+                               GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, 0,
                                "scroll_vertical", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
                                GTK_TYPE_FLOAT, 0.0);
@@ -726,76 +748,149 @@ gtk_clist_class_init (GtkCListClass *klass)
                                "scroll_vertical", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
                                GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, 0,
+                               "scroll_vertical", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+                               GTK_TYPE_FLOAT, 0.0);
   gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
                                "scroll_vertical", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
                                GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, 0,
+                               "scroll_vertical", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+                               GTK_TYPE_FLOAT, 0.0);
   gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
                                "scroll_vertical", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
                                GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, 0,
+                               "scroll_vertical", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+                               GTK_TYPE_FLOAT, 0.0);
   gtk_binding_entry_add_signal (binding_set, GDK_Home, GDK_CONTROL_MASK,
                                "scroll_vertical", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
                                GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, GDK_CONTROL_MASK,
+                               "scroll_vertical", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                               GTK_TYPE_FLOAT, 0.0);
   gtk_binding_entry_add_signal (binding_set, GDK_End, GDK_CONTROL_MASK,
                                "scroll_vertical", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
                                GTK_TYPE_FLOAT, 1.0);
-
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_End, GDK_CONTROL_MASK,
+                               "scroll_vertical", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                               GTK_TYPE_FLOAT, 1.0);
+  
   gtk_binding_entry_add_signal (binding_set, GDK_Up, GDK_SHIFT_MASK,
                                "extend_selection", 3,
                                GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
                                GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, GDK_SHIFT_MASK,
+                               "extend_selection", 3,
+                               GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+                               GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
   gtk_binding_entry_add_signal (binding_set, GDK_Down, GDK_SHIFT_MASK,
                                "extend_selection", 3,
                                GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
                                GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, GDK_SHIFT_MASK,
+                               "extend_selection", 3,
+                               GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+                               GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
   gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, GDK_SHIFT_MASK,
                                "extend_selection", 3,
                                GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
                                GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, GDK_SHIFT_MASK,
+                               "extend_selection", 3,
+                               GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+                               GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
   gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, GDK_SHIFT_MASK,
                                "extend_selection", 3,
                                GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
                                GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, GDK_SHIFT_MASK,
+                               "extend_selection", 3,
+                               GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+                               GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
   gtk_binding_entry_add_signal (binding_set, GDK_Home,
                                GDK_SHIFT_MASK | GDK_CONTROL_MASK,
                                "extend_selection", 3,
                                GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
                                GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Home,
+                                GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+                               "extend_selection", 3,
+                               GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                               GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
   gtk_binding_entry_add_signal (binding_set, GDK_End,
                                GDK_SHIFT_MASK | GDK_CONTROL_MASK,
                                "extend_selection", 3,
                                GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
                                GTK_TYPE_FLOAT, 1.0, GTK_TYPE_BOOL, TRUE);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_End,
+                               GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+                               "extend_selection", 3,
+                               GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                               GTK_TYPE_FLOAT, 1.0, GTK_TYPE_BOOL, TRUE);
 
+  
   gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
                                "scroll_horizontal", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
                                GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, 0,
+                               "scroll_horizontal", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+                               GTK_TYPE_FLOAT, 0.0);
+  
   gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
                                "scroll_horizontal", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
                                GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, 0,
+                               "scroll_horizontal", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+                               GTK_TYPE_FLOAT, 0.0);
+
   gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
                                "scroll_horizontal", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
                                GTK_TYPE_FLOAT, 0.0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
+                               "scroll_horizontal", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                               GTK_TYPE_FLOAT, 0.0);
+  
   gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
                                "scroll_horizontal", 2,
                                GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
                                GTK_TYPE_FLOAT, 1.0);
 
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
+                               "scroll_horizontal", 2,
+                               GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+                               GTK_TYPE_FLOAT, 1.0);
+  
   gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
                                "undo_selection", 0);
   gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
                                "abort_column_resize", 0);
   gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
                                "toggle_focus_row", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
+                               "toggle_focus_row", 0);  
   gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK,
                                "toggle_add_mode", 0);
-  gtk_binding_entry_add_signal (binding_set, '/', GDK_CONTROL_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, GDK_CONTROL_MASK,
+                               "toggle_add_mode", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_slash, GDK_CONTROL_MASK,
+                               "select_all", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KP_Divide, GDK_CONTROL_MASK,
                                "select_all", 0);
   gtk_binding_entry_add_signal (binding_set, '\\', GDK_CONTROL_MASK,
                                "unselect_all", 0);
@@ -826,8 +921,8 @@ gtk_clist_set_arg (GtkObject      *object,
 
   switch (arg_id)
     {
-    case ARG_N_COLUMNS: /* construct-only arg, only set when !GTK_CONSTRUCTED */
-      gtk_clist_construct (clist, MAX (1, GTK_VALUE_UINT (*arg)), NULL);
+    case ARG_N_COLUMNS: /* only set at construction time */
+      clist->columns = MAX (1, GTK_VALUE_UINT (*arg));
       break;
     case ARG_SHADOW_TYPE:
       gtk_clist_set_shadow_type (clist, GTK_VALUE_ENUM (*arg));
@@ -850,7 +945,8 @@ gtk_clist_set_arg (GtkObject      *object,
     case ARG_USE_DRAG_ICONS:
       gtk_clist_set_use_drag_icons (clist, GTK_VALUE_BOOL (*arg));
       break;
-    default:
+    case ARG_SORT_TYPE:
+      gtk_clist_set_sort_type (clist, GTK_VALUE_ENUM (*arg));
       break;
     }
 }
@@ -896,6 +992,9 @@ gtk_clist_get_arg (GtkObject      *object,
     case ARG_USE_DRAG_ICONS:
       GTK_VALUE_BOOL (*arg) = GTK_CLIST_USE_DRAG_ICONS (clist);
       break;
+    case ARG_SORT_TYPE:
+      GTK_VALUE_ENUM (*arg) = clist->sort_type;
+      break;
     default:
       arg->type = GTK_TYPE_INVALID;
       break;
@@ -909,17 +1008,12 @@ gtk_clist_init (GtkCList *clist)
 
   GTK_WIDGET_UNSET_FLAGS (clist, GTK_NO_WINDOW);
   GTK_WIDGET_SET_FLAGS (clist, GTK_CAN_FOCUS);
-  GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
   GTK_CLIST_SET_FLAG (clist, CLIST_DRAW_DRAG_LINE);
   GTK_CLIST_SET_FLAG (clist, CLIST_USE_DRAG_ICONS);
 
-  clist->row_mem_chunk = NULL;
-  clist->cell_mem_chunk = NULL;
-
   clist->freeze_count = 0;
 
   clist->rows = 0;
-  clist->row_center_offset = 0;
   clist->row_height = 0;
   clist->row_list = NULL;
   clist->row_list_end = NULL;
@@ -962,6 +1056,7 @@ gtk_clist_init (GtkCList *clist)
   clist->undo_unselection = NULL;
 
   clist->focus_row = -1;
+  clist->focus_header_column = -1;
   clist->undo_anchor = -1;
 
   clist->anchor = -1;
@@ -976,60 +1071,31 @@ gtk_clist_init (GtkCList *clist)
   clist->compare = default_compare;
   clist->sort_type = GTK_SORT_ASCENDING;
   clist->sort_column = 0;
+
+  clist->drag_highlight_row = -1;
 }
 
-/* Constructors */
-void
-gtk_clist_construct (GtkCList *clist,
-                    gint      columns,
-                    gchar    *titles[])
+/* Constructor */
+static GObject*
+gtk_clist_constructor (GType                  type,
+                      guint                  n_construct_properties,
+                      GObjectConstructParam *construct_properties)
 {
-  g_return_if_fail (clist != NULL);
-  g_return_if_fail (GTK_IS_CLIST (clist));
-  g_return_if_fail (columns > 0);
-  g_return_if_fail (GTK_OBJECT_CONSTRUCTED (clist) == FALSE);
-
-  /* mark the object as constructed */
-  gtk_object_constructed (GTK_OBJECT (clist));
-
-  /* initalize memory chunks, if this has not been done by any
-   * possibly derived widget
-   */
-  if (!clist->row_mem_chunk)
-    clist->row_mem_chunk = g_mem_chunk_new ("clist row mem chunk",
-                                           sizeof (GtkCListRow),
-                                           sizeof (GtkCListRow) *
-                                           CLIST_OPTIMUM_SIZE, 
-                                           G_ALLOC_AND_FREE);
-
-  if (!clist->cell_mem_chunk)
-    clist->cell_mem_chunk = g_mem_chunk_new ("clist cell mem chunk",
-                                            sizeof (GtkCell) * columns,
-                                            sizeof (GtkCell) * columns *
-                                            CLIST_OPTIMUM_SIZE, 
-                                            G_ALLOC_AND_FREE);
-
-  /* set number of columns, allocate memory */
-  clist->columns = columns;
+  GObject *object = G_OBJECT_CLASS (parent_class)->constructor (type,
+                                                               n_construct_properties,
+                                                               construct_properties);
+  GtkCList *clist = GTK_CLIST (object);
+  
+  /* allocate memory for columns */
   clist->column = columns_new (clist);
-
+  
   /* there needs to be at least one column button 
    * because there is alot of code that will break if it
-   * isn't there*/
+   * isn't there
+   */
   column_button_create (clist, 0);
-
-  if (titles)
-    {
-      guint i;
-      
-      GTK_CLIST_SET_FLAG (clist, CLIST_SHOW_TITLES);
-      for (i = 0; i < columns; i++)
-       gtk_clist_set_column_title (clist, i, titles[i]);
-    }
-  else
-    {
-      GTK_CLIST_UNSET_FLAG (clist, CLIST_SHOW_TITLES);
-    }
+  
+  return object;
 }
 
 /* GTKCLIST PUBLIC INTERFACE
@@ -1054,12 +1120,23 @@ GtkWidget*
 gtk_clist_new_with_titles (gint   columns,
                           gchar *titles[])
 {
-  GtkWidget *widget;
+  GtkCList *clist;
 
-  widget = gtk_type_new (GTK_TYPE_CLIST);
-  gtk_clist_construct (GTK_CLIST (widget), columns, titles);
+  clist = g_object_new (GTK_TYPE_CLIST,
+                       "n_columns", columns,
+                       NULL);
+  if (titles)
+    {
+      guint i;
 
-  return widget;
+      for (i = 0; i < clist->columns; i++)
+       gtk_clist_set_column_title (clist, i, titles[i]);
+      gtk_clist_column_titles_show (clist);
+    }
+  else
+    gtk_clist_column_titles_hide (clist);
+  
+  return GTK_WIDGET (clist);
 }
 
 void
@@ -1068,7 +1145,6 @@ gtk_clist_set_hadjustment (GtkCList      *clist,
 {
   GtkAdjustment *old_adjustment;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   if (adjustment)
     g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
@@ -1088,8 +1164,7 @@ gtk_clist_set_hadjustment (GtkCList      *clist,
 
   if (clist->hadjustment)
     {
-      gtk_object_ref (GTK_OBJECT (clist->hadjustment));
-      gtk_object_sink (GTK_OBJECT (clist->hadjustment));
+      g_object_ref_sink (clist->hadjustment);
 
       gtk_signal_connect (GTK_OBJECT (clist->hadjustment), "changed",
                          (GtkSignalFunc) hadjustment_changed,
@@ -1106,7 +1181,6 @@ gtk_clist_set_hadjustment (GtkCList      *clist,
 GtkAdjustment *
 gtk_clist_get_hadjustment (GtkCList *clist)
 {
-  g_return_val_if_fail (clist != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
 
   return clist->hadjustment;
@@ -1118,7 +1192,6 @@ gtk_clist_set_vadjustment (GtkCList      *clist,
 {
   GtkAdjustment *old_adjustment;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   if (adjustment)
     g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
@@ -1138,8 +1211,7 @@ gtk_clist_set_vadjustment (GtkCList      *clist,
 
   if (clist->vadjustment)
     {
-      gtk_object_ref (GTK_OBJECT (clist->vadjustment));
-      gtk_object_sink (GTK_OBJECT (clist->vadjustment));
+      g_object_ref_sink (clist->vadjustment);
 
       gtk_signal_connect (GTK_OBJECT (clist->vadjustment), "changed",
                          (GtkSignalFunc) vadjustment_changed,
@@ -1156,7 +1228,6 @@ gtk_clist_set_vadjustment (GtkCList      *clist,
 GtkAdjustment *
 gtk_clist_get_vadjustment (GtkCList *clist)
 {
-  g_return_val_if_fail (clist != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
 
   return clist->vadjustment;
@@ -1177,7 +1248,6 @@ void
 gtk_clist_set_shadow_type (GtkCList      *clist,
                           GtkShadowType  type)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   clist->shadow_type = type;
@@ -1190,8 +1260,8 @@ void
 gtk_clist_set_selection_mode (GtkCList         *clist,
                              GtkSelectionMode  mode)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
+  g_return_if_fail (mode != GTK_SELECTION_NONE);
 
   if (mode == clist->selection_mode)
     return;
@@ -1210,19 +1280,20 @@ gtk_clist_set_selection_mode (GtkCList         *clist,
   switch (mode)
     {
     case GTK_SELECTION_MULTIPLE:
-    case GTK_SELECTION_EXTENDED:
       return;
     case GTK_SELECTION_BROWSE:
     case GTK_SELECTION_SINGLE:
       gtk_clist_unselect_all (clist);
       break;
+    default:
+      /* Someone set it by hand */
+      g_assert_not_reached ();
     }
 }
 
 void
 gtk_clist_freeze (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   clist->freeze_count++;
@@ -1231,7 +1302,6 @@ gtk_clist_freeze (GtkCList *clist)
 void
 gtk_clist_thaw (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (clist->freeze_count)
@@ -1263,7 +1333,6 @@ gtk_clist_thaw (GtkCList *clist)
 void
 gtk_clist_column_titles_show (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (!GTK_CLIST_SHOW_TITLES(clist))
@@ -1278,7 +1347,6 @@ gtk_clist_column_titles_show (GtkCList *clist)
 void 
 gtk_clist_column_titles_hide (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (GTK_CLIST_SHOW_TITLES(clist))
@@ -1294,9 +1362,6 @@ void
 gtk_clist_column_title_active (GtkCList *clist,
                               gint      column)
 {
-  GtkObject *object;
-
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1304,35 +1369,11 @@ gtk_clist_column_title_active (GtkCList *clist,
   if (!clist->column[column].button || !clist->column[column].button_passive)
     return;
 
-  object = GTK_OBJECT (clist->column[column].button);
-
   clist->column[column].button_passive = FALSE;
 
-  gtk_signal_disconnect_by_func (object,
-                                (GtkSignalFunc) column_title_passive_func,
-                                GINT_TO_POINTER (gtk_signal_lookup
-                                                 ("button_press_event",
-                                                  GTK_TYPE_WIDGET)));
-  gtk_signal_disconnect_by_func (object,
-                                (GtkSignalFunc) column_title_passive_func,
-                                GINT_TO_POINTER (gtk_signal_lookup
-                                                 ("button_release_event",
-                                                  GTK_TYPE_WIDGET)));
-  gtk_signal_disconnect_by_func (object,
-                                (GtkSignalFunc) column_title_passive_func,
-                                GINT_TO_POINTER (gtk_signal_lookup
-                                                 ("motion_notify_event",
-                                                  GTK_TYPE_WIDGET)));
-  gtk_signal_disconnect_by_func (object,
-                                (GtkSignalFunc) column_title_passive_func,
-                                GINT_TO_POINTER (gtk_signal_lookup
-                                                 ("enter_notify_event",
-                                                  GTK_TYPE_WIDGET)));
-  gtk_signal_disconnect_by_func (object,
+  gtk_signal_disconnect_by_func (GTK_OBJECT (clist->column[column].button),
                                 (GtkSignalFunc) column_title_passive_func,
-                                GINT_TO_POINTER (gtk_signal_lookup
-                                                 ("leave_notify_event",
-                                                  GTK_TYPE_WIDGET)));
+                                NULL);
 
   GTK_WIDGET_SET_FLAGS (clist->column[column].button, GTK_CAN_FOCUS);
   if (GTK_WIDGET_VISIBLE (clist))
@@ -1343,10 +1384,8 @@ void
 gtk_clist_column_title_passive (GtkCList *clist,
                                gint      column)
 {
-  GtkObject *object;
   GtkButton *button;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1354,46 +1393,17 @@ gtk_clist_column_title_passive (GtkCList *clist,
   if (!clist->column[column].button || clist->column[column].button_passive)
     return;
 
-  object = GTK_OBJECT (clist->column[column].button);
   button = GTK_BUTTON (clist->column[column].button);
 
   clist->column[column].button_passive = TRUE;
 
-    
-
-  gtk_signal_connect (object, "button_press_event",
-                     (GtkSignalFunc) column_title_passive_func,
-                     GINT_TO_POINTER (gtk_signal_lookup
-                                      ("button_press_event",
-                                       GTK_TYPE_WIDGET)));
-
   if (button->button_down)
     gtk_button_released (button);
-
-  gtk_signal_connect (object, "button_release_event",
-                     (GtkSignalFunc) column_title_passive_func,
-                     GINT_TO_POINTER (gtk_signal_lookup
-                                      ("button_release_event",
-                                       GTK_TYPE_WIDGET)));
-  gtk_signal_connect (object, "motion_notify_event",
-                     (GtkSignalFunc) column_title_passive_func,
-                     GINT_TO_POINTER (gtk_signal_lookup
-                                      ("motion_notify_event",
-                                       GTK_TYPE_WIDGET)));
-  gtk_signal_connect (object, "enter_notify_event",
-                     (GtkSignalFunc) column_title_passive_func,
-                     GINT_TO_POINTER (gtk_signal_lookup
-                                      ("enter_notify_event",
-                                       GTK_TYPE_WIDGET)));
-
   if (button->in_button)
     gtk_button_leave (button);
 
-  gtk_signal_connect (object, "leave_notify_event",
-                     (GtkSignalFunc) column_title_passive_func,
-                     GINT_TO_POINTER (gtk_signal_lookup
-                                      ("leave_notify_event",
-                                       GTK_TYPE_WIDGET)));
+  gtk_signal_connect (GTK_OBJECT (clist->column[column].button), "event",
+                     (GtkSignalFunc) column_title_passive_func, NULL);
 
   GTK_WIDGET_UNSET_FLAGS (clist->column[column].button, GTK_CAN_FOCUS);
   if (GTK_WIDGET_VISIBLE (clist))
@@ -1405,12 +1415,8 @@ gtk_clist_column_titles_active (GtkCList *clist)
 {
   gint i;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (!GTK_CLIST_SHOW_TITLES(clist))
-    return;
-
   for (i = 0; i < clist->columns; i++)
     gtk_clist_column_title_active (clist, i);
 }
@@ -1420,12 +1426,8 @@ gtk_clist_column_titles_passive (GtkCList *clist)
 {
   gint i;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (!GTK_CLIST_SHOW_TITLES(clist))
-    return;
-
   for (i = 0; i < clist->columns; i++)
     gtk_clist_column_title_passive (clist, i);
 }
@@ -1440,7 +1442,6 @@ gtk_clist_set_column_title (GtkCList    *clist,
   GtkWidget *alignment = NULL;
   GtkWidget *label;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1499,7 +1500,6 @@ gchar *
 gtk_clist_get_column_title (GtkCList *clist,
                            gint      column)
 {
-  g_return_val_if_fail (clist != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
 
   if (column < 0 || column >= clist->columns)
@@ -1516,7 +1516,6 @@ gtk_clist_set_column_widget (GtkCList  *clist,
   gint new_button = 0;
   GtkWidget *old_widget;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1555,14 +1554,13 @@ GtkWidget *
 gtk_clist_get_column_widget (GtkCList *clist,
                             gint      column)
 {
-  g_return_val_if_fail (clist != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
 
   if (column < 0 || column >= clist->columns)
     return NULL;
 
   if (clist->column[column].button)
-    return GTK_BUTTON (clist->column[column].button)->child;
+    return GTK_BIN (clist->column[column].button)->child;
 
   return NULL;
 }
@@ -1574,7 +1572,6 @@ gtk_clist_set_column_justification (GtkCList         *clist,
 {
   GtkWidget *alignment;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1620,7 +1617,6 @@ gtk_clist_set_column_visibility (GtkCList *clist,
                                 gint      column,
                                 gboolean  visible)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1658,9 +1654,8 @@ gtk_clist_set_column_visibility (GtkCList *clist,
 void
 gtk_clist_set_column_resizeable (GtkCList *clist,
                                 gint      column,
-                                gint      resizeable)
+                                gboolean  resizeable)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1681,7 +1676,6 @@ gtk_clist_set_column_auto_resize (GtkCList *clist,
                                  gint      column,
                                  gboolean  auto_resize)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1693,7 +1687,7 @@ gtk_clist_set_column_auto_resize (GtkCList *clist,
   if (auto_resize)
     {
       clist->column[column].resizeable = FALSE;
-      if (!GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
+      if (!GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
        {
          gint width;
 
@@ -1712,7 +1706,6 @@ gtk_clist_columns_autosize (GtkCList *clist)
   gint i;
   gint width;
 
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
 
   gtk_clist_freeze (clist);
@@ -1737,10 +1730,9 @@ gtk_clist_optimal_column_width (GtkCList *clist,
   GList *list;
   gint width;
 
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_CLIST (clist), 0);
 
-  if (column < 0 || column > clist->columns)
+  if (column < 0 || column >= clist->columns)
     return 0;
 
   if (GTK_CLIST_SHOW_TITLES(clist) && clist->column[column].button)
@@ -1754,7 +1746,7 @@ gtk_clist_optimal_column_width (GtkCList *clist,
 
   for (list = clist->row_list; list; list = list->next)
     {
-      GTK_CLIST_CLASS_FW (clist)->cell_size_request
+  GTK_CLIST_GET_CLASS (clist)->cell_size_request
        (clist, GTK_CLIST_ROW (list), column, &requisition);
       width = MAX (width, requisition.width);
     }
@@ -1767,7 +1759,6 @@ gtk_clist_set_column_width (GtkCList *clist,
                            gint      column,
                            gint      width)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1782,7 +1773,6 @@ gtk_clist_set_column_min_width (GtkCList *clist,
                                gint      column,
                                gint      min_width)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1805,7 +1795,6 @@ gtk_clist_set_column_max_width (GtkCList *clist,
                                gint      column,
                                gint      max_width)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1845,11 +1834,11 @@ column_auto_resize (GtkCList    *clist,
   GtkRequisition requisition;
 
   if (!clist->column[column].auto_resize ||
-      GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
+      GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
     return;
 
   if (clist_row)
-    GTK_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row,
+    GTK_CLIST_GET_CLASS (clist)->cell_size_request (clist, clist_row,
                                                   column, &requisition);
   else
     requisition.width = 0;
@@ -1872,7 +1861,7 @@ column_auto_resize (GtkCList    *clist,
 
       for (list = clist->row_list; list; list = list->next)
        {
-         GTK_CLIST_CLASS_FW (clist)->cell_size_request
+         GTK_CLIST_GET_CLASS (clist)->cell_size_request
            (clist, GTK_CLIST_ROW (list), column, &requisition);
          new_width = MAX (new_width, requisition.width);
          if (new_width == clist->column[column].width)
@@ -1889,7 +1878,6 @@ real_resize_column (GtkCList *clist,
                    gint      column,
                    gint      width)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -1917,7 +1905,6 @@ real_resize_column (GtkCList *clist,
 static void
 abort_column_resize (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (!GTK_CLIST_IN_DRAG(clist))
@@ -1925,7 +1912,8 @@ abort_column_resize (GtkCList *clist)
 
   GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
   gtk_grab_remove (GTK_WIDGET (clist));
-  gdk_pointer_ungrab (GDK_CURRENT_TIME);
+  gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (clist)),
+                             GDK_CURRENT_TIME);
   clist->drag_pos = -1;
 
   if (clist->x_drag >= 0 && clist->x_drag <= clist->clist_window_width - 1)
@@ -2092,7 +2080,7 @@ new_column_width (GtkCList *clist,
                  gint      column,
                  gint     *x)
 {
-  gint xthickness = GTK_WIDGET (clist)->style->klass->xthickness;
+  gint xthickness = GTK_WIDGET (clist)->style->xthickness;
   gint width;
   gint cx;
   gint dx;
@@ -2149,7 +2137,6 @@ column_button_create (GtkCList *clist,
   gtk_signal_connect (GTK_OBJECT (button), "clicked",
                      (GtkSignalFunc) column_button_clicked,
                      (gpointer) clist);
-
   gtk_widget_show (button);
 }
 
@@ -2178,7 +2165,21 @@ column_title_passive_func (GtkWidget *widget,
                           GdkEvent  *event,
                           gpointer   data)
 {
-  gtk_signal_emit_stop (GTK_OBJECT (widget), GPOINTER_TO_INT (data));
+  g_return_val_if_fail (event != NULL, FALSE);
+  
+  switch (event->type)
+    {
+    case GDK_MOTION_NOTIFY:
+    case GDK_BUTTON_PRESS:
+    case GDK_2BUTTON_PRESS:
+    case GDK_3BUTTON_PRESS:
+    case GDK_BUTTON_RELEASE:
+    case GDK_ENTER_NOTIFY:
+    case GDK_LEAVE_NOTIFY:
+      return TRUE;
+    default:
+      break;
+    }
   return FALSE;
 }
 
@@ -2200,7 +2201,6 @@ gtk_clist_get_cell_type (GtkCList *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, -1);
   g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
 
   if (row < 0 || row >= clist->rows)
@@ -2208,7 +2208,7 @@ gtk_clist_get_cell_type (GtkCList *clist,
   if (column < 0 || column >= clist->columns)
     return -1;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   return clist_row->cell[column].type;
 }
@@ -2221,7 +2221,6 @@ gtk_clist_set_text (GtkCList    *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
@@ -2229,17 +2228,17 @@ gtk_clist_set_text (GtkCList    *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   /* if text is null, then the cell is empty */
-  GTK_CLIST_CLASS_FW (clist)->set_cell_contents
+  GTK_CLIST_GET_CLASS (clist)->set_cell_contents
     (clist, clist_row, column, GTK_CELL_TEXT, text, 0, NULL, NULL);
 
   /* redraw the list if it's not frozen */
   if (CLIST_UNFROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+       GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
     }
 }
 
@@ -2251,7 +2250,6 @@ gtk_clist_get_text (GtkCList  *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
 
   if (row < 0 || row >= clist->rows)
@@ -2259,7 +2257,7 @@ gtk_clist_get_text (GtkCList  *clist,
   if (column < 0 || column >= clist->columns)
     return 0;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].type != GTK_CELL_TEXT)
     return 0;
@@ -2279,7 +2277,6 @@ gtk_clist_set_pixmap (GtkCList  *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
@@ -2287,20 +2284,20 @@ gtk_clist_set_pixmap (GtkCList  *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
   
   gdk_pixmap_ref (pixmap);
   
   if (mask) gdk_pixmap_ref (mask);
   
-  GTK_CLIST_CLASS_FW (clist)->set_cell_contents
+  GTK_CLIST_GET_CLASS (clist)->set_cell_contents
     (clist, clist_row, column, GTK_CELL_PIXMAP, NULL, 0, pixmap, mask);
 
   /* redraw the list if it's not frozen */
   if (CLIST_UNFROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+       GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
     }
 }
 
@@ -2313,7 +2310,6 @@ gtk_clist_get_pixmap (GtkCList   *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
 
   if (row < 0 || row >= clist->rows)
@@ -2321,7 +2317,7 @@ gtk_clist_get_pixmap (GtkCList   *clist,
   if (column < 0 || column >= clist->columns)
     return 0;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].type != GTK_CELL_PIXMAP)
     return 0;
@@ -2347,7 +2343,6 @@ gtk_clist_set_pixtext (GtkCList    *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
@@ -2355,18 +2350,18 @@ gtk_clist_set_pixtext (GtkCList    *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
   
   gdk_pixmap_ref (pixmap);
   if (mask) gdk_pixmap_ref (mask);
-  GTK_CLIST_CLASS_FW (clist)->set_cell_contents
+  GTK_CLIST_GET_CLASS (clist)->set_cell_contents
     (clist, clist_row, column, GTK_CELL_PIXTEXT, text, spacing, pixmap, mask);
 
   /* redraw the list if it's not frozen */
   if (CLIST_UNFROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+       GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
     }
 }
 
@@ -2381,7 +2376,6 @@ gtk_clist_get_pixtext (GtkCList   *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
 
   if (row < 0 || row >= clist->rows)
@@ -2389,7 +2383,7 @@ gtk_clist_get_pixtext (GtkCList   *clist,
   if (column < 0 || column >= clist->columns)
     return 0;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].type != GTK_CELL_PIXTEXT)
     return 0;
@@ -2402,7 +2396,8 @@ gtk_clist_get_pixtext (GtkCList   *clist,
     *pixmap = GTK_CELL_PIXTEXT (clist_row->cell[column])->pixmap;
 
   /* mask can be NULL */
-  *mask = GTK_CELL_PIXTEXT (clist_row->cell[column])->mask;
+  if (mask)
+    *mask = GTK_CELL_PIXTEXT (clist_row->cell[column])->mask;
 
   return 1;
 }
@@ -2414,10 +2409,9 @@ gtk_clist_set_shift (GtkCList *clist,
                     gint      vertical,
                     gint      horizontal)
 {
-  GtkRequisition requisition;
+  GtkRequisition requisition = { 0 };
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
@@ -2425,11 +2419,11 @@ gtk_clist_set_shift (GtkCList *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist->column[column].auto_resize &&
-      !GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
-    GTK_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row,
+      !GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
+    GTK_CLIST_GET_CLASS (clist)->cell_size_request (clist, clist_row,
                                                   column, &requisition);
 
   clist_row->cell[column].vertical = vertical;
@@ -2438,7 +2432,7 @@ gtk_clist_set_shift (GtkCList *clist,
   column_auto_resize (clist, clist_row, column, requisition.width);
 
   if (CLIST_UNFROZEN (clist) && gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-    GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+    GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
 }
 
 /* PRIVATE CELL FUNCTIONS
@@ -2456,14 +2450,16 @@ set_cell_contents (GtkCList    *clist,
                   GdkBitmap   *mask)
 {
   GtkRequisition requisition;
-
-  g_return_if_fail (clist != NULL);
+  gchar *old_text = NULL;
+  GdkPixmap *old_pixmap = NULL;
+  GdkBitmap *old_mask = NULL;
+  
   g_return_if_fail (GTK_IS_CLIST (clist));
   g_return_if_fail (clist_row != NULL);
 
   if (clist->column[column].auto_resize &&
-      !GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
-    GTK_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row,
+      !GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
+    GTK_CLIST_GET_CLASS (clist)->cell_size_request (clist, clist_row,
                                                   column, &requisition);
 
   switch (clist_row->cell[column].type)
@@ -2471,21 +2467,19 @@ set_cell_contents (GtkCList    *clist,
     case GTK_CELL_EMPTY:
       break;
     case GTK_CELL_TEXT:
-      g_free (GTK_CELL_TEXT (clist_row->cell[column])->text);
+      old_text = GTK_CELL_TEXT (clist_row->cell[column])->text;
       break;
     case GTK_CELL_PIXMAP:
-      gdk_pixmap_unref (GTK_CELL_PIXMAP (clist_row->cell[column])->pixmap);
-      if (GTK_CELL_PIXMAP (clist_row->cell[column])->mask)
-       gdk_bitmap_unref (GTK_CELL_PIXMAP (clist_row->cell[column])->mask);
+      old_pixmap = GTK_CELL_PIXMAP (clist_row->cell[column])->pixmap;
+      old_mask = GTK_CELL_PIXMAP (clist_row->cell[column])->mask;
       break;
     case GTK_CELL_PIXTEXT:
-      g_free (GTK_CELL_PIXTEXT (clist_row->cell[column])->text);
-      gdk_pixmap_unref (GTK_CELL_PIXTEXT (clist_row->cell[column])->pixmap);
-      if (GTK_CELL_PIXTEXT (clist_row->cell[column])->mask)
-       gdk_bitmap_unref (GTK_CELL_PIXTEXT (clist_row->cell[column])->mask);
+      old_text = GTK_CELL_PIXTEXT (clist_row->cell[column])->text;
+      old_pixmap = GTK_CELL_PIXTEXT (clist_row->cell[column])->pixmap;
+      old_mask = GTK_CELL_PIXTEXT (clist_row->cell[column])->mask;
       break;
     case GTK_CELL_WIDGET:
-      /* unimplimented */
+      /* unimplemented */
       break;
     default:
       break;
@@ -2493,6 +2487,8 @@ set_cell_contents (GtkCList    *clist,
 
   clist_row->cell[column].type = GTK_CELL_EMPTY;
 
+  /* Note that pixmap and mask were already ref'ed by the caller
+   */
   switch (type)
     {
     case GTK_CELL_TEXT:
@@ -2526,8 +2522,54 @@ set_cell_contents (GtkCList    *clist,
     }
 
   if (clist->column[column].auto_resize &&
-      !GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
+      !GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
     column_auto_resize (clist, clist_row, column, requisition.width);
+
+  if (old_text)
+    g_free (old_text);
+  if (old_pixmap)
+    gdk_pixmap_unref (old_pixmap);
+  if (old_mask)
+    gdk_pixmap_unref (old_mask);
+}
+
+PangoLayout *
+_gtk_clist_create_cell_layout (GtkCList       *clist,
+                              GtkCListRow    *clist_row,
+                              gint            column)
+{
+  PangoLayout *layout;
+  GtkStyle *style;
+  GtkCell *cell;
+  gchar *text;
+  
+  get_cell_style (clist, clist_row, GTK_STATE_NORMAL, column, &style,
+                 NULL, NULL);
+
+
+  cell = &clist_row->cell[column];
+  switch (cell->type)
+    {
+    case GTK_CELL_TEXT:
+    case GTK_CELL_PIXTEXT:
+      text = ((cell->type == GTK_CELL_PIXTEXT) ?
+             GTK_CELL_PIXTEXT (*cell)->text :
+             GTK_CELL_TEXT (*cell)->text);
+
+      if (!text)
+       return NULL;
+      
+      layout = gtk_widget_create_pango_layout (GTK_WIDGET (clist),
+                                              ((cell->type == GTK_CELL_PIXTEXT) ?
+                                               GTK_CELL_PIXTEXT (*cell)->text :
+                                               GTK_CELL_TEXT (*cell)->text));
+      pango_layout_set_font_description (layout, style->font_desc);
+      
+      return layout;
+      
+    default:
+      return NULL;
+    }
 }
 
 static void
@@ -2536,45 +2578,49 @@ cell_size_request (GtkCList       *clist,
                   gint            column,
                   GtkRequisition *requisition)
 {
-  GtkStyle *style;
   gint width;
   gint height;
+  PangoLayout *layout;
+  PangoRectangle logical_rect;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   g_return_if_fail (requisition != NULL);
 
-  get_cell_style (clist, clist_row, GTK_STATE_NORMAL, column, &style,
-                 NULL, NULL);
+  layout = _gtk_clist_create_cell_layout (clist, clist_row, column);
+  if (layout)
+    {
+      pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+      
+      requisition->width = logical_rect.width;
+      requisition->height = logical_rect.height;
+      
+      g_object_unref (G_OBJECT (layout));
+    }
+  else
+    {
+      requisition->width  = 0;
+      requisition->height = 0;
+    }
+
+  if (layout && clist_row->cell[column].type == GTK_CELL_PIXTEXT)
+    requisition->width += GTK_CELL_PIXTEXT (clist_row->cell[column])->spacing;
 
   switch (clist_row->cell[column].type)
     {
-    case GTK_CELL_TEXT:
-      requisition->width =
-       gdk_string_width (style->font,
-                         GTK_CELL_TEXT (clist_row->cell[column])->text);
-      requisition->height = style->font->ascent + style->font->descent;
-      break;
     case GTK_CELL_PIXTEXT:
       gdk_window_get_size (GTK_CELL_PIXTEXT (clist_row->cell[column])->pixmap,
                           &width, &height);
-      requisition->width = width +
-       GTK_CELL_PIXTEXT (clist_row->cell[column])->spacing +
-       gdk_string_width (style->font,
-                         GTK_CELL_TEXT (clist_row->cell[column])->text);
-
-      requisition->height = MAX (style->font->ascent + style->font->descent,
-                                height);
+      requisition->width += width;
+      requisition->height = MAX (requisition->height, height);      
       break;
     case GTK_CELL_PIXMAP:
       gdk_window_get_size (GTK_CELL_PIXMAP (clist_row->cell[column])->pixmap,
                           &width, &height);
-      requisition->width = width;
-      requisition->height = height;
+      requisition->width += width;
+      requisition->height = MAX (requisition->height, height);
       break;
+      
     default:
-      requisition->width  = 0;
-      requisition->height = 0;
       break;
     }
 
@@ -2593,22 +2639,20 @@ gint
 gtk_clist_prepend (GtkCList    *clist,
                   gchar       *text[])
 {
-  g_return_val_if_fail (clist != NULL, -1);
   g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
   g_return_val_if_fail (text != NULL, -1);
 
-  return GTK_CLIST_CLASS_FW (clist)->insert_row (clist, 0, text);
+  return GTK_CLIST_GET_CLASS (clist)->insert_row (clist, 0, text);
 }
 
 gint
 gtk_clist_append (GtkCList    *clist,
                  gchar       *text[])
 {
-  g_return_val_if_fail (clist != NULL, -1);
   g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
   g_return_val_if_fail (text != NULL, -1);
 
-  return GTK_CLIST_CLASS_FW (clist)->insert_row (clist, clist->rows, text);
+  return GTK_CLIST_GET_CLASS (clist)->insert_row (clist, clist->rows, text);
 }
 
 gint
@@ -2616,30 +2660,28 @@ gtk_clist_insert (GtkCList    *clist,
                  gint         row,
                  gchar       *text[])
 {
-  g_return_val_if_fail (clist != NULL, -1);
   g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
   g_return_val_if_fail (text != NULL, -1);
 
   if (row < 0 || row > clist->rows)
     row = clist->rows;
 
-  return GTK_CLIST_CLASS_FW (clist)->insert_row (clist, row, text);
+  return GTK_CLIST_GET_CLASS (clist)->insert_row (clist, row, text);
 }
 
 void
 gtk_clist_remove (GtkCList *clist,
                  gint      row)
 {
-  GTK_CLIST_CLASS_FW (clist)->remove_row (clist, row);
+  GTK_CLIST_GET_CLASS (clist)->remove_row (clist, row);
 }
 
 void
 gtk_clist_clear (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
-  GTK_CLIST_CLASS_FW (clist)->clear (clist);
+  GTK_CLIST_GET_CLASS (clist)->clear (clist);
 }
 
 /* PRIVATE INSERT/REMOVE ROW FUNCTIONS
@@ -2656,7 +2698,6 @@ real_insert_row (GtkCList *clist,
   gint i;
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, -1);
   g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
   g_return_val_if_fail (text != NULL, -1);
 
@@ -2670,7 +2711,7 @@ real_insert_row (GtkCList *clist,
   /* set the text in the row's columns */
   for (i = 0; i < clist->columns; i++)
     if (text[i])
-      GTK_CLIST_CLASS_FW (clist)->set_cell_contents
+      GTK_CLIST_GET_CLASS (clist)->set_cell_contents
        (clist, clist_row, i, GTK_CELL_TEXT, text[i], 0, NULL ,NULL);
 
   if (!clist->rows)
@@ -2748,11 +2789,10 @@ static void
 real_remove_row (GtkCList *clist,
                 gint      row)
 {
-  gint was_visible, was_selected;
+  gint was_visible;
   GList *list;
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   /* return if out of bounds */
@@ -2760,10 +2800,9 @@ real_remove_row (GtkCList *clist,
     return;
 
   was_visible = (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE);
-  was_selected = 0;
 
   /* get the row we're going to delete */
-  list = g_list_nth (clist->row_list, row);
+  list = ROW_ELEMENT (clist, row);
   g_assert (list != NULL);
   clist_row = list->data;
 
@@ -2775,8 +2814,9 @@ real_remove_row (GtkCList *clist,
     gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
                     row, -1, NULL);
 
-  /* reset the row end pointer if we're removing at the
-   * end of the list */
+  sync_selection (clist, row, SYNC_REMOVE);
+
+  /* reset the row end pointer if we're removing at the end of the list */
   clist->rows--;
   if (clist->row_list == list)
     clist->row_list = g_list_next (list);
@@ -2784,15 +2824,9 @@ real_remove_row (GtkCList *clist,
     clist->row_list_end = g_list_previous (list);
   g_list_remove (list, clist_row);
 
-  /*if (clist->focus_row >=0 &&
-      (row <= clist->focus_row || clist->focus_row >= clist->rows))
-      clist->focus_row--;*/
-
   if (row < ROW_FROM_YPIXEL (clist, 0))
     clist->voffset += clist->row_height + CELL_SPACING;
 
-  sync_selection (clist, row, SYNC_REMOVE);
-
   if (clist->selection_mode == GTK_SELECTION_BROWSE && !clist->selection &&
       clist->focus_row >= 0)
     gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
@@ -2818,7 +2852,6 @@ real_clear (GtkCList *clist)
   GList *free_list;
   gint i;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   /* free up the selection list */
@@ -2877,7 +2910,6 @@ real_row_move (GtkCList *clist,
   gint first, last;
   gint d;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (GTK_CLIST_AUTO_SORT(clist))
@@ -2891,7 +2923,7 @@ real_row_move (GtkCList *clist,
   gtk_clist_freeze (clist);
 
   /* unlink source row */
-  clist_row = g_list_nth_data (clist->row_list, source_row);
+  clist_row = ROW_ELEMENT (clist, source_row)->data;
   if (source_row == clist->rows - 1)
     clist->row_list_end = clist->row_list_end->prev;
   clist->row_list = g_list_remove (clist->row_list, clist_row);
@@ -2954,7 +2986,6 @@ gtk_clist_moveto (GtkCList *clist,
                  gfloat    row_align,
                  gfloat    col_align)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < -1 || row >= clist->rows)
@@ -2993,7 +3024,6 @@ gtk_clist_set_row_height (GtkCList *clist,
 {
   GtkWidget *widget;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   widget = GTK_WIDGET (clist);
@@ -3009,18 +3039,23 @@ gtk_clist_set_row_height (GtkCList *clist,
       clist->row_height = 0;
     }
 
-  if (GTK_WIDGET_REALIZED (clist))
+  if (widget->style->font_desc)
     {
+      PangoContext *context = gtk_widget_get_pango_context (widget);
+      PangoFontMetrics *metrics;
+
+      metrics = pango_context_get_metrics (context,
+                                          widget->style->font_desc,
+                                          pango_context_get_language (context));
+      
       if (!GTK_CLIST_ROW_HEIGHT_SET(clist))
        {
-         clist->row_height = (widget->style->font->ascent +
-                              widget->style->font->descent + 1);
-         clist->row_center_offset = widget->style->font->ascent + 1.5;
+         clist->row_height = (pango_font_metrics_get_ascent (metrics) +
+                              pango_font_metrics_get_descent (metrics));
+         clist->row_height = PANGO_PIXELS (clist->row_height);
        }
-      else
-       clist->row_center_offset = 1.5 + (clist->row_height +
-                                         widget->style->font->ascent -
-                                         widget->style->font->descent - 1) / 2;
+
+      pango_font_metrics_unref (metrics);
     }
       
   CLIST_REFRESH (clist);
@@ -3042,13 +3077,16 @@ gtk_clist_set_row_data_full (GtkCList         *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row > (clist->rows - 1))
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
+
+  if (clist_row->destroy)
+    clist_row->destroy (clist_row->data);
+  
   clist_row->data = data;
   clist_row->destroy = destroy;
 }
@@ -3059,13 +3097,12 @@ gtk_clist_get_row_data (GtkCList *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
 
   if (row < 0 || row > (clist->rows - 1))
     return NULL;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
   return clist_row->data;
 }
 
@@ -3076,7 +3113,6 @@ gtk_clist_find_row_from_data (GtkCList *clist,
   GList *list;
   gint n;
 
-  g_return_val_if_fail (clist != NULL, -1);
   g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
 
   for (n = 0, list = clist->row_list; list; n++, list = list->next)
@@ -3093,7 +3129,6 @@ gtk_clist_swap_rows (GtkCList *clist,
 {
   gint first, last;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   g_return_if_fail (row1 != row2);
 
@@ -3116,7 +3151,6 @@ gtk_clist_row_move (GtkCList *clist,
                    gint      source_row,
                    gint      dest_row)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (GTK_CLIST_AUTO_SORT(clist))
@@ -3137,7 +3171,6 @@ gtk_clist_row_is_visible (GtkCList *clist,
 {
   gint top;
 
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
 
   if (row < 0 || row >= clist->rows)
@@ -3162,19 +3195,18 @@ gtk_clist_row_is_visible (GtkCList *clist,
 }
 
 void
-gtk_clist_set_foreground (GtkCList *clist,
-                         gint      row,
-                         GdkColor *color)
+gtk_clist_set_foreground (GtkCList       *clist,
+                         gint            row,
+                         const GdkColor *color)
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (color)
     {
@@ -3188,23 +3220,22 @@ gtk_clist_set_foreground (GtkCList *clist,
     clist_row->fg_set = FALSE;
 
   if (CLIST_UNFROZEN (clist) && gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-    GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+    GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
 }
 
 void
-gtk_clist_set_background (GtkCList *clist,
-                         gint      row,
-                         GdkColor *color)
+gtk_clist_set_background (GtkCList       *clist,
+                         gint            row,
+                         const GdkColor *color)
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (color)
     {
@@ -3219,7 +3250,7 @@ gtk_clist_set_background (GtkCList *clist,
 
   if (CLIST_UNFROZEN (clist)
       && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-    GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+    GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
 }
 
 /* PUBLIC ROW/CELL STYLE FUNCTIONS
@@ -3234,10 +3265,9 @@ gtk_clist_set_cell_style (GtkCList *clist,
                          gint      column,
                          GtkStyle *style)
 {
-  GtkRequisition requisition;
+  GtkRequisition requisition = { 0 };
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
@@ -3245,28 +3275,28 @@ gtk_clist_set_cell_style (GtkCList *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].style == style)
     return;
 
   if (clist->column[column].auto_resize &&
-      !GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
-    GTK_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row,
+      !GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
+    GTK_CLIST_GET_CLASS (clist)->cell_size_request (clist, clist_row,
                                                   column, &requisition);
 
   if (clist_row->cell[column].style)
     {
       if (GTK_WIDGET_REALIZED (clist))
         gtk_style_detach (clist_row->cell[column].style);
-      gtk_style_unref (clist_row->cell[column].style);
+      g_object_unref (clist_row->cell[column].style);
     }
 
   clist_row->cell[column].style = style;
 
   if (clist_row->cell[column].style)
     {
-      gtk_style_ref (clist_row->cell[column].style);
+      g_object_ref (clist_row->cell[column].style);
       
       if (GTK_WIDGET_REALIZED (clist))
         clist_row->cell[column].style =
@@ -3280,7 +3310,7 @@ gtk_clist_set_cell_style (GtkCList *clist,
   if (CLIST_UNFROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+       GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
     }
 }
 
@@ -3291,13 +3321,12 @@ gtk_clist_get_cell_style (GtkCList *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
 
   if (row < 0 || row >= clist->rows || column < 0 || column >= clist->columns)
     return NULL;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   return clist_row->cell[column].style;
 }
@@ -3312,25 +3341,24 @@ gtk_clist_set_row_style (GtkCList *clist,
   gint *old_width;
   gint i;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->style == style)
     return;
 
   old_width = g_new (gint, clist->columns);
 
-  if (!GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
+  if (!GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
     {
       for (i = 0; i < clist->columns; i++)
        if (clist->column[i].auto_resize)
          {
-           GTK_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row,
+           GTK_CLIST_GET_CLASS (clist)->cell_size_request (clist, clist_row,
                                                           i, &requisition);
            old_width[i] = requisition.width;
          }
@@ -3340,21 +3368,21 @@ gtk_clist_set_row_style (GtkCList *clist,
     {
       if (GTK_WIDGET_REALIZED (clist))
         gtk_style_detach (clist_row->style);
-      gtk_style_unref (clist_row->style);
+      g_object_unref (clist_row->style);
     }
 
   clist_row->style = style;
 
   if (clist_row->style)
     {
-      gtk_style_ref (clist_row->style);
+      g_object_ref (clist_row->style);
       
       if (GTK_WIDGET_REALIZED (clist))
         clist_row->style = gtk_style_attach (clist_row->style,
                                             clist->clist_window);
     }
 
-  if (GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
+  if (GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
     for (i = 0; i < clist->columns; i++)
       column_auto_resize (clist, clist_row, i, old_width[i]);
 
@@ -3364,7 +3392,7 @@ gtk_clist_set_row_style (GtkCList *clist,
   if (CLIST_UNFROZEN (clist))
     {
       if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+       GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
     }
 }
 
@@ -3374,13 +3402,12 @@ gtk_clist_get_row_style (GtkCList *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_val_if_fail (clist != NULL, NULL);
   g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
 
   if (row < 0 || row >= clist->rows)
     return NULL;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   return clist_row->style;
 }
@@ -3401,13 +3428,12 @@ gtk_clist_set_selectable (GtkCList *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (selectable == clist_row->selectable)
     return;
@@ -3417,11 +3443,11 @@ gtk_clist_set_selectable (GtkCList *clist,
   if (!selectable && clist_row->state == GTK_STATE_SELECTED)
     {
       if (clist->anchor >= 0 &&
-         clist->selection_mode == GTK_SELECTION_EXTENDED)
+         clist->selection_mode == GTK_SELECTION_MULTIPLE)
        {
          clist->drag_button = 0;
          remove_grab (clist);
-         GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+         GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
        }
       gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
                       row, -1, NULL);
@@ -3432,13 +3458,12 @@ gboolean
 gtk_clist_get_selectable (GtkCList *clist,
                          gint      row)
 {
-  g_return_val_if_fail (clist != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (clist), FALSE);
 
   if (row < 0 || row >= clist->rows)
     return FALSE;
 
-  return GTK_CLIST_ROW (g_list_nth (clist->row_list, row))->selectable;
+  return GTK_CLIST_ROW (ROW_ELEMENT (clist, row))->selectable;
 }
 
 void
@@ -3446,7 +3471,6 @@ gtk_clist_select_row (GtkCList *clist,
                      gint      row,
                      gint      column)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
@@ -3463,7 +3487,6 @@ gtk_clist_unselect_row (GtkCList *clist,
                        gint      row,
                        gint      column)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row >= clist->rows)
@@ -3478,28 +3501,25 @@ gtk_clist_unselect_row (GtkCList *clist,
 void
 gtk_clist_select_all (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  GTK_CLIST_CLASS_FW (clist)->select_all (clist);
+  GTK_CLIST_GET_CLASS (clist)->select_all (clist);
 }
 
 void
 gtk_clist_unselect_all (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  GTK_CLIST_CLASS_FW (clist)->unselect_all (clist);
+  GTK_CLIST_GET_CLASS (clist)->unselect_all (clist);
 }
 
 void
 gtk_clist_undo_selection (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (clist->selection_mode == GTK_SELECTION_EXTENDED &&
+  if (clist->selection_mode == GTK_SELECTION_MULTIPLE &&
       (clist->undo_selection || clist->undo_unselection))
     gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNDO_SELECTION]);
 }
@@ -3542,10 +3562,9 @@ toggle_row (GtkCList *clist,
 
   switch (clist->selection_mode)
     {
-    case GTK_SELECTION_EXTENDED:
     case GTK_SELECTION_MULTIPLE:
     case GTK_SELECTION_SINGLE:
-      clist_row = g_list_nth (clist->row_list, row)->data;
+      clist_row = ROW_ELEMENT (clist, row)->data;
 
       if (!clist_row)
        return;
@@ -3560,6 +3579,8 @@ toggle_row (GtkCList *clist,
       gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
                       row, column, event);
       break;
+    default:
+      g_assert_not_reached ();
     }
 }
 
@@ -3569,7 +3590,7 @@ fake_toggle_row (GtkCList *clist,
 {
   GList *work;
 
-  work = g_list_nth (clist->row_list, row);
+  work = ROW_ELEMENT (clist, row);
 
   if (!work || !GTK_CLIST_ROW (work)->selectable)
     return;
@@ -3581,27 +3602,33 @@ fake_toggle_row (GtkCList *clist,
   
   if (CLIST_UNFROZEN (clist) &&
       gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-    GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row,
+    GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row,
                                          GTK_CLIST_ROW (work));
 }
 
+static gboolean
+clist_has_grab (GtkCList *clist)
+{
+  return (GTK_WIDGET_HAS_GRAB (clist) &&
+         gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (clist))));
+}
+
 static void
 toggle_focus_row (GtkCList *clist)
 {
   g_return_if_fail (clist != 0);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) ||
+  if (clist_has_grab (clist) ||
       clist->focus_row < 0 || clist->focus_row >= clist->rows)
     return;
 
   switch (clist->selection_mode)
     {
     case  GTK_SELECTION_SINGLE:
-    case  GTK_SELECTION_MULTIPLE:
       toggle_row (clist, clist->focus_row, 0, NULL);
       break;
-    case GTK_SELECTION_EXTENDED:
+    case GTK_SELECTION_MULTIPLE:
       g_list_free (clist->undo_selection);
       g_list_free (clist->undo_unselection);
       clist->undo_selection = NULL;
@@ -3614,9 +3641,9 @@ toggle_focus_row (GtkCList *clist)
       if (GTK_CLIST_ADD_MODE(clist))
        fake_toggle_row (clist, clist->focus_row);
       else
-       GTK_CLIST_CLASS_FW (clist)->fake_unselect_all (clist,clist->focus_row);
+       GTK_CLIST_GET_CLASS (clist)->fake_unselect_all (clist,clist->focus_row);
 
-      GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+      GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
       break;
     default:
       break;
@@ -3629,8 +3656,8 @@ toggle_add_mode (GtkCList *clist)
   g_return_if_fail (clist != 0);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
-  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) ||
-      clist->selection_mode != GTK_SELECTION_EXTENDED)
+  if (clist_has_grab (clist) ||
+      clist->selection_mode != GTK_SELECTION_MULTIPLE)
     return;
 
   gtk_clist_draw_focus (GTK_WIDGET (clist));
@@ -3661,7 +3688,6 @@ real_select_row (GtkCList *clist,
   gint sel_row;
   gboolean row_selected;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row > (clist->rows - 1))
@@ -3694,7 +3720,7 @@ real_select_row (GtkCList *clist,
       break;
     }
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->state != GTK_STATE_NORMAL || !clist_row->selectable)
     return;
@@ -3712,7 +3738,7 @@ real_select_row (GtkCList *clist,
   
   if (CLIST_UNFROZEN (clist)
       && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-    GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+    GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
 }
 
 static void
@@ -3723,13 +3749,12 @@ real_unselect_row (GtkCList *clist,
 {
   GtkCListRow *clist_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (row < 0 || row > (clist->rows - 1))
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->state == GTK_STATE_SELECTED)
     {
@@ -3744,20 +3769,16 @@ real_unselect_row (GtkCList *clist,
       
       if (CLIST_UNFROZEN (clist)
          && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
+       GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row, clist_row);
     }
 }
 
 static void
 real_select_all (GtkCList *clist)
 {
-  GList *list;
-  gint i;
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+  if (clist_has_grab (clist))
     return;
 
   switch (clist->selection_mode)
@@ -3766,7 +3787,7 @@ real_select_all (GtkCList *clist)
     case GTK_SELECTION_BROWSE:
       return;
 
-    case GTK_SELECTION_EXTENDED:
+    case GTK_SELECTION_MULTIPLE:
       g_list_free (clist->undo_selection);
       g_list_free (clist->undo_unselection);
       clist->undo_selection = NULL;
@@ -3782,17 +3803,10 @@ real_select_all (GtkCList *clist)
       clist->drag_pos = 0;
       clist->undo_anchor = clist->focus_row;
       update_extended_selection (clist, clist->rows);
-      GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
-      return;
-
-    case GTK_SELECTION_MULTIPLE:
-      for (i = 0, list = clist->row_list; list; i++, list = list->next)
-       {
-         if (((GtkCListRow *)(list->data))->state == GTK_STATE_NORMAL)
-           gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
-                            i, -1, NULL);
-       }
+      GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
       return;
+    default:
+      g_assert_not_reached ();
     }
 }
 
@@ -3802,10 +3816,9 @@ real_unselect_all (GtkCList *clist)
   GList *list;
   gint i;
  
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+  if (clist_has_grab (clist))
     return;
 
   switch (clist->selection_mode)
@@ -3819,7 +3832,7 @@ real_unselect_all (GtkCList *clist)
          return;
        }
       break;
-    case GTK_SELECTION_EXTENDED:
+    case GTK_SELECTION_MULTIPLE:
       g_list_free (clist->undo_selection);
       g_list_free (clist->undo_unselection);
       clist->undo_selection = NULL;
@@ -3851,7 +3864,7 @@ fake_unselect_all (GtkCList *clist,
   GList *work;
   gint i;
 
-  if (row >= 0 && (work = g_list_nth (clist->row_list, row)))
+  if (row >= 0 && (work = ROW_ELEMENT (clist, row)))
     {
       if (GTK_CLIST_ROW (work)->state == GTK_STATE_NORMAL &&
          GTK_CLIST_ROW (work)->selectable)
@@ -3860,7 +3873,7 @@ fake_unselect_all (GtkCList *clist,
          
          if (CLIST_UNFROZEN (clist) &&
              gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
-           GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row,
+           GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, row,
                                                  GTK_CLIST_ROW (work));
        }  
     }
@@ -3868,7 +3881,7 @@ fake_unselect_all (GtkCList *clist,
   clist->undo_selection = clist->selection;
   clist->selection = NULL;
   clist->selection_end = NULL;
-  
+
   for (list = clist->undo_selection; list; list = list->next)
     {
       if ((i = GPOINTER_TO_INT (list->data)) == row ||
@@ -3878,7 +3891,7 @@ fake_unselect_all (GtkCList *clist,
       GTK_CLIST_ROW (work)->state = GTK_STATE_NORMAL;
       if (CLIST_UNFROZEN (clist) &&
          gtk_clist_row_is_visible (clist, i) != GTK_VISIBILITY_NONE)
-       GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, i,
+       GTK_CLIST_GET_CLASS (clist)->draw_row (clist, NULL, i,
                                              GTK_CLIST_ROW (work));
     }
 }
@@ -3888,15 +3901,13 @@ real_undo_selection (GtkCList *clist)
 {
   GList *work;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) ||
-      clist->selection_mode != GTK_SELECTION_EXTENDED)
+  if (clist_has_grab (clist) ||
+      clist->selection_mode != GTK_SELECTION_MULTIPLE)
     return;
 
-  if (clist->anchor >= 0)
-    GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+  GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
 
   if (!(clist->undo_selection || clist->undo_unselection))
     {
@@ -3909,8 +3920,11 @@ real_undo_selection (GtkCList *clist)
                     GPOINTER_TO_INT (work->data), -1, NULL);
 
   for (work = clist->undo_unselection; work; work = work->next)
-    gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], 
-                    GPOINTER_TO_INT (work->data), -1, NULL);
+    {
+      /* g_print ("unselect %d\n",GPOINTER_TO_INT (work->data)); */
+      gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], 
+                      GPOINTER_TO_INT (work->data), -1, NULL);
+    }
 
   if (GTK_WIDGET_HAS_FOCUS(clist) && clist->focus_row != clist->undo_anchor)
     {
@@ -3941,10 +3955,9 @@ set_anchor (GtkCList *clist,
            gint      anchor,
            gint      undo_anchor)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
-  if (clist->selection_mode != GTK_SELECTION_EXTENDED || clist->anchor >= 0)
+  if (clist->selection_mode != GTK_SELECTION_MULTIPLE || clist->anchor >= 0)
     return;
 
   g_list_free (clist->undo_selection);
@@ -3956,7 +3969,7 @@ set_anchor (GtkCList *clist,
     fake_toggle_row (clist, anchor);
   else
     {
-      GTK_CLIST_CLASS_FW (clist)->fake_unselect_all (clist, anchor);
+      GTK_CLIST_GET_CLASS (clist)->fake_unselect_all (clist, anchor);
       clist->anchor_state = GTK_STATE_SELECTED;
     }
 
@@ -3975,7 +3988,10 @@ resync_selection (GtkCList *clist,
   GList *list;
   GtkCListRow *clist_row;
 
-  if (clist->anchor < 0)
+  if (clist->selection_mode != GTK_SELECTION_MULTIPLE)
+    return;
+
+  if (clist->anchor < 0 || clist->drag_pos < 0)
     return;
 
   gtk_clist_freeze (clist);
@@ -4066,9 +4082,9 @@ resync_selection (GtkCList *clist,
              }
          }
     }
-
-  for (list = g_list_reverse (clist->undo_unselection); list;
-       list = list->next)
+  
+  clist->undo_unselection = g_list_reverse (clist->undo_unselection);
+  for (list = clist->undo_unselection; list; list = list->next)
     gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
                     GPOINTER_TO_INT (list->data), -1, event);
 
@@ -4095,7 +4111,7 @@ update_extended_selection (GtkCList *clist,
   gint h2 = 0;
   gint top;
 
-  if (clist->selection_mode != GTK_SELECTION_EXTENDED || clist->anchor == -1)
+  if (clist->selection_mode != GTK_SELECTION_MULTIPLE || clist->anchor == -1)
     return;
 
   if (row < 0)
@@ -4160,7 +4176,7 @@ update_extended_selection (GtkCList *clist,
           i++, list = list->next)
        if (GTK_CLIST_ROW (list)->selectable)
          {
-           if (GTK_CLIST_CLASS_FW (clist)->selection_find (clist, i, list))
+           if (GTK_CLIST_GET_CLASS (clist)->selection_find (clist, i, list))
              GTK_CLIST_ROW (list)->state = GTK_STATE_SELECTED;
            else
              GTK_CLIST_ROW (list)->state = GTK_STATE_NORMAL;
@@ -4237,10 +4253,9 @@ update_extended_selection (GtkCList *clist,
 static void
 start_selection (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+  if (clist_has_grab (clist))
     return;
 
   set_anchor (clist, GTK_CLIST_ADD_MODE(clist), clist->focus_row,
@@ -4250,14 +4265,13 @@ start_selection (GtkCList *clist)
 static void
 end_selection (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_FOCUS(clist)) ||
-      clist->anchor == -1)
+  if (gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (clist))) &&
+      GTK_WIDGET_HAS_FOCUS (clist))
     return;
-  
-  GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+  GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
 }
 
 static void
@@ -4266,11 +4280,10 @@ extend_selection (GtkCList      *clist,
                  gfloat         position,
                  gboolean       auto_start_selection)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) ||
-      clist->selection_mode != GTK_SELECTION_EXTENDED)
+  if (clist_has_grab (clist) ||
+      clist->selection_mode != GTK_SELECTION_MULTIPLE)
     return;
 
   if (auto_start_selection)
@@ -4309,12 +4322,13 @@ sync_selection (GtkCList *clist,
        clist->focus_row += d;
       if (clist->focus_row == -1 && clist->rows >= 1)
        clist->focus_row = 0;
-      else if (clist->focus_row >= clist->rows)
+      else if (d < 0 && clist->focus_row >= clist->rows - 1)
+       clist->focus_row = clist->rows - 2;
+      else if (clist->focus_row >= clist->rows)        /* Paranoia */
        clist->focus_row = clist->rows - 1;
     }
 
-  if (clist->selection_mode == GTK_SELECTION_BROWSE && clist->anchor != -1)
-    GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+  GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
 
   g_list_free (clist->undo_selection);
   g_list_free (clist->undo_unselection);
@@ -4345,7 +4359,6 @@ gtk_clist_destroy (GtkObject *object)
   gint i;
   GtkCList *clist;
 
-  g_return_if_fail (object != NULL);
   g_return_if_fail (GTK_IS_CLIST (object));
 
   clist = GTK_CLIST (object);
@@ -4392,22 +4405,17 @@ gtk_clist_destroy (GtkObject *object)
 }
 
 static void
-gtk_clist_finalize (GtkObject *object)
+gtk_clist_finalize (GObject *object)
 {
   GtkCList *clist;
 
-  g_return_if_fail (object != NULL);
   g_return_if_fail (GTK_IS_CLIST (object));
 
   clist = GTK_CLIST (object);
 
   columns_delete (clist);
 
-  g_mem_chunk_destroy (clist->cell_mem_chunk);
-  g_mem_chunk_destroy (clist->row_mem_chunk);
-
-  if (GTK_OBJECT_CLASS (parent_class)->finalize)
-    (*GTK_OBJECT_CLASS (parent_class)->finalize) (object);
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 /* GTKWIDGET
@@ -4415,10 +4423,8 @@ gtk_clist_finalize (GtkObject *object)
  *   gtk_clist_unrealize
  *   gtk_clist_map
  *   gtk_clist_unmap
- *   gtk_clist_draw
  *   gtk_clist_expose
  *   gtk_clist_style_set
- *   gtk_clist_key_press
  *   gtk_clist_button_press
  *   gtk_clist_button_release
  *   gtk_clist_motion
@@ -4438,7 +4444,6 @@ gtk_clist_realize (GtkWidget *widget)
   gint i;
   gint j;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
 
   clist = GTK_CLIST (widget);
@@ -4459,7 +4464,6 @@ gtk_clist_realize (GtkWidget *widget)
   attributes.event_mask |= (GDK_EXPOSURE_MASK |
                            GDK_BUTTON_PRESS_MASK |
                            GDK_BUTTON_RELEASE_MASK |
-                           GDK_KEY_PRESS_MASK |
                            GDK_KEY_RELEASE_MASK);
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
@@ -4495,9 +4499,9 @@ gtk_clist_realize (GtkWidget *widget)
 
   /* clist-window */
   attributes.x = (clist->internal_allocation.x +
-                 widget->style->klass->xthickness);
+                 widget->style->xthickness);
   attributes.y = (clist->internal_allocation.y +
-                 widget->style->klass->ythickness +
+                 widget->style->ythickness +
                  clist->column_title_area.height);
   attributes.width = clist->clist_window_width;
   attributes.height = clist->clist_window_height;
@@ -4517,10 +4521,10 @@ gtk_clist_realize (GtkWidget *widget)
   attributes.event_mask = (GDK_BUTTON_PRESS_MASK |
                           GDK_BUTTON_RELEASE_MASK |
                           GDK_POINTER_MOTION_MASK |
-                          GDK_POINTER_MOTION_HINT_MASK |
-                          GDK_KEY_PRESS_MASK);
+                          GDK_POINTER_MOTION_HINT_MASK);
   attributes_mask = GDK_WA_CURSOR;
-  attributes.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
+  attributes.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
+                                                 GDK_SB_H_DOUBLE_ARROW);
   clist->cursor_drag = attributes.cursor;
 
   attributes.x =  LIST_WIDTH (clist) + 1;
@@ -4547,7 +4551,8 @@ gtk_clist_realize (GtkWidget *widget)
   /* We'll use this gc to do scrolling as well */
   gdk_gc_set_exposures (clist->fg_gc, TRUE);
 
-  values.foreground = widget->style->white;
+  values.foreground = (widget->style->white.pixel==0 ?
+                      widget->style->black:widget->style->white);
   values.function = GDK_XOR;
   values.subwindow_mode = GDK_INCLUDE_INFERIORS;
   clist->xor_gc = gdk_gc_new_with_values (widget->window,
@@ -4591,7 +4596,6 @@ gtk_clist_unrealize (GtkWidget *widget)
   gint i;
   GtkCList *clist;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
 
   clist = GTK_CLIST (widget);
@@ -4599,8 +4603,12 @@ gtk_clist_unrealize (GtkWidget *widget)
   /* freeze the list */
   clist->freeze_count++;
 
-  /* detach optional row/cell styles */
+  if (GTK_WIDGET_MAPPED (widget))
+    gtk_clist_unmap (widget);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
 
+  /* detach optional row/cell styles */
   if (GTK_WIDGET_REALIZED (widget))
     {
       GtkCListRow *clist_row;
@@ -4627,12 +4635,16 @@ gtk_clist_unrealize (GtkWidget *widget)
   gdk_gc_destroy (clist->bg_gc);
 
   for (i = 0; i < clist->columns; i++)
-    if (clist->column[i].window)
-      {
-       gdk_window_set_user_data (clist->column[i].window, NULL);
-       gdk_window_destroy (clist->column[i].window);
-       clist->column[i].window = NULL;
-      }
+    {
+      if (clist->column[i].button)
+       gtk_widget_unrealize (clist->column[i].button);
+      if (clist->column[i].window)
+       {
+         gdk_window_set_user_data (clist->column[i].window, NULL);
+         gdk_window_destroy (clist->column[i].window);
+         clist->column[i].window = NULL;
+       }
+    }
 
   gdk_window_set_user_data (clist->clist_window, NULL);
   gdk_window_destroy (clist->clist_window);
@@ -4657,7 +4669,6 @@ gtk_clist_map (GtkWidget *widget)
   gint i;
   GtkCList *clist;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
 
   clist = GTK_CLIST (widget);
@@ -4668,10 +4679,12 @@ gtk_clist_map (GtkWidget *widget)
 
       /* map column buttons */
       for (i = 0; i < clist->columns; i++)
-       if (clist->column[i].button &&
-           GTK_WIDGET_VISIBLE (clist->column[i].button) &&
-           !GTK_WIDGET_MAPPED (clist->column[i].button))
-         gtk_widget_map (clist->column[i].button);
+       {
+         if (clist->column[i].button &&
+             GTK_WIDGET_VISIBLE (clist->column[i].button) &&
+             !GTK_WIDGET_MAPPED (clist->column[i].button))
+           gtk_widget_map (clist->column[i].button);
+       }
       
       for (i = 0; i < clist->columns; i++)
        if (clist->column[i].window && clist->column[i].button)
@@ -4695,7 +4708,6 @@ gtk_clist_unmap (GtkWidget *widget)
   gint i;
   GtkCList *clist;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
 
   clist = GTK_CLIST (widget);
@@ -4704,13 +4716,11 @@ gtk_clist_unmap (GtkWidget *widget)
     {
       GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
 
-      if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+      if (clist_has_grab (clist))
        {
          remove_grab (clist);
 
-         if (clist->anchor != -1 &&
-             clist->selection_mode == GTK_SELECTION_EXTENDED)
-           GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, NULL);
+         GTK_CLIST_GET_CLASS (widget)->resync_selection (clist, NULL);
 
          clist->click_cell.row = -1;
          clist->click_cell.column = -1;
@@ -4748,60 +4758,12 @@ gtk_clist_unmap (GtkWidget *widget)
     }
 }
 
-static void
-gtk_clist_draw (GtkWidget    *widget,
-               GdkRectangle *area)
-{
-  GtkCList *clist;
-  gint border_width;
-  GdkRectangle child_area;
-  int i;
-
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_CLIST (widget));
-  g_return_if_fail (area != NULL);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      clist = GTK_CLIST (widget);
-      border_width = GTK_CONTAINER (widget)->border_width;
-
-      gdk_window_clear_area (widget->window,
-                            area->x - border_width, 
-                            area->y - border_width,
-                            area->width, area->height);
-
-      /* draw list shadow/border */
-      gtk_draw_shadow (widget->style, widget->window,
-                      GTK_STATE_NORMAL, clist->shadow_type,
-                      0, 0, 
-                      clist->clist_window_width +
-                      (2 * widget->style->klass->xthickness),
-                      clist->clist_window_height +
-                      (2 * widget->style->klass->ythickness) +
-                      clist->column_title_area.height);
-
-      gdk_window_clear_area (clist->clist_window, 0, 0, -1, -1);
-      draw_rows (clist, NULL);
-
-      for (i = 0; i < clist->columns; i++)
-       {
-         if (!clist->column[i].visible)
-           continue;
-         if (clist->column[i].button &&
-             gtk_widget_intersect(clist->column[i].button, area, &child_area))
-           gtk_widget_draw (clist->column[i].button, &child_area);
-       }
-    }
-}
-
 static gint
 gtk_clist_expose (GtkWidget      *widget,
                  GdkEventExpose *event)
 {
   GtkCList *clist;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
@@ -4815,14 +4777,34 @@ gtk_clist_expose (GtkWidget      *widget,
                         GTK_STATE_NORMAL, clist->shadow_type,
                         0, 0,
                         clist->clist_window_width +
-                        (2 * widget->style->klass->xthickness),
+                        (2 * widget->style->xthickness),
                         clist->clist_window_height +
-                        (2 * widget->style->klass->ythickness) +
+                        (2 * widget->style->ythickness) +
                         clist->column_title_area.height);
 
       /* exposure events on the list */
       if (event->window == clist->clist_window)
        draw_rows (clist, &event->area);
+
+      if (event->window == clist->clist_window &&
+         clist->drag_highlight_row >= 0)
+       GTK_CLIST_GET_CLASS (clist)->draw_drag_highlight
+         (clist, g_list_nth (clist->row_list,
+                             clist->drag_highlight_row)->data,
+          clist->drag_highlight_row, clist->drag_highlight_pos);
+
+      if (event->window == clist->title_window)
+       {
+         gint i;
+         
+         for (i = 0; i < clist->columns; i++)
+           {
+             if (clist->column[i].button)
+               gtk_container_propagate_expose (GTK_CONTAINER (clist),
+                                               clist->column[i].button,
+                                               event);
+           }
+       }
     }
 
   return FALSE;
@@ -4834,7 +4816,6 @@ gtk_clist_style_set (GtkWidget *widget,
 {
   GtkCList *clist;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
 
   if (GTK_WIDGET_CLASS (parent_class)->style_set)
@@ -4853,18 +4834,11 @@ gtk_clist_style_set (GtkWidget *widget,
 
   /* text properties */
   if (!GTK_CLIST_ROW_HEIGHT_SET(clist))
-    {
-      clist->row_height = (widget->style->font->ascent +
-                          widget->style->font->descent + 1);
-      clist->row_center_offset = widget->style->font->ascent + 1.5;
-    }
-  else
-    clist->row_center_offset = 1.5 + (clist->row_height +
-                                     widget->style->font->ascent -
-                                     widget->style->font->descent - 1) / 2;
+    /* Reset clist->row_height */
+    gtk_clist_set_row_height (clist, 0);
 
   /* Column widths */
-  if (!GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
+  if (!GTK_CLIST_AUTO_RESIZE_BLOCKED (clist))
     {
       gint width;
       gint i;
@@ -4879,34 +4853,6 @@ gtk_clist_style_set (GtkWidget *widget,
     }
 }
 
-static gint
-gtk_clist_key_press (GtkWidget   *widget,
-                    GdkEventKey *event)
-{
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_CLASS (parent_class)->key_press_event &&
-      GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
-    return TRUE;
-
-  switch (event->keyval)
-    {
-    case GDK_Tab:
-    case GDK_ISO_Left_Tab:
-      if (event->state & GDK_SHIFT_MASK)
-       return gtk_container_focus (GTK_CONTAINER (widget),
-                                   GTK_DIR_TAB_BACKWARD);
-      else
-       return gtk_container_focus (GTK_CONTAINER (widget),
-                                   GTK_DIR_TAB_FORWARD);
-    default:
-      break;
-    }
-  return FALSE;
-}
-
 static gint
 gtk_clist_button_press (GtkWidget      *widget,
                        GdkEventButton *event)
@@ -4919,7 +4865,6 @@ gtk_clist_button_press (GtkWidget      *widget,
   gint column;
   gint button_actions;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
@@ -5008,11 +4953,13 @@ gtk_clist_button_press (GtkWidget      *widget,
              switch (clist->selection_mode)
                {
                case GTK_SELECTION_SINGLE:
-               case GTK_SELECTION_MULTIPLE:
                  if (event->type != GDK_BUTTON_PRESS)
-                   gtk_signal_emit (GTK_OBJECT (clist),
-                                    clist_signals[SELECT_ROW],
-                                    row, column, event);
+                   {
+                     gtk_signal_emit (GTK_OBJECT (clist),
+                                      clist_signals[SELECT_ROW],
+                                      row, column, event);
+                     clist->anchor = -1;
+                   }
                  else
                    clist->anchor = row;
                  break;
@@ -5021,13 +4968,13 @@ gtk_clist_button_press (GtkWidget      *widget,
                                   clist_signals[SELECT_ROW],
                                   row, column, event);
                  break;
-               case GTK_SELECTION_EXTENDED:
+               case GTK_SELECTION_MULTIPLE:
                  if (event->type != GDK_BUTTON_PRESS)
                    {
                      if (clist->anchor != -1)
                        {
                          update_extended_selection (clist, clist->focus_row);
-                         GTK_CLIST_CLASS_FW (clist)->resync_selection
+                         GTK_CLIST_GET_CLASS (clist)->resync_selection
                            (clist, (GdkEvent *) event);
                        }
                      gtk_signal_emit (GTK_OBJECT (clist),
@@ -5080,7 +5027,7 @@ gtk_clist_button_press (GtkWidget      *widget,
                }
            }
        }
-      return FALSE;
+      return TRUE;
     }
 
   /* press on resize windows */
@@ -5115,7 +5062,10 @@ gtk_clist_button_press (GtkWidget      *widget,
        if (GTK_CLIST_ADD_MODE(clist))
          gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_SOLID, 0, 0);
        draw_xor_line (clist);
+
+        return TRUE;
       }
+
   return FALSE;
 }
 
@@ -5126,7 +5076,6 @@ gtk_clist_button_release (GtkWidget      *widget,
   GtkCList *clist;
   gint button_actions;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
@@ -5155,7 +5104,7 @@ gtk_clist_button_release (GtkWidget      *widget,
       GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
       gtk_widget_get_pointer (widget, &x, NULL);
       gtk_grab_remove (widget);
-      gdk_pointer_ungrab (event->time);
+      gdk_display_pointer_ungrab (gtk_widget_get_display (widget), event->time);
 
       if (clist->x_drag >= 0)
        draw_xor_line (clist);
@@ -5169,7 +5118,8 @@ gtk_clist_button_release (GtkWidget      *widget,
 
       width = new_column_width (clist, i, &x);
       gtk_clist_set_column_width (clist, i, width);
-      return FALSE;
+
+      return TRUE;
     }
 
   if (clist->drag_button == event->button)
@@ -5187,15 +5137,15 @@ gtk_clist_button_release (GtkWidget      *widget,
        {
          switch (clist->selection_mode)
            {
-           case GTK_SELECTION_EXTENDED:
+           case GTK_SELECTION_MULTIPLE:
              if (!(event->state & GDK_SHIFT_MASK) ||
+                 !GTK_WIDGET_CAN_FOCUS (widget) ||
                  event->x < 0 || event->x >= clist->clist_window_width ||
                  event->y < 0 || event->y >= clist->clist_window_height)
-               GTK_CLIST_CLASS_FW (clist)->resync_selection
+               GTK_CLIST_GET_CLASS (clist)->resync_selection
                  (clist, (GdkEvent *) event);
              break;
            case GTK_SELECTION_SINGLE:
-           case GTK_SELECTION_MULTIPLE:
              if (get_selection_info (clist, event->x, event->y,
                                      &row, &column))
                {
@@ -5208,7 +5158,10 @@ gtk_clist_button_release (GtkWidget      *widget,
              break;
            }
        }
+
+      return TRUE;
     }
+  
   return FALSE;
 }
 
@@ -5223,11 +5176,10 @@ gtk_clist_motion (GtkWidget      *widget,
   gint new_width;
   gint button_actions = 0;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
 
   clist = GTK_CLIST (widget);
-  if (!(gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)))
+  if (!clist_has_grab (clist))
     return FALSE;
 
   if (clist->drag_button > 0)
@@ -5275,6 +5227,11 @@ gtk_clist_motion (GtkWidget      *widget,
 
   if (event->is_hint || event->window != clist->clist_window)
     gdk_window_get_pointer (clist->clist_window, &x, &y, NULL);
+  else
+    {
+      x = event->x;
+      y = event->y;
+    }
 
   if (GTK_CLIST_REORDERABLE(clist) && button_actions & GTK_BUTTON_DRAGS)
     {
@@ -5307,8 +5264,8 @@ gtk_clist_motion (GtkWidget      *widget,
       if (clist->htimer)
        return FALSE;
 
-      clist->htimer = gtk_timeout_add
-       (SCROLL_TIME, (GtkFunction) horizontal_timeout, clist);
+      clist->htimer = gdk_threads_add_timeout
+       (SCROLL_TIME, (GSourceFunc) horizontal_timeout, clist);
 
       if (!((x < 0 && clist->hadjustment->value == 0) ||
            (x >= clist->clist_window_width &&
@@ -5339,8 +5296,8 @@ gtk_clist_motion (GtkWidget      *widget,
       if (clist->vtimer)
        return FALSE;
 
-      clist->vtimer = gtk_timeout_add (SCROLL_TIME,
-                                      (GtkFunction) vertical_timeout, clist);
+      clist->vtimer = gdk_threads_add_timeout (SCROLL_TIME,
+                                    (GSourceFunc) vertical_timeout, clist);
 
       if (clist->drag_button &&
          ((y < 0 && clist->focus_row == 0) ||
@@ -5367,7 +5324,7 @@ gtk_clist_motion (GtkWidget      *widget,
          gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
                           clist->focus_row, -1, event);
          break;
-       case GTK_SELECTION_EXTENDED:
+       case GTK_SELECTION_MULTIPLE:
          update_extended_selection (clist, clist->focus_row);
          break;
        default:
@@ -5391,7 +5348,6 @@ gtk_clist_size_request (GtkWidget      *widget,
   GtkCList *clist;
   gint i;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
   g_return_if_fail (requisition != NULL);
 
@@ -5414,11 +5370,11 @@ gtk_clist_size_request (GtkWidget      *widget,
            MAX (clist->column_title_area.height,
                 child_requisition.height);
        }
-
-  requisition->width += (widget->style->klass->xthickness +
+  
+  requisition->width += (widget->style->xthickness +
                         GTK_CONTAINER (widget)->border_width) * 2;
   requisition->height += (clist->column_title_area.height +
-                         (widget->style->klass->ythickness +
+                         (widget->style->ythickness +
                           GTK_CONTAINER (widget)->border_width) * 2);
 
   /* if (!clist->hadjustment) */
@@ -5435,7 +5391,6 @@ gtk_clist_size_allocate (GtkWidget     *widget,
   GtkAllocation clist_allocation;
   gint border_width;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
   g_return_if_fail (allocation != NULL);
 
@@ -5464,14 +5419,14 @@ gtk_clist_size_allocate (GtkWidget     *widget,
        
   /* allocate clist window assuming no scrollbars */
   clist_allocation.x = (clist->internal_allocation.x +
-                       widget->style->klass->xthickness);
+                       widget->style->xthickness);
   clist_allocation.y = (clist->internal_allocation.y +
-                       widget->style->klass->ythickness +
+                       widget->style->ythickness +
                        clist->column_title_area.height);
   clist_allocation.width = MAX (1, (gint)clist->internal_allocation.width - 
-                               (2 * (gint)widget->style->klass->xthickness));
+                               (2 * (gint)widget->style->xthickness));
   clist_allocation.height = MAX (1, (gint)clist->internal_allocation.height -
-                                (2 * (gint)widget->style->klass->ythickness) -
+                                (2 * (gint)widget->style->ythickness) -
                                 (gint)clist->column_title_area.height);
   
   clist->clist_window_width = clist_allocation.width;
@@ -5487,8 +5442,8 @@ gtk_clist_size_allocate (GtkWidget     *widget,
     }
   
   /* position the window which holds the column title buttons */
-  clist->column_title_area.x = widget->style->klass->xthickness;
-  clist->column_title_area.y = widget->style->klass->ythickness;
+  clist->column_title_area.x = widget->style->xthickness;
+  clist->column_title_area.y = widget->style->ythickness;
   clist->column_title_area.width = clist_allocation.width;
   
   if (GTK_WIDGET_REALIZED (widget))
@@ -5519,7 +5474,6 @@ gtk_clist_forall (GtkContainer *container,
   GtkCList *clist;
   guint i;
 
-  g_return_if_fail (container != NULL);
   g_return_if_fail (GTK_IS_CLIST (container));
   g_return_if_fail (callback != NULL);
 
@@ -5681,7 +5635,7 @@ draw_row (GtkCList     *clist,
   /* if the function is passed the pointer to the row instead of null,
    * it avoids this expensive lookup */
   if (!clist_row)
-    clist_row = (g_list_nth (clist->row_list, row))->data;
+    clist_row = ROW_ELEMENT (clist, row)->data;
 
   /* rectangle of the entire row */
   row_rectangle.x = 0;
@@ -5695,7 +5649,7 @@ draw_row (GtkCList     *clist,
   cell_rectangle.width = row_rectangle.width;
   cell_rectangle.height = CELL_SPACING;
 
-  /* rectangle used to clip drawing operations, it's y and height
+  /* rectangle used to clip drawing operations, its y and height
    * positions only need to be set once, so we set them once here. 
    * the x and width are set withing the drawing loop below once per
    * column */
@@ -5719,14 +5673,14 @@ draw_row (GtkCList     *clist,
       if (gdk_rectangle_intersect (area, &cell_rectangle,
                                   &intersect_rectangle))
        gdk_draw_rectangle (clist->clist_window,
-                           widget->style->base_gc[GTK_STATE_ACTIVE],
+                           widget->style->base_gc[GTK_STATE_NORMAL],
                            TRUE,
                            intersect_rectangle.x,
                            intersect_rectangle.y,
                            intersect_rectangle.width,
                            intersect_rectangle.height);
 
-      /* the last row has to clear it's bottom cell spacing too */
+      /* the last row has to clear its bottom cell spacing too */
       if (clist_row == clist->row_list_end->data)
        {
          cell_rectangle.y += clist->row_height + CELL_SPACING;
@@ -5734,7 +5688,7 @@ draw_row (GtkCList     *clist,
          if (gdk_rectangle_intersect (area, &cell_rectangle,
                                       &intersect_rectangle))
            gdk_draw_rectangle (clist->clist_window,
-                               widget->style->base_gc[GTK_STATE_ACTIVE],
+                               widget->style->base_gc[GTK_STATE_NORMAL],
                                TRUE,
                                intersect_rectangle.x,
                                intersect_rectangle.y,
@@ -5750,20 +5704,20 @@ draw_row (GtkCList     *clist,
     {
       rect = &clip_rectangle;
       gdk_draw_rectangle (clist->clist_window,
-                         widget->style->base_gc[GTK_STATE_ACTIVE],
+                         widget->style->base_gc[GTK_STATE_NORMAL],
                          TRUE,
                          cell_rectangle.x,
                          cell_rectangle.y,
                          cell_rectangle.width,
                          cell_rectangle.height);
 
-      /* the last row has to clear it's bottom cell spacing too */
+      /* the last row has to clear its bottom cell spacing too */
       if (clist_row == clist->row_list_end->data)
        {
          cell_rectangle.y += clist->row_height + CELL_SPACING;
 
          gdk_draw_rectangle (clist->clist_window,
-                             widget->style->base_gc[GTK_STATE_ACTIVE],
+                             widget->style->base_gc[GTK_STATE_NORMAL],
                              TRUE,
                              cell_rectangle.x,
                              cell_rectangle.y,
@@ -5782,12 +5736,13 @@ draw_row (GtkCList     *clist,
       GtkStyle *style;
       GdkGC *fg_gc;
       GdkGC *bg_gc;
+      PangoLayout *layout;
+      PangoRectangle logical_rect;
 
       gint width;
       gint height;
       gint pixmap_width;
       gint offset = 0;
-      gint row_center_offset;
 
       if (!clist->column[i].visible)
        continue;
@@ -5813,31 +5768,33 @@ draw_row (GtkCList     *clist,
       clip_rectangle.width -= (2 * COLUMN_INSET + CELL_SPACING +
                               (i == last_column) * CELL_SPACING);
 
+
       /* calculate real width for column justification */
+      
+      layout = _gtk_clist_create_cell_layout (clist, clist_row, i);
+      if (layout)
+       {
+         pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+         width = logical_rect.width;
+       }
+      else
+       width = 0;
+
       pixmap_width = 0;
       offset = 0;
       switch (clist_row->cell[i].type)
        {
-       case GTK_CELL_TEXT:
-         width = gdk_string_width (style->font,
-                                   GTK_CELL_TEXT (clist_row->cell[i])->text);
-         break;
        case GTK_CELL_PIXMAP:
          gdk_window_get_size (GTK_CELL_PIXMAP (clist_row->cell[i])->pixmap,
                               &pixmap_width, &height);
-         width = pixmap_width;
+         width += pixmap_width;
          break;
        case GTK_CELL_PIXTEXT:
          gdk_window_get_size (GTK_CELL_PIXTEXT (clist_row->cell[i])->pixmap,
                               &pixmap_width, &height);
-         width = (pixmap_width +
-                  GTK_CELL_PIXTEXT (clist_row->cell[i])->spacing +
-                  gdk_string_width (style->font,
-                                    GTK_CELL_PIXTEXT
-                                    (clist_row->cell[i])->text));
+         width += pixmap_width + GTK_CELL_PIXTEXT (clist_row->cell[i])->spacing;
          break;
        default:
-         continue;
          break;
        }
 
@@ -5879,24 +5836,22 @@ draw_row (GtkCList     *clist,
                              (clip_rectangle.height - height) / 2,
                              pixmap_width, height);
          offset += GTK_CELL_PIXTEXT (clist_row->cell[i])->spacing;
+
+         /* Fall through */
        case GTK_CELL_TEXT:
-         if (style != GTK_WIDGET (clist)->style)
-           row_center_offset = (((clist->row_height - style->font->ascent -
-                                 style->font->descent - 1) / 2) + 1.5 +
-                                style->font->ascent);
-         else
-           row_center_offset = clist->row_center_offset;
-
-         gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle);
-         gdk_draw_string (clist->clist_window, style->font, fg_gc,
-                          offset,
-                          row_rectangle.y + row_center_offset + 
-                          clist_row->cell[i].vertical,
-                          (clist_row->cell[i].type == GTK_CELL_PIXTEXT) ?
-                          GTK_CELL_PIXTEXT (clist_row->cell[i])->text :
-                          GTK_CELL_TEXT (clist_row->cell[i])->text);
-         gdk_gc_set_clip_rectangle (fg_gc, NULL);
-         break;
+         if (layout)
+           {
+             gint row_center_offset = (clist->row_height - logical_rect.height - 1) / 2;
+
+             gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle);
+             gdk_draw_layout (clist->clist_window, fg_gc,
+                              offset,
+                              row_rectangle.y + row_center_offset + clist_row->cell[i].vertical,
+                              layout);
+              g_object_unref (G_OBJECT (layout));
+             gdk_gc_set_clip_rectangle (fg_gc, NULL);
+           }
+         break;
        default:
          break;
        }
@@ -5933,7 +5888,6 @@ draw_rows (GtkCList     *clist,
   gint first_row;
   gint last_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (clist->row_height == 0 ||
@@ -5958,7 +5912,7 @@ draw_rows (GtkCList     *clist,
   if (clist->rows == first_row)
     first_row--;
 
-  list = g_list_nth (clist->row_list, first_row);
+  list = ROW_ELEMENT (clist, first_row);
   i = first_row;
   while (list)
     {
@@ -5968,13 +5922,13 @@ draw_rows (GtkCList     *clist,
       if (i > last_row)
        return;
 
-      GTK_CLIST_CLASS_FW (clist)->draw_row (clist, area, i, clist_row);
+      GTK_CLIST_GET_CLASS (clist)->draw_row (clist, area, i, clist_row);
       i++;
     }
 
   if (!area)
-    gdk_window_clear_area (clist->clist_window,
-                          0, ROW_TOP_YPIXEL (clist, i), -1, -1);
+    gdk_window_clear_area (clist->clist_window, 0,
+                          ROW_TOP_YPIXEL (clist, i), 0, 0);
 }
 
 static void                          
@@ -5988,7 +5942,7 @@ draw_xor_line (GtkCList *clist)
 
   gdk_draw_line (widget->window, clist->xor_gc,
                  clist->x_drag,
-                widget->style->klass->ythickness,
+                widget->style->ythickness,
                  clist->x_drag,
                  clist->column_title_area.height +
                 clist->clist_window_height + 1);
@@ -5997,7 +5951,6 @@ draw_xor_line (GtkCList *clist)
 static void
 clist_refresh (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
   if (CLIST_UNFROZEN (clist))
@@ -6020,7 +5973,6 @@ get_selection_info (GtkCList *clist,
 {
   gint trow, tcol;
 
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
 
   /* bounds checking, return false if the user clicked 
@@ -6049,7 +6001,6 @@ gtk_clist_get_selection_info (GtkCList *clist,
                              gint     *row, 
                              gint     *column)
 {
-  g_return_val_if_fail (clist != NULL, 0);
   g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
   return get_selection_info (clist, x, y, row, column);
 }
@@ -6069,12 +6020,15 @@ adjust_adjustments (GtkCList *clist,
   if (clist->vadjustment)
     {
       clist->vadjustment->page_size = clist->clist_window_height;
-      clist->vadjustment->page_increment = clist->clist_window_height / 2;
       clist->vadjustment->step_increment = clist->row_height;
+      clist->vadjustment->page_increment =
+       MAX (clist->vadjustment->page_size - clist->vadjustment->step_increment,
+            clist->vadjustment->page_size / 2);
       clist->vadjustment->lower = 0;
       clist->vadjustment->upper = LIST_HEIGHT (clist);
 
-      if (clist->clist_window_height - clist->voffset > LIST_HEIGHT (clist))
+      if (clist->clist_window_height - clist->voffset > LIST_HEIGHT (clist) ||
+         (clist->voffset + (gint)clist->vadjustment->value) != 0)
        {
          clist->vadjustment->value = MAX (0, (LIST_HEIGHT (clist) -
                                               clist->clist_window_height));
@@ -6087,12 +6041,15 @@ adjust_adjustments (GtkCList *clist,
   if (clist->hadjustment)
     {
       clist->hadjustment->page_size = clist->clist_window_width;
-      clist->hadjustment->page_increment = clist->clist_window_width / 2;
       clist->hadjustment->step_increment = 10;
+      clist->hadjustment->page_increment =
+       MAX (clist->hadjustment->page_size - clist->hadjustment->step_increment,
+            clist->hadjustment->page_size / 2);
       clist->hadjustment->lower = 0;
       clist->hadjustment->upper = LIST_WIDTH (clist);
 
-      if (clist->clist_window_width - clist->hoffset > LIST_WIDTH (clist))
+      if (clist->clist_window_width - clist->hoffset > LIST_WIDTH (clist) ||
+         (clist->hoffset + (gint)clist->hadjustment->value) != 0)
        {
          clist->hadjustment->value = MAX (0, (LIST_WIDTH (clist) -
                                               clist->clist_window_width));
@@ -6147,74 +6104,85 @@ vadjustment_value_changed (GtkAdjustment *adjustment,
                           gpointer       data)
 {
   GtkCList *clist;
-  GdkRectangle area;
-  gint diff, value;
+  gint dy, value;
 
   g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
   g_return_if_fail (GTK_IS_CLIST (data));
 
   clist = GTK_CLIST (data);
 
-  if (!GTK_WIDGET_DRAWABLE (clist) || adjustment != clist->vadjustment)
+  if (adjustment != clist->vadjustment)
     return;
 
-  value = adjustment->value;
+  value = -adjustment->value;
+  dy = value - clist->voffset;
+  clist->voffset = value;
 
-  if (value > -clist->voffset)
+  if (GTK_WIDGET_DRAWABLE (clist))
     {
-      /* scroll down */
-      diff = value + clist->voffset;
+      gdk_window_scroll (clist->clist_window, 0, dy);
+      gdk_window_process_updates (clist->clist_window, FALSE);
+    }
+  
+  return;
+}
 
-      /* we have to re-draw the whole screen here... */
-      if (diff >= clist->clist_window_height)
-       {
-         clist->voffset = -value;
-         draw_rows (clist, NULL);
-         return;
-       }
+typedef struct
+{
+  GdkWindow *window;
+  gint dx;
+} ScrollData;
 
-      if ((diff != 0) && (diff != clist->clist_window_height))
-       gdk_window_copy_area (clist->clist_window, clist->fg_gc,
-                             0, 0, clist->clist_window, 0, diff,
-                             clist->clist_window_width,
-                             clist->clist_window_height - diff);
+/* The window to which widget->window is relative */
+#define ALLOCATION_WINDOW(widget)              \
+   (GTK_WIDGET_NO_WINDOW (widget) ?            \
+    (widget)->window :                          \
+     gdk_window_get_parent ((widget)->window))
 
-      area.x = 0;
-      area.y = clist->clist_window_height - diff;
-      area.width = clist->clist_window_width;
-      area.height = diff;
+static void
+adjust_allocation_recurse (GtkWidget *widget,
+                          gpointer   data)
+{
+  ScrollData *scroll_data = data;
+  
+  if (!GTK_WIDGET_REALIZED (widget))
+    {
+      if (GTK_WIDGET_VISIBLE (widget))
+       {
+         GdkRectangle tmp_rectangle = widget->allocation;
+         tmp_rectangle.x += scroll_data->dx;
+      
+         gtk_widget_size_allocate (widget, &tmp_rectangle);
+       }
     }
   else
     {
-      /* scroll up */
-      diff = -clist->voffset - value;
-
-      /* we have to re-draw the whole screen here... */
-      if (diff >= clist->clist_window_height)
+      if (ALLOCATION_WINDOW (widget) == scroll_data->window)
        {
-         clist->voffset = -value;
-         draw_rows (clist, NULL);
-         return;
-       }
-
-      if ((diff != 0) && (diff != clist->clist_window_height))
-       gdk_window_copy_area (clist->clist_window, clist->fg_gc,
-                             0, diff, clist->clist_window, 0, 0,
-                             clist->clist_window_width,
-                             clist->clist_window_height - diff);
+         widget->allocation.x += scroll_data->dx;
 
-      area.x = 0;
-      area.y = 0;
-      area.width = clist->clist_window_width;
-      area.height = diff;
+         if (GTK_IS_CONTAINER (widget))
+           gtk_container_forall (GTK_CONTAINER (widget),
+                                 adjust_allocation_recurse,
+                                 data);
+       }
     }
+}
 
-  clist->voffset = -value;
-  if ((diff != 0) && (diff != clist->clist_window_height))
-    check_exposures (clist);
+static void
+adjust_allocation (GtkWidget *widget,
+                  gint       dx)
+{
+  ScrollData scroll_data;
 
-  draw_rows (clist, &area);
+  if (GTK_WIDGET_REALIZED (widget))
+    scroll_data.window = ALLOCATION_WINDOW (widget);
+  else
+    scroll_data.window = NULL;
+    
+  scroll_data.dx = dx;
+  
+  adjust_allocation_recurse (widget, &scroll_data);
 }
 
 static void
@@ -6222,185 +6190,91 @@ hadjustment_value_changed (GtkAdjustment *adjustment,
                           gpointer       data)
 {
   GtkCList *clist;
+  GtkContainer *container;
   GdkRectangle area;
   gint i;
   gint y = 0;
-  gint diff = 0;
   gint value;
+  gint dx;
 
   g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
   g_return_if_fail (GTK_IS_CLIST (data));
 
   clist = GTK_CLIST (data);
+  container = GTK_CONTAINER (data);
 
-  if (!GTK_WIDGET_DRAWABLE (clist) || adjustment != clist->hadjustment)
+  if (adjustment != clist->hadjustment)
     return;
 
   value = adjustment->value;
 
-  /* move the column buttons and resize windows */
-  for (i = 0; i < clist->columns; i++)
-    {
-      if (clist->column[i].button)
-       {
-         clist->column[i].button->allocation.x -= value + clist->hoffset;
-         
-         if (clist->column[i].button->window)
-           {
-             gdk_window_move (clist->column[i].button->window,
-                              clist->column[i].button->allocation.x,
-                              clist->column[i].button->allocation.y);
-             
-             if (clist->column[i].window)
-               gdk_window_move (clist->column[i].window,
-                                clist->column[i].button->allocation.x +
-                                clist->column[i].button->allocation.width - 
-                                (DRAG_WIDTH / 2), 0); 
-           }
-       }
-    }
+  dx = -value - clist->hoffset;
 
-  if (value > -clist->hoffset)
-    {
-      /* scroll right */
-      diff = value + clist->hoffset;
-      
-      clist->hoffset = -value;
-      
-      /* we have to re-draw the whole screen here... */
-      if (diff >= clist->clist_window_width)
-       {
-         draw_rows (clist, NULL);
-         return;
-       }
+  if (GTK_WIDGET_REALIZED (clist))
+    gdk_window_scroll (clist->title_window, dx, 0);
 
-      if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
-         !GTK_CLIST_CHILD_HAS_FOCUS(clist) && GTK_CLIST_ADD_MODE(clist))
-       {
-         y = ROW_TOP_YPIXEL (clist, clist->focus_row);
-             
-         gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y,
-                             clist->clist_window_width - 1,
-                             clist->row_height - 1);
-       }
-      gdk_window_copy_area (clist->clist_window,
-                           clist->fg_gc,
-                           0, 0,
-                           clist->clist_window,
-                           diff,
-                           0,
-                           clist->clist_window_width - diff,
-                           clist->clist_window_height);
+  /* adjust the column button's allocations */
+  for (i = 0; i < clist->columns; i++)
+    if (clist->column[i].button)
+      adjust_allocation (clist->column[i].button, dx);
 
-      area.x = clist->clist_window_width - diff;
-    }
-  else
-    {
-      /* scroll left */
-      if (!(diff = -clist->hoffset - value))
-       return;
+  clist->hoffset = -value;
 
-      clist->hoffset = -value;
-      
-      /* we have to re-draw the whole screen here... */
-      if (diff >= clist->clist_window_width)
-       {
-         draw_rows (clist, NULL);
-         return;
-       }
-      
+  if (GTK_WIDGET_DRAWABLE (clist))
+    {
       if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
-         !GTK_CLIST_CHILD_HAS_FOCUS(clist) && GTK_CLIST_ADD_MODE(clist))
-       {
-         y = ROW_TOP_YPIXEL (clist, clist->focus_row);
-         
-         gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y,
-                             clist->clist_window_width - 1,
-                             clist->row_height - 1);
-       }
-
-      gdk_window_copy_area (clist->clist_window,
-                           clist->fg_gc,
-                           diff, 0,
-                           clist->clist_window,
-                           0,
-                           0,
-                           clist->clist_window_width - diff,
-                           clist->clist_window_height);
-         
-      area.x = 0;
-    }
-
-  area.y = 0;
-  area.width = diff;
-  area.height = clist->clist_window_height;
-
-  check_exposures (clist);
+          !container->focus_child && GTK_CLIST_ADD_MODE(clist))
+        {
+          y = ROW_TOP_YPIXEL (clist, clist->focus_row);
+      
+          gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y,
+                              clist->clist_window_width - 1,
+                              clist->row_height - 1);
+        }
+      gdk_window_scroll (clist->clist_window, dx, 0);
+      gdk_window_process_updates (clist->clist_window, FALSE);
 
-  if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
-      !GTK_CLIST_CHILD_HAS_FOCUS(clist))
-    {
-      if (GTK_CLIST_ADD_MODE(clist))
-       {
-         gint focus_row;
-         
-         focus_row = clist->focus_row;
-         clist->focus_row = -1;
-         draw_rows (clist, &area);
-         clist->focus_row = focus_row;
-         
-         gdk_draw_rectangle (clist->clist_window, clist->xor_gc,
-                             FALSE, 0, y, clist->clist_window_width - 1,
-                             clist->row_height - 1);
-         return;
-       }
-      else
-       {
-         gint x0;
-         gint x1;
+      if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) &&
+          !container->focus_child)
+        {
+          if (GTK_CLIST_ADD_MODE(clist))
+            {
+              gint focus_row;
          
-         if (area.x == 0)
-           {
-             x0 = clist->clist_window_width - 1;
-             x1 = diff;
-           }
-         else
-           {
-             x0 = 0;
-             x1 = area.x - 1;
-           }
+              focus_row = clist->focus_row;
+              clist->focus_row = -1;
+              draw_rows (clist, &area);
+              clist->focus_row = focus_row;
          
-         y = ROW_TOP_YPIXEL (clist, clist->focus_row);
-         gdk_draw_line (clist->clist_window, clist->xor_gc,
-                        x0, y + 1, x0, y + clist->row_height - 2);
-         gdk_draw_line (clist->clist_window, clist->xor_gc,
-                        x1, y + 1, x1, y + clist->row_height - 2);
+              gdk_draw_rectangle (clist->clist_window, clist->xor_gc,
+                                  FALSE, 0, y, clist->clist_window_width - 1,
+                                  clist->row_height - 1);
+              return;
+            }
+          else if (ABS(dx) < clist->clist_window_width - 1)
+            {
+              gint x0;
+              gint x1;
          
-       }
-    }
-  draw_rows (clist, &area);
-}
-
-static void
-check_exposures (GtkCList *clist)
-{
-  GdkEvent *event;
-
-  if (!GTK_WIDGET_REALIZED (clist))
-    return;
-
-  /* Make sure graphics expose events are processed before scrolling
-   * again */
-  while ((event = gdk_event_get_graphics_expose (clist->clist_window)) != NULL)
-    {
-      gtk_widget_event (GTK_WIDGET (clist), event);
-      if (event->expose.count == 0)
-       {
-         gdk_event_free (event);
-         break;
-       }
-      gdk_event_free (event);
+              if (dx > 0)
+                {
+                  x0 = clist->clist_window_width - 1;
+                  x1 = dx;
+                }
+              else
+                {
+                  x0 = 0;
+                  x1 = clist->clist_window_width - 1 + dx;
+                }
+
+              y = ROW_TOP_YPIXEL (clist, clist->focus_row);
+              gdk_draw_line (clist->clist_window, clist->xor_gc,
+                             x0, y + 1, x0, y + clist->row_height - 2);
+              gdk_draw_line (clist->clist_window, clist->xor_gc,
+                             x1, y + 1, x1, y + clist->row_height - 2);
+            }
+        }
     }
 }
 
@@ -6474,8 +6348,8 @@ row_new (GtkCList *clist)
   int i;
   GtkCListRow *clist_row;
 
-  clist_row = g_chunk_new (GtkCListRow, clist->row_mem_chunk);
-  clist_row->cell = g_chunk_new (GtkCell, clist->cell_mem_chunk);
+  clist_row = g_slice_new (GtkCListRow);
+  clist_row->cell = g_slice_alloc (sizeof (GtkCell) * clist->columns);
 
   for (i = 0; i < clist->columns; i++)
     {
@@ -6504,13 +6378,13 @@ row_delete (GtkCList    *clist,
 
   for (i = 0; i < clist->columns; i++)
     {
-      GTK_CLIST_CLASS_FW (clist)->set_cell_contents
+      GTK_CLIST_GET_CLASS (clist)->set_cell_contents
        (clist, clist_row, i, GTK_CELL_EMPTY, NULL, 0, NULL, NULL);
       if (clist_row->cell[i].style)
        {
          if (GTK_WIDGET_REALIZED (clist))
            gtk_style_detach (clist_row->cell[i].style);
-         gtk_style_unref (clist_row->cell[i].style);
+         g_object_unref (clist_row->cell[i].style);
        }
     }
 
@@ -6518,125 +6392,129 @@ row_delete (GtkCList    *clist,
     {
       if (GTK_WIDGET_REALIZED (clist))
         gtk_style_detach (clist_row->style);
-      gtk_style_unref (clist_row->style);
+      g_object_unref (clist_row->style);
     }
 
   if (clist_row->destroy)
     clist_row->destroy (clist_row->data);
 
-  g_mem_chunk_free (clist->cell_mem_chunk, clist_row->cell);
-  g_mem_chunk_free (clist->row_mem_chunk, clist_row);
+  g_slice_free1 (sizeof (GtkCell) * clist->columns, clist_row->cell);
+  g_slice_free (GtkCListRow, clist_row);
 }
 
 /* FOCUS FUNCTIONS
+ *   gtk_clist_focus_content_area
  *   gtk_clist_focus
  *   gtk_clist_draw_focus
  *   gtk_clist_focus_in
  *   gtk_clist_focus_out
- *   gtk_clist_set_focus_child
  *   title_focus
  */
-static gint
-gtk_clist_focus (GtkContainer     *container,
+static void
+gtk_clist_focus_content_area (GtkCList *clist)
+{
+  if (clist->focus_row < 0)
+    {
+      clist->focus_row = 0;
+      
+      if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
+          clist->selection_mode == GTK_SELECTION_MULTIPLE) &&
+         !clist->selection)
+       gtk_signal_emit (GTK_OBJECT (clist),
+                        clist_signals[SELECT_ROW],
+                        clist->focus_row, -1, NULL);
+    }
+  gtk_widget_grab_focus (GTK_WIDGET (clist));
+}
+
+static gboolean
+gtk_clist_focus (GtkWidget        *widget,
                 GtkDirectionType  direction)
 {
-  GtkCList *clist;
+  GtkCList *clist = GTK_CLIST (widget);
   GtkWidget *focus_child;
-  gint old_row;
-
-  g_return_val_if_fail (container != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_CLIST (container), FALSE);
+  gboolean is_current_focus;
 
-  if (!GTK_WIDGET_IS_SENSITIVE (container))
+  if (!GTK_WIDGET_IS_SENSITIVE (widget))
     return FALSE;
-  
-  clist = GTK_CLIST (container);
-  focus_child = container->focus_child;
-  old_row = clist->focus_row;
 
+  focus_child = GTK_CONTAINER (widget)->focus_child;
+  
+  is_current_focus = gtk_widget_is_focus (GTK_WIDGET (clist));
+                         
+  if (focus_child &&
+      gtk_widget_child_focus (focus_child, direction))
+    return TRUE;
+      
   switch (direction)
     {
     case GTK_DIR_LEFT:
     case GTK_DIR_RIGHT:
-      if (GTK_CLIST_CHILD_HAS_FOCUS(clist))
+      if (focus_child)
        {
-         if (title_focus (clist, direction))
+         if (title_focus_move (clist, direction))
            return TRUE;
-         gtk_container_set_focus_child (container, NULL);
-         return FALSE;
-        }
-      gtk_widget_grab_focus (GTK_WIDGET (container));
-      return TRUE;
+       }
+      else if (!is_current_focus)
+       {
+         gtk_clist_focus_content_area (clist);
+         return TRUE;
+       }
+      break;
     case GTK_DIR_DOWN:
     case GTK_DIR_TAB_FORWARD:
-      if (GTK_CLIST_CHILD_HAS_FOCUS(clist))
+      if (!focus_child && !is_current_focus)
        {
-         gboolean tf = FALSE;
-
-         if (((focus_child && direction == GTK_DIR_DOWN) ||
-              !(tf = title_focus (clist, GTK_DIR_TAB_FORWARD)))
-             && clist->rows)
-           {
-             if (clist->focus_row < 0)
-               {
-                 clist->focus_row = 0;
-
-                 if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
-                      clist->selection_mode == GTK_SELECTION_EXTENDED) &&
-                     !clist->selection)
-                   gtk_signal_emit (GTK_OBJECT (clist),
-                                    clist_signals[SELECT_ROW],
-                                    clist->focus_row, -1, NULL);
-               }
-             gtk_widget_grab_focus (GTK_WIDGET (container));
-             return TRUE;
-           }
-
-         if (tf)
+         if (title_focus_in (clist, direction))
            return TRUE;
        }
       
-      GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
+      if (!is_current_focus && clist->rows)
+       {
+         gtk_clist_focus_content_area (clist);
+         return TRUE;
+       }
       break;
     case GTK_DIR_UP:
     case GTK_DIR_TAB_BACKWARD:
-      if (!focus_child &&
-         GTK_CLIST_CHILD_HAS_FOCUS(clist) && clist->rows)
+      if (!focus_child && is_current_focus)
        {
-         if (clist->focus_row < 0)
-           {
-             clist->focus_row = 0;
-             if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
-                  clist->selection_mode == GTK_SELECTION_EXTENDED) &&
-                 !clist->selection)
-               gtk_signal_emit (GTK_OBJECT (clist),
-                                clist_signals[SELECT_ROW],
-                                clist->focus_row, -1, NULL);
-           }
-         gtk_widget_grab_focus (GTK_WIDGET (container));
+         if (title_focus_in (clist, direction))
+           return TRUE;
+       }
+      
+      if (!is_current_focus && !focus_child && clist->rows)
+       {
+         gtk_clist_focus_content_area (clist);
          return TRUE;
        }
-
-      GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
-
-      if (title_focus (clist, direction))
-       return TRUE;
-
       break;
     default:
       break;
     }
 
-  gtk_container_set_focus_child (container, NULL);
   return FALSE;
 }
 
+static void
+gtk_clist_set_focus_child (GtkContainer *container,
+                          GtkWidget    *child)
+{
+  GtkCList *clist = GTK_CLIST (container);
+  gint i;
+
+  for (i = 0; i < clist->columns; i++)
+    if (clist->column[i].button == child)
+      clist->focus_header_column = i;
+  
+  parent_class->set_focus_child (container, child);
+}
+
 static void
 gtk_clist_draw_focus (GtkWidget *widget)
 {
   GtkCList *clist;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
 
   if (!GTK_WIDGET_DRAWABLE (widget) || !GTK_WIDGET_CAN_FOCUS (widget))
@@ -6654,16 +6532,7 @@ static gint
 gtk_clist_focus_in (GtkWidget     *widget,
                    GdkEventFocus *event)
 {
-  GtkCList *clist;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
-  GTK_CLIST_UNSET_FLAG (widget, CLIST_CHILD_HAS_FOCUS);
-
-  clist = GTK_CLIST (widget);
+  GtkCList *clist = GTK_CLIST (widget);
 
   if (clist->selection_mode == GTK_SELECTION_BROWSE &&
       clist->selection == NULL && clist->focus_row > -1)
@@ -6675,10 +6544,10 @@ gtk_clist_focus_in (GtkWidget     *widget,
        gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
                         clist->focus_row, -1, event);
       else
-       gtk_widget_draw_focus (widget);
+       gtk_clist_draw_focus (widget);
     }
   else
-    gtk_widget_draw_focus (widget);
+    gtk_clist_draw_focus (widget);
 
   return FALSE;
 }
@@ -6687,142 +6556,165 @@ static gint
 gtk_clist_focus_out (GtkWidget     *widget,
                     GdkEventFocus *event)
 {
-  GtkCList *clist;
+  GtkCList *clist = GTK_CLIST (widget);
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+  gtk_clist_draw_focus (widget);
+  
+  GTK_CLIST_GET_CLASS (widget)->resync_selection (clist, (GdkEvent *) event);
 
-  GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
-  GTK_CLIST_SET_FLAG (widget, CLIST_CHILD_HAS_FOCUS);
+  return FALSE;
+}
 
-  gtk_widget_draw_focus (widget);
+static gboolean
+focus_column (GtkCList *clist, gint column, gint dir)
+{
+  GtkWidget *child = clist->column[column].button;
   
-  clist = GTK_CLIST (widget);
-
-  if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_EXTENDED)
-    GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, (GdkEvent *) event);
+  if (gtk_widget_child_focus (child, dir))
+    {
+      return TRUE;
+    }
+  else if (GTK_WIDGET_CAN_FOCUS (child))
+    {
+      gtk_widget_grab_focus (child);
+      return TRUE;
+    }
 
   return FALSE;
 }
 
-static void
-gtk_clist_set_focus_child (GtkContainer *container,
-                          GtkWidget    *child)
+/* Focus moved onto the headers. Focus first focusable and visible child.
+ * (FIXME: focus the last focused child if visible)
+ */
+static gboolean
+title_focus_in (GtkCList *clist, gint dir)
 {
-  g_return_if_fail (container != NULL);
-  g_return_if_fail (GTK_IS_CLIST (container));
+  gint i;
+  gint left, right;
 
-  if (child)
+  if (!GTK_CLIST_SHOW_TITLES (clist))
+    return FALSE;
+
+  /* Check last focused column */
+  if (clist->focus_header_column != -1)
     {
-      g_return_if_fail (GTK_IS_WIDGET (child));
-      GTK_CLIST_SET_FLAG (container, CLIST_CHILD_HAS_FOCUS);
+      i = clist->focus_header_column;
+      
+      left = COLUMN_LEFT_XPIXEL (clist, i);
+      right = left + clist->column[i].area.width;
+      
+      if (left >= 0 && right <= clist->clist_window_width)
+       {
+         if (focus_column (clist, i, dir))
+           return TRUE;
+       }
     }
 
-  parent_class->set_focus_child (container, child);
+  /* Check fully visible columns */
+  for (i = 0 ; i < clist->columns ; i++)
+    {
+      left = COLUMN_LEFT_XPIXEL (clist, i);
+      right = left + clist->column[i].area.width;
+      
+      if (left >= 0 && right <= clist->clist_window_width)
+       {
+         if (focus_column (clist, i, dir))
+           return TRUE;
+       }
+    }
+
+  /* Check partially visible columns */
+  for (i = 0 ; i < clist->columns ; i++)
+    {
+      left = COLUMN_LEFT_XPIXEL (clist, i);
+      right = left + clist->column[i].area.width;
+
+      if ((left < 0 && right > 0) ||
+         (left < clist->clist_window_width && right > clist->clist_window_width))
+       {
+         if (focus_column (clist, i, dir))
+           return TRUE;
+       }
+    }
+      
+  return FALSE;
 }
 
+/* Move the focus right or left within the title buttons, scrolling
+ * as necessary to keep the focused child visible.
+ */
 static gboolean
-title_focus (GtkCList *clist,
-            gint      dir)
+title_focus_move (GtkCList *clist,
+                 gint      dir)
 {
   GtkWidget *focus_child;
   gboolean return_val = FALSE;
-  gint last_column;
-  gint d = 1;
-  gint i = 0;
+  gint d = 0;
+  gint i = -1;
   gint j;
 
   if (!GTK_CLIST_SHOW_TITLES(clist))
     return FALSE;
 
   focus_child = GTK_CONTAINER (clist)->focus_child;
+  g_assert (focus_child);
 
-  for (last_column = clist->columns - 1;
-       last_column >= 0 && !clist->column[last_column].visible; last_column--)
-    ;
-  
+  /* Movement direction within headers
+   */
   switch (dir)
     {
-    case GTK_DIR_TAB_BACKWARD:
-    case GTK_DIR_UP:
-      if (!focus_child || !GTK_CLIST_CHILD_HAS_FOCUS(clist))
-       {
-         if (dir == GTK_DIR_UP)
-           i = COLUMN_FROM_XPIXEL (clist, 0);
-         else
-           i = last_column;
-         focus_child = clist->column[i].button;
-         dir = GTK_DIR_TAB_FORWARD;
-       }
-      else
-       d = -1;
+    case GTK_DIR_RIGHT:
+      d = 1;
       break;
     case GTK_DIR_LEFT:
       d = -1;
-      if (!focus_child)
-       {
-         i = last_column;
-         focus_child = clist->column[i].button;
-       }
       break;
-    case GTK_DIR_RIGHT:
-      if (!focus_child)
+    }
+  
+  for (i = 0; i < clist->columns; i++)
+    if (clist->column[i].button == focus_child)
+      break;
+  
+  g_assert (i != -1);          /* Have a starting column */
+  
+  j = i + d;
+  while (!return_val && j >= 0 && j < clist->columns)
+    {
+      if (clist->column[j].button &&
+         GTK_WIDGET_VISIBLE (clist->column[j].button))
        {
-         i = 0;
-         focus_child = clist->column[i].button;
+         if (focus_column (clist, j, dir))
+           {
+             return_val = TRUE;
+             break;
+           }
        }
-      break;
+      j += d;
     }
 
-  if (focus_child)
-    while (i < clist->columns)
-      {
-       if (clist->column[i].button == focus_child)
-         {
-           if (clist->column[i].button && 
-               GTK_WIDGET_VISIBLE (clist->column[i].button) &&
-               GTK_IS_CONTAINER (clist->column[i].button) &&
-               !GTK_WIDGET_HAS_FOCUS(clist->column[i].button))
-             if (gtk_container_focus 
-                 (GTK_CONTAINER (clist->column[i].button), dir))
+  /* If we didn't find it, wrap around and keep looking
+   */
+  if (!return_val)
+    {
+      j = d > 0 ? 0 : clist->columns - 1;
+
+      while (!return_val && j != i)
+       {
+         if (clist->column[j].button &&
+             GTK_WIDGET_VISIBLE (clist->column[j].button))
+           {
+             if (focus_column (clist, j, dir))
                {
                  return_val = TRUE;
-                 i -= d;
+                 break;
                }
-           if (!return_val && dir == GTK_DIR_UP)
-             return FALSE;
-           i += d;
-           break;
-         }
-       i++;
-      }
-
-  j = i;
+           }
+         j += d;
+       }
+    }
 
-  if (!return_val)
-    while (j >= 0 && j < clist->columns)
-      {
-       if (clist->column[j].button &&
-           GTK_WIDGET_VISIBLE (clist->column[j].button))
-         {
-           if (GTK_IS_CONTAINER (clist->column[j].button) &&
-               gtk_container_focus 
-               (GTK_CONTAINER (clist->column[j].button), dir))
-             {
-               return_val = TRUE;
-               break;
-             }
-           else if (GTK_WIDGET_CAN_FOCUS (clist->column[j].button))
-             {
-               gtk_widget_grab_focus (clist->column[j].button);
-               return_val = TRUE;
-               break;
-             }
-         }
-       j += d;
-      }
-  
+  /* Scroll horizontally so focused column is visible
+   */
   if (return_val)
     {
       if (COLUMN_LEFT_XPIXEL (clist, j) < CELL_SPACING + COLUMN_INSET)
@@ -6830,13 +6722,20 @@ title_focus (GtkCList *clist,
       else if (COLUMN_LEFT_XPIXEL(clist, j) + clist->column[j].area.width >
               clist->clist_window_width)
        {
+         gint last_column;
+         
+         for (last_column = clist->columns - 1;
+              last_column >= 0 && !clist->column[last_column].visible; last_column--);
+
          if (j == last_column)
            gtk_clist_moveto (clist, -1, j, 0, 0);
          else
            gtk_clist_moveto (clist, -1, j, 0, 1);
        }
     }
-  return return_val;
+  return TRUE;                 /* Even if we didn't find a new one, we can keep the
+                                * focus in the same place.
+                                */
 }
 
 /* PRIVATE SCROLLING FUNCTIONS
@@ -6863,6 +6762,7 @@ move_focus_row (GtkCList      *clist,
 
   switch (scroll_type)
     {
+    case GTK_SCROLL_STEP_UP:
     case GTK_SCROLL_STEP_BACKWARD:
       if (clist->focus_row <= 0)
        return;
@@ -6870,6 +6770,8 @@ move_focus_row (GtkCList      *clist,
       clist->focus_row--;
       gtk_clist_draw_focus (widget);
       break;
+
+    case GTK_SCROLL_STEP_DOWN:
     case GTK_SCROLL_STEP_FORWARD:
       if (clist->focus_row >= clist->rows - 1)
        return;
@@ -6877,6 +6779,7 @@ move_focus_row (GtkCList      *clist,
       clist->focus_row++;
       gtk_clist_draw_focus (widget);
       break;
+    case GTK_SCROLL_PAGE_UP:
     case GTK_SCROLL_PAGE_BACKWARD:
       if (clist->focus_row <= 0)
        return;
@@ -6887,6 +6790,7 @@ move_focus_row (GtkCList      *clist,
                              (2 * (clist->row_height + CELL_SPACING)));
       gtk_clist_draw_focus (widget);
       break;
+    case GTK_SCROLL_PAGE_DOWN:
     case GTK_SCROLL_PAGE_FORWARD:
       if (clist->focus_row >= clist->rows - 1)
        return;
@@ -6921,7 +6825,7 @@ scroll_horizontal (GtkCList      *clist,
   g_return_if_fail (clist != 0);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+  if (clist_has_grab (clist))
     return;
 
   for (last_column = clist->columns - 1;
@@ -6993,15 +6897,14 @@ scroll_vertical (GtkCList      *clist,
 {
   gint old_focus_row;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+  if (clist_has_grab (clist))
     return;
 
   switch (clist->selection_mode)
     {
-    case GTK_SELECTION_EXTENDED:
+    case GTK_SELECTION_MULTIPLE:
       if (clist->anchor >= 0)
        return;
     case GTK_SELECTION_BROWSE:
@@ -7025,16 +6928,20 @@ scroll_vertical (GtkCList      *clist,
        {
        case GTK_VISIBILITY_NONE:
          if (old_focus_row != clist->focus_row &&
-             !(clist->selection_mode == GTK_SELECTION_EXTENDED &&
+             !(clist->selection_mode == GTK_SELECTION_MULTIPLE &&
                GTK_CLIST_ADD_MODE(clist)))
            gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
                             clist->focus_row, -1, NULL);
          switch (scroll_type)
            {
+            case GTK_SCROLL_PAGE_UP:
+            case GTK_SCROLL_STEP_UP:
            case GTK_SCROLL_STEP_BACKWARD:
            case GTK_SCROLL_PAGE_BACKWARD:
              gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
              break;
+            case GTK_SCROLL_PAGE_DOWN:
+            case GTK_SCROLL_STEP_DOWN:
            case GTK_SCROLL_STEP_FORWARD:
            case GTK_SCROLL_PAGE_FORWARD:
              gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
@@ -7065,7 +6972,7 @@ scroll_vertical (GtkCList      *clist,
            }
        default:
          if (old_focus_row != clist->focus_row &&
-             !(clist->selection_mode == GTK_SELECTION_EXTENDED &&
+             !(clist->selection_mode == GTK_SELECTION_MULTIPLE &&
                GTK_CLIST_ADD_MODE(clist)))
            gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
                             clist->focus_row, -1, NULL);
@@ -7088,14 +6995,14 @@ static void
 move_horizontal (GtkCList *clist,
                 gint      diff)
 {
-  gfloat value;
+  gdouble value;
 
   if (!clist->hadjustment)
     return;
 
   value = CLAMP (clist->hadjustment->value + diff, 0.0,
                 clist->hadjustment->upper - clist->hadjustment->page_size);
-  gtk_adjustment_set_value(clist->hadjustment, value);
+  gtk_adjustment_set_value (clist->hadjustment, value);
 }
 
 static void
@@ -7103,7 +7010,7 @@ move_vertical (GtkCList *clist,
               gint      row,
               gfloat    align)
 {
-  gfloat value;
+  gdouble value;
 
   if (!clist->vadjustment)
     return;
@@ -7115,53 +7022,34 @@ move_vertical (GtkCList *clist,
   if (value + clist->vadjustment->page_size > clist->vadjustment->upper)
     value = clist->vadjustment->upper - clist->vadjustment->page_size;
 
-  gtk_adjustment_set_value(clist->vadjustment, value);
+  gtk_adjustment_set_value (clist->vadjustment, value);
 }
 
-static gint
-horizontal_timeout (GtkCList *clist)
+static void
+do_fake_motion (GtkWidget *widget)
 {
-  gint x, y;
-  GdkEventMotion event;
-  GdkModifierType mask;
-
-  GDK_THREADS_ENTER ();
+  GdkEvent *event = gdk_event_new (GDK_MOTION_NOTIFY);
 
-  clist->htimer = 0;
-  gdk_window_get_pointer (clist->clist_window, &x, &y, &mask);
+  event->motion.send_event = TRUE;
 
-  event.is_hint = 0;
-  event.x = x;
-  event.y = y;
-  event.state = mask;
+  gtk_clist_motion (widget, (GdkEventMotion *)event);
+  gdk_event_free (event);
+}
 
-  gtk_clist_motion (GTK_WIDGET (clist), &event);
+static gint
+horizontal_timeout (GtkCList *clist)
+{
+  clist->htimer = 0;
+  do_fake_motion (GTK_WIDGET (clist));
 
-  GDK_THREADS_LEAVE ();
-  
   return FALSE;
 }
 
 static gint
 vertical_timeout (GtkCList *clist)
 {
-  gint x, y;
-  GdkEventMotion event;
-  GdkModifierType mask;
-
-  GDK_THREADS_ENTER ();
-
   clist->vtimer = 0;
-  gdk_window_get_pointer (clist->clist_window, &x, &y, &mask);
-
-  event.is_hint = 0;
-  event.x = x;
-  event.y = y;
-  event.state = mask;
-
-  gtk_clist_motion (GTK_WIDGET (clist), &event);
-
-  GDK_THREADS_LEAVE ();
+  do_fake_motion (GTK_WIDGET (clist));
 
   return FALSE;
 }
@@ -7169,22 +7057,26 @@ vertical_timeout (GtkCList *clist)
 static void
 remove_grab (GtkCList *clist)
 {
+  GtkWidget *widget = GTK_WIDGET (clist);
+  
   if (GTK_WIDGET_HAS_GRAB (clist))
     {
-      gtk_grab_remove (GTK_WIDGET (clist));
-      if (gdk_pointer_is_grabbed ())
-       gdk_pointer_ungrab (GDK_CURRENT_TIME);
+      GdkDisplay *display = gtk_widget_get_display (widget);
+      
+      gtk_grab_remove (widget);
+      if (gdk_display_pointer_is_grabbed (display))
+       gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
     }
 
   if (clist->htimer)
     {
-      gtk_timeout_remove (clist->htimer);
+      g_source_remove (clist->htimer);
       clist->htimer = 0;
     }
 
   if (clist->vtimer)
     {
-      gtk_timeout_remove (clist->vtimer);
+      g_source_remove (clist->vtimer);
       clist->vtimer = 0;
     }
 }
@@ -7199,17 +7091,15 @@ remove_grab (GtkCList *clist)
 void
 gtk_clist_sort (GtkCList *clist)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  GTK_CLIST_CLASS_FW (clist)->sort_list (clist);
+  GTK_CLIST_GET_CLASS (clist)->sort_list (clist);
 }
 
 void
 gtk_clist_set_compare_func (GtkCList            *clist,
                            GtkCListCompareFunc  cmp_func)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   clist->compare = (cmp_func) ? cmp_func : default_compare;
@@ -7219,7 +7109,6 @@ void
 gtk_clist_set_auto_sort (GtkCList *clist,
                         gboolean  auto_sort)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
   if (GTK_CLIST_AUTO_SORT(clist) && !auto_sort)
@@ -7235,7 +7124,6 @@ void
 gtk_clist_set_sort_type (GtkCList    *clist,
                         GtkSortType  sort_type)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
   clist->sort_type = sort_type;
@@ -7245,7 +7133,6 @@ void
 gtk_clist_set_sort_column (GtkCList *clist,
                           gint      column)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (column < 0 || column >= clist->columns)
@@ -7311,20 +7198,19 @@ real_sort_list (GtkCList *clist)
   GList *work;
   gint i;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (clist->rows <= 1)
     return;
 
-  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+  if (clist_has_grab (clist))
     return;
 
   gtk_clist_freeze (clist);
 
-  if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_EXTENDED)
+  if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_MULTIPLE)
     {
-      GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+      GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
       g_list_free (clist->undo_selection);
       g_list_free (clist->undo_unselection);
       clist->undo_selection = NULL;
@@ -7401,6 +7287,7 @@ gtk_clist_merge (GtkCList *clist,
        }
     }
 
+  z.next->prev = NULL;
   return z.next;
 }
 
@@ -7412,7 +7299,7 @@ gtk_clist_mergesort (GtkCList *clist,
   GList *half;
   gint i;
 
-  if (num == 1)
+  if (num <= 1)
     {
       return list;
     }
@@ -7452,6 +7339,63 @@ drag_dest_info_destroy (gpointer data)
   g_free (info);
 }
 
+static void
+drag_dest_cell (GtkCList         *clist,
+               gint              x,
+               gint              y,
+               GtkCListDestInfo *dest_info)
+{
+  GtkWidget *widget;
+
+  widget = GTK_WIDGET (clist);
+
+  dest_info->insert_pos = GTK_CLIST_DRAG_NONE;
+
+  y -= (GTK_CONTAINER (clist)->border_width +
+       widget->style->ythickness +
+       clist->column_title_area.height);
+
+  dest_info->cell.row = ROW_FROM_YPIXEL (clist, y);
+  if (dest_info->cell.row >= clist->rows)
+    {
+      dest_info->cell.row = clist->rows - 1;
+      y = ROW_TOP_YPIXEL (clist, dest_info->cell.row) + clist->row_height;
+    }
+  if (dest_info->cell.row < -1)
+    dest_info->cell.row = -1;
+  
+  x -= GTK_CONTAINER (widget)->border_width + widget->style->xthickness;
+
+  dest_info->cell.column = COLUMN_FROM_XPIXEL (clist, x);
+
+  if (dest_info->cell.row >= 0)
+    {
+      gint y_delta;
+      gint h = 0;
+
+      y_delta = y - ROW_TOP_YPIXEL (clist, dest_info->cell.row);
+      
+      if (GTK_CLIST_DRAW_DRAG_RECT(clist))
+       {
+         dest_info->insert_pos = GTK_CLIST_DRAG_INTO;
+         h = clist->row_height / 4;
+       }
+      else if (GTK_CLIST_DRAW_DRAG_LINE(clist))
+       {
+         dest_info->insert_pos = GTK_CLIST_DRAG_BEFORE;
+         h = clist->row_height / 2;
+       }
+
+      if (GTK_CLIST_DRAW_DRAG_LINE(clist))
+       {
+         if (y_delta < h)
+           dest_info->insert_pos = GTK_CLIST_DRAG_BEFORE;
+         else if (clist->row_height - y_delta < h)
+           dest_info->insert_pos = GTK_CLIST_DRAG_AFTER;
+       }
+    }
+}
+
 static void
 gtk_clist_drag_begin (GtkWidget             *widget,
                      GdkDragContext *context)
@@ -7459,7 +7403,6 @@ gtk_clist_drag_begin (GtkWidget        *widget,
   GtkCList *clist;
   GtkCListCellInfo *info;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
   g_return_if_fail (context != NULL);
 
@@ -7470,15 +7413,16 @@ gtk_clist_drag_begin (GtkWidget      *widget,
 
   switch (clist->selection_mode)
     {
-    case GTK_SELECTION_EXTENDED:
+    case GTK_SELECTION_MULTIPLE:
       update_extended_selection (clist, clist->focus_row);
-      GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+      GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
       break;
     case GTK_SELECTION_SINGLE:
-    case GTK_SELECTION_MULTIPLE:
       clist->anchor = -1;
     case GTK_SELECTION_BROWSE:
       break;
+    default:
+      g_assert_not_reached ();
     }
 
   info = g_dataset_get_data (context, "gtk-clist-drag-source");
@@ -7508,7 +7452,6 @@ gtk_clist_drag_end (GtkWidget        *widget,
 {
   GtkCList *clist;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
   g_return_if_fail (context != NULL);
 
@@ -7526,7 +7469,6 @@ gtk_clist_drag_leave (GtkWidget      *widget,
   GtkCList *clist;
   GtkCListDestInfo *dest_info;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
   g_return_if_fail (context != NULL);
 
@@ -7541,17 +7483,18 @@ gtk_clist_drag_leave (GtkWidget      *widget,
          gtk_drag_get_source_widget (context) == widget)
        {
          GList *list;
-         GdkAtom atom = gdk_atom_intern ("gtk-clist-drag-reorder", FALSE);
+         GdkAtom atom = gdk_atom_intern_static_string ("gtk-clist-drag-reorder");
 
          list = context->targets;
          while (list)
            {
-             if (atom == GPOINTER_TO_INT (list->data))
+             if (atom == GDK_POINTER_TO_ATOM (list->data))
                {
-                 GTK_CLIST_CLASS_FW (clist)->draw_drag_highlight
+                 GTK_CLIST_GET_CLASS (clist)->draw_drag_highlight
                    (clist,
                     g_list_nth (clist->row_list, dest_info->cell.row)->data,
                     dest_info->cell.row, dest_info->insert_pos);
+                 clist->drag_highlight_row = -1;
                  break;
                }
              list = list->next;
@@ -7569,56 +7512,13 @@ gtk_clist_drag_motion (GtkWidget      *widget,
                       guint           time)
 {
   GtkCList *clist;
-  gint row, column;
+  GtkCListDestInfo new_info;
   GtkCListDestInfo *dest_info;
-  gint h = 0;
-  gint insert_pos = GTK_CLIST_DRAG_NONE;
-  gint y_delta;
 
-  g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
 
   clist = GTK_CLIST (widget);
 
-  y -= (GTK_CONTAINER (widget)->border_width +
-       widget->style->klass->ythickness + clist->column_title_area.height);
-  row = ROW_FROM_YPIXEL (clist, y);
-
-  if (row >= clist->rows)
-    {
-      row = clist->rows - 1;
-      y = ROW_TOP_YPIXEL (clist, row) + clist->row_height;
-    }
-  if (row < -1)
-    row = -1;
-
-  x -= GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness;
-  column = COLUMN_FROM_XPIXEL (clist, x);
-
-  if (row >= 0)
-    {
-      y_delta = y - ROW_TOP_YPIXEL (clist, row);
-      
-      if (GTK_CLIST_DRAW_DRAG_RECT(clist))
-       {
-         insert_pos = GTK_CLIST_DRAG_INTO;
-         h = clist->row_height / 4;
-       }
-      else if (GTK_CLIST_DRAW_DRAG_LINE(clist))
-       {
-         insert_pos = GTK_CLIST_DRAG_BEFORE;
-         h = clist->row_height / 2;
-       }
-
-      if (GTK_CLIST_DRAW_DRAG_LINE(clist))
-       {
-         if (y_delta < h)
-           insert_pos = GTK_CLIST_DRAG_BEFORE;
-         else if (clist->row_height - y_delta < h)
-           insert_pos = GTK_CLIST_DRAG_AFTER;
-       }
-    }
-
   dest_info = g_dataset_get_data (context, "gtk-clist-drag-dest");
 
   if (!dest_info)
@@ -7633,15 +7533,17 @@ gtk_clist_drag_motion (GtkWidget      *widget,
                               drag_dest_info_destroy);
     }
 
+  drag_dest_cell (clist, x, y, &new_info);
+
   if (GTK_CLIST_REORDERABLE (clist))
     {
       GList *list;
-      GdkAtom atom = gdk_atom_intern ("gtk-clist-drag-reorder", FALSE);
+      GdkAtom atom = gdk_atom_intern_static_string ("gtk-clist-drag-reorder");
 
       list = context->targets;
       while (list)
        {
-         if (atom == GPOINTER_TO_INT (list->data))
+         if (atom == GDK_POINTER_TO_ATOM (list->data))
            break;
          list = list->next;
        }
@@ -7649,12 +7551,12 @@ gtk_clist_drag_motion (GtkWidget      *widget,
       if (list)
        {
          if (gtk_drag_get_source_widget (context) != widget ||
-             insert_pos == GTK_CLIST_DRAG_NONE ||
-             row == clist->click_cell.row ||
-             (row == clist->click_cell.row - 1 &&
-              insert_pos == GTK_CLIST_DRAG_AFTER) ||
-             (row == clist->click_cell.row + 1 &&
-              insert_pos == GTK_CLIST_DRAG_BEFORE))
+             new_info.insert_pos == GTK_CLIST_DRAG_NONE ||
+             new_info.cell.row == clist->click_cell.row ||
+             (new_info.cell.row == clist->click_cell.row - 1 &&
+              new_info.insert_pos == GTK_CLIST_DRAG_AFTER) ||
+             (new_info.cell.row == clist->click_cell.row + 1 &&
+              new_info.insert_pos == GTK_CLIST_DRAG_BEFORE))
            {
              if (dest_info->cell.row < 0)
                {
@@ -7664,24 +7566,27 @@ gtk_clist_drag_motion (GtkWidget      *widget,
              return TRUE;
            }
                
-         if (row != dest_info->cell.row ||
-             (row == dest_info->cell.row &&
-              dest_info->insert_pos != insert_pos))
+         if (new_info.cell.row != dest_info->cell.row ||
+             (new_info.cell.row == dest_info->cell.row &&
+              dest_info->insert_pos != new_info.insert_pos))
            {
              if (dest_info->cell.row >= 0)
-               GTK_CLIST_CLASS_FW (clist)->draw_drag_highlight
+               GTK_CLIST_GET_CLASS (clist)->draw_drag_highlight
                  (clist, g_list_nth (clist->row_list,
                                      dest_info->cell.row)->data,
                   dest_info->cell.row, dest_info->insert_pos);
 
-             dest_info->insert_pos  = insert_pos;
-             dest_info->cell.row    = row;
-             dest_info->cell.column = column;
+             dest_info->insert_pos  = new_info.insert_pos;
+             dest_info->cell.row    = new_info.cell.row;
+             dest_info->cell.column = new_info.cell.column;
              
-             GTK_CLIST_CLASS_FW (clist)->draw_drag_highlight
+             GTK_CLIST_GET_CLASS (clist)->draw_drag_highlight
                (clist, g_list_nth (clist->row_list,
                                    dest_info->cell.row)->data,
                 dest_info->cell.row, dest_info->insert_pos);
+             
+             clist->drag_highlight_row = dest_info->cell.row;
+             clist->drag_highlight_pos = dest_info->insert_pos;
 
              gdk_drag_status (context, context->suggested_action, time);
            }
@@ -7689,9 +7594,9 @@ gtk_clist_drag_motion (GtkWidget      *widget,
        }
     }
 
-  dest_info->insert_pos  = insert_pos;
-  dest_info->cell.row    = row;
-  dest_info->cell.column = column;
+  dest_info->insert_pos  = new_info.insert_pos;
+  dest_info->cell.row    = new_info.cell.row;
+  dest_info->cell.column = new_info.cell.column;
   return TRUE;
 }
 
@@ -7702,7 +7607,6 @@ gtk_clist_drag_drop (GtkWidget      *widget,
                     gint            y,
                     guint           time)
 {
-  g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
   g_return_val_if_fail (context != NULL, FALSE);
 
@@ -7710,12 +7614,12 @@ gtk_clist_drag_drop (GtkWidget      *widget,
       gtk_drag_get_source_widget (context) == widget)
     {
       GList *list;
-      GdkAtom atom = gdk_atom_intern ("gtk-clist-drag-reorder", FALSE);
+      GdkAtom atom = gdk_atom_intern_static_string ("gtk-clist-drag-reorder");
 
       list = context->targets;
       while (list)
        {
-         if (atom == GPOINTER_TO_INT (list->data))
+         if (atom == GDK_POINTER_TO_ATOM (list->data))
            return TRUE;
          list = list->next;
        }
@@ -7734,7 +7638,6 @@ gtk_clist_drag_data_received (GtkWidget        *widget,
 {
   GtkCList *clist;
 
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
   g_return_if_fail (context != NULL);
   g_return_if_fail (selection_data != NULL);
@@ -7744,27 +7647,26 @@ gtk_clist_drag_data_received (GtkWidget        *widget,
   if (GTK_CLIST_REORDERABLE (clist) &&
       gtk_drag_get_source_widget (context) == widget &&
       selection_data->target ==
-      gdk_atom_intern ("gtk-clist-drag-reorder", FALSE) &&
-      selection_data->format == GTK_TYPE_POINTER &&
+      gdk_atom_intern_static_string ("gtk-clist-drag-reorder") &&
+      selection_data->format == 8 &&
       selection_data->length == sizeof (GtkCListCellInfo))
     {
       GtkCListCellInfo *source_info;
-      GtkCListDestInfo *dest_info;
 
       source_info = (GtkCListCellInfo *)(selection_data->data);
-      dest_info = g_dataset_get_data (context, "gtk-clist-drag-dest");
-
-      if (dest_info && source_info)
+      if (source_info)
        {
-         if (dest_info->insert_pos == GTK_CLIST_DRAG_AFTER)
-           dest_info->cell.row++;
-         if (source_info->row < dest_info->cell.row)
-           dest_info->cell.row--;
-
-         if (dest_info->cell.row != source_info->row)
-           gtk_clist_row_move (GTK_CLIST (widget),
-                               source_info->row,
-                               dest_info->cell.row);
+         GtkCListDestInfo dest_info;
+
+         drag_dest_cell (clist, x, y, &dest_info);
+
+         if (dest_info.insert_pos == GTK_CLIST_DRAG_AFTER)
+           dest_info.cell.row++;
+         if (source_info->row < dest_info.cell.row)
+           dest_info.cell.row--;
+         if (dest_info.cell.row != source_info->row)
+           gtk_clist_row_move (clist, source_info->row, dest_info.cell.row);
+
          g_dataset_remove_data (context, "gtk-clist-drag-dest");
        }
     }
@@ -7777,13 +7679,11 @@ gtk_clist_drag_data_get (GtkWidget        *widget,
                         guint             info,
                         guint             time)
 {
-  g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_CLIST (widget));
   g_return_if_fail (context != NULL);
   g_return_if_fail (selection_data != NULL);
 
-  if (selection_data->target ==
-      gdk_atom_intern ("gtk-clist-drag-reorder", FALSE))
+  if (selection_data->target == gdk_atom_intern_static_string ("gtk-clist-drag-reorder"))
     {
       GtkCListCellInfo *info;
 
@@ -7797,12 +7697,9 @@ gtk_clist_drag_data_get (GtkWidget        *widget,
          ret_info.column = info->column;
 
          gtk_selection_data_set (selection_data, selection_data->target,
-                                 GTK_TYPE_POINTER, (guchar *) &ret_info,
+                                 8, (guchar *) &ret_info,
                                  sizeof (GtkCListCellInfo));
        }
-      else
-       gtk_selection_data_set (selection_data, selection_data->target,
-                               GTK_TYPE_POINTER, NULL, 0);
     }
 }
 
@@ -7839,7 +7736,6 @@ gtk_clist_set_reorderable (GtkCList *clist,
 {
   GtkWidget *widget;
 
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if ((GTK_CLIST_REORDERABLE(clist) != 0) == reorderable)
@@ -7865,7 +7761,6 @@ void
 gtk_clist_set_use_drag_icons (GtkCList *clist,
                              gboolean  use_icons)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
   if (use_icons != 0)
@@ -7879,21 +7774,23 @@ gtk_clist_set_button_actions (GtkCList *clist,
                              guint     button,
                              guint8    button_actions)
 {
-  g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
-  if (button <= MAX_BUTTON)
+  if (button < MAX_BUTTON)
     {
-      if (gdk_pointer_is_grabbed () || GTK_WIDGET_HAS_GRAB (clist))
+      if (gdk_display_pointer_is_grabbed (gtk_widget_get_display (GTK_WIDGET (clist))) || 
+         GTK_WIDGET_HAS_GRAB (clist))
        {
          remove_grab (clist);
          clist->drag_button = 0;
        }
 
-      if (clist->anchor >= 0 &&
-         clist->selection_mode == GTK_SELECTION_EXTENDED)
-       GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+      GTK_CLIST_GET_CLASS (clist)->resync_selection (clist, NULL);
 
       clist->button_actions[button] = button_actions;
     }
 }
+
+#define __GTK_CLIST_C__
+#include "gtkaliasdef.c"
+