+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (clist->selection_mode != GTK_SELECTION_EXTENDED || clist->anchor >= 0)
+ return;
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ if (add_mode)
+ fake_toggle_row (clist, anchor);
+ else
+ {
+ GTK_CLIST_CLASS_FW (clist)->fake_unselect_all (clist, anchor);
+ clist->anchor_state = GTK_STATE_SELECTED;
+ }
+
+ clist->anchor = anchor;
+ clist->drag_pos = anchor;
+ clist->undo_anchor = undo_anchor;
+}
+
+static void
+resync_selection (GtkCList *clist,
+ GdkEvent *event)
+{
+ gint i;
+ gint e;
+ gint row;
+ GList *list;
+ GtkCListRow *clist_row;
+
+ if (clist->selection_mode != GTK_SELECTION_EXTENDED)
+ return;
+
+ if (clist->anchor < 0 || clist->drag_pos < 0)
+ return;
+
+ gtk_clist_freeze (clist);
+
+ i = MIN (clist->anchor, clist->drag_pos);
+ e = MAX (clist->anchor, clist->drag_pos);
+
+ if (clist->undo_selection)
+ {
+ list = clist->selection;
+ clist->selection = clist->undo_selection;
+ clist->selection_end = g_list_last (clist->selection);
+ clist->undo_selection = list;
+ list = clist->selection;
+ while (list)
+ {
+ row = GPOINTER_TO_INT (list->data);
+ list = list->next;
+ if (row < i || row > e)
+ {
+ clist_row = g_list_nth (clist->row_list, row)->data;
+ if (clist_row->selectable)
+ {
+ clist_row->state = GTK_STATE_SELECTED;
+ gtk_signal_emit (GTK_OBJECT (clist),
+ clist_signals[UNSELECT_ROW],
+ row, -1, event);
+ clist->undo_selection = g_list_prepend
+ (clist->undo_selection, GINT_TO_POINTER (row));
+ }
+ }
+ }
+ }
+
+ if (clist->anchor < clist->drag_pos)
+ {
+ for (list = g_list_nth (clist->row_list, i); i <= e;
+ i++, list = list->next)
+ if (GTK_CLIST_ROW (list)->selectable)
+ {
+ if (g_list_find (clist->selection, GINT_TO_POINTER(i)))
+ {
+ if (GTK_CLIST_ROW (list)->state == GTK_STATE_NORMAL)
+ {
+ GTK_CLIST_ROW (list)->state = GTK_STATE_SELECTED;
+ gtk_signal_emit (GTK_OBJECT (clist),
+ clist_signals[UNSELECT_ROW],
+ i, -1, event);
+ clist->undo_selection =
+ g_list_prepend (clist->undo_selection,
+ GINT_TO_POINTER (i));
+ }
+ }
+ else if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED)
+ {
+ GTK_CLIST_ROW (list)->state = GTK_STATE_NORMAL;
+ clist->undo_unselection =
+ g_list_prepend (clist->undo_unselection,
+ GINT_TO_POINTER (i));
+ }
+ }
+ }
+ else
+ {
+ for (list = g_list_nth (clist->row_list, e); i <= e;
+ e--, list = list->prev)
+ if (GTK_CLIST_ROW (list)->selectable)
+ {
+ if (g_list_find (clist->selection, GINT_TO_POINTER(e)))
+ {
+ if (GTK_CLIST_ROW (list)->state == GTK_STATE_NORMAL)
+ {
+ GTK_CLIST_ROW (list)->state = GTK_STATE_SELECTED;
+ gtk_signal_emit (GTK_OBJECT (clist),
+ clist_signals[UNSELECT_ROW],
+ e, -1, event);
+ clist->undo_selection =
+ g_list_prepend (clist->undo_selection,
+ GINT_TO_POINTER (e));
+ }
+ }
+ else if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED)
+ {
+ GTK_CLIST_ROW (list)->state = GTK_STATE_NORMAL;
+ clist->undo_unselection =
+ g_list_prepend (clist->undo_unselection,
+ GINT_TO_POINTER (e));
+ }
+ }
+ }
+
+ 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);
+
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+
+ gtk_clist_thaw (clist);
+}
+
+static void
+update_extended_selection (GtkCList *clist,
+ gint row)
+{
+ gint i;
+ GList *list;
+ GdkRectangle area;
+ gint s1 = -1;
+ gint s2 = -1;
+ gint e1 = -1;
+ gint e2 = -1;
+ gint y1 = clist->clist_window_height;
+ gint y2 = clist->clist_window_height;
+ gint h1 = 0;
+ gint h2 = 0;
+ gint top;
+
+ if (clist->selection_mode != GTK_SELECTION_EXTENDED || clist->anchor == -1)
+ return;
+
+ if (row < 0)
+ row = 0;
+ if (row >= clist->rows)
+ row = clist->rows - 1;
+
+ /* extending downwards */
+ if (row > clist->drag_pos && clist->anchor <= clist->drag_pos)
+ {
+ s2 = clist->drag_pos + 1;
+ e2 = row;
+ }
+ /* extending upwards */
+ else if (row < clist->drag_pos && clist->anchor >= clist->drag_pos)
+ {
+ s2 = row;
+ e2 = clist->drag_pos - 1;
+ }
+ else if (row < clist->drag_pos && clist->anchor < clist->drag_pos)
+ {
+ e1 = clist->drag_pos;
+ /* row and drag_pos on different sides of anchor :
+ take back the selection between anchor and drag_pos,
+ select between anchor and row */
+ if (row < clist->anchor)
+ {
+ s1 = clist->anchor + 1;
+ s2 = row;
+ e2 = clist->anchor - 1;
+ }
+ /* take back the selection between anchor and drag_pos */
+ else
+ s1 = row + 1;
+ }
+ else if (row > clist->drag_pos && clist->anchor > clist->drag_pos)
+ {
+ s1 = clist->drag_pos;
+ /* row and drag_pos on different sides of anchor :
+ take back the selection between anchor and drag_pos,
+ select between anchor and row */
+ if (row > clist->anchor)
+ {
+ e1 = clist->anchor - 1;
+ s2 = clist->anchor + 1;
+ e2 = row;
+ }
+ /* take back the selection between anchor and drag_pos */
+ else
+ e1 = row - 1;
+ }
+
+ clist->drag_pos = row;
+
+ area.x = 0;
+ area.width = clist->clist_window_width;
+
+ /* restore the elements between s1 and e1 */
+ if (s1 >= 0)
+ {
+ for (i = s1, list = g_list_nth (clist->row_list, i); i <= e1;
+ i++, list = list->next)
+ if (GTK_CLIST_ROW (list)->selectable)
+ {
+ if (GTK_CLIST_CLASS_FW (clist)->selection_find (clist, i, list))
+ GTK_CLIST_ROW (list)->state = GTK_STATE_SELECTED;
+ else
+ GTK_CLIST_ROW (list)->state = GTK_STATE_NORMAL;
+ }
+
+ top = ROW_TOP_YPIXEL (clist, clist->focus_row);
+
+ if (top + clist->row_height <= 0)
+ {
+ area.y = 0;
+ area.height = ROW_TOP_YPIXEL (clist, e1) + clist->row_height;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ }
+ else if (top >= clist->clist_window_height)
+ {
+ area.y = ROW_TOP_YPIXEL (clist, s1) - 1;
+ area.height = clist->clist_window_height - area.y;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ }
+ else if (top < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ else if (top + clist->row_height > clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+
+ y1 = ROW_TOP_YPIXEL (clist, s1) - 1;
+ h1 = (e1 - s1 + 1) * (clist->row_height + CELL_SPACING);
+ }
+
+ /* extend the selection between s2 and e2 */
+ if (s2 >= 0)
+ {
+ for (i = s2, list = g_list_nth (clist->row_list, i); i <= e2;
+ i++, list = list->next)
+ if (GTK_CLIST_ROW (list)->selectable &&
+ GTK_CLIST_ROW (list)->state != clist->anchor_state)
+ GTK_CLIST_ROW (list)->state = clist->anchor_state;
+
+ top = ROW_TOP_YPIXEL (clist, clist->focus_row);
+
+ if (top + clist->row_height <= 0)
+ {
+ area.y = 0;
+ area.height = ROW_TOP_YPIXEL (clist, e2) + clist->row_height;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ }
+ else if (top >= clist->clist_window_height)
+ {
+ area.y = ROW_TOP_YPIXEL (clist, s2) - 1;
+ area.height = clist->clist_window_height - area.y;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ }
+ else if (top < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ else if (top + clist->row_height > clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+
+ y2 = ROW_TOP_YPIXEL (clist, s2) - 1;
+ h2 = (e2 - s2 + 1) * (clist->row_height + CELL_SPACING);
+ }
+
+ area.y = MAX (0, MIN (y1, y2));
+ if (area.y > clist->clist_window_height)
+ area.y = 0;
+ area.height = MIN (clist->clist_window_height, h1 + h2);
+ if (s1 >= 0 && s2 >= 0)
+ area.height += (clist->row_height + CELL_SPACING);
+ draw_rows (clist, &area);
+}
+
+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))
+ return;
+
+ set_anchor (clist, GTK_CLIST_ADD_MODE(clist), clist->focus_row,
+ clist->focus_row);
+}
+
+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))
+ return;
+
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+}
+
+static void
+extend_selection (GtkCList *clist,
+ GtkScrollType scroll_type,
+ 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)
+ return;
+
+ if (auto_start_selection)
+ set_anchor (clist, GTK_CLIST_ADD_MODE(clist), clist->focus_row,
+ clist->focus_row);
+ else if (clist->anchor == -1)
+ return;
+
+ move_focus_row (clist, scroll_type, position);
+
+ if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height >
+ clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+
+ update_extended_selection (clist, clist->focus_row);
+}
+
+static void
+sync_selection (GtkCList *clist,
+ gint row,
+ gint mode)
+{
+ GList *list;
+ gint d;
+
+ if (mode == SYNC_INSERT)
+ d = 1;
+ else
+ d = -1;
+
+ if (clist->focus_row >= row)
+ {
+ if (d > 0 || clist->focus_row > row)
+ clist->focus_row += d;
+ if (clist->focus_row == -1 && clist->rows >= 1)
+ clist->focus_row = 0;
+ else if (clist->focus_row >= clist->rows)
+ clist->focus_row = clist->rows - 1;
+ }
+
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+ clist->undo_anchor = clist->focus_row;
+
+ list = clist->selection;
+
+ while (list)
+ {
+ if (GPOINTER_TO_INT (list->data) >= row)
+ list->data = ((gchar*) list->data) + d;
+ list = list->next;
+ }
+}
+
+/* GTKOBJECT
+ * gtk_clist_destroy
+ * gtk_clist_finalize
+ */
+static void
+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);
+
+ /* freeze the list */
+ clist->freeze_count++;
+
+ /* get rid of all the rows */
+ gtk_clist_clear (clist);
+
+ /* Since we don't have a _remove method, unparent the children
+ * instead of destroying them so the focus will be unset properly.
+ * (For other containers, the _remove method takes care of the
+ * unparent) The destroy will happen when the refcount drops
+ * to zero.
+ */
+
+ /* unref adjustments */
+ if (clist->hadjustment)
+ {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (clist->hadjustment), clist);
+ gtk_object_unref (GTK_OBJECT (clist->hadjustment));
+ clist->hadjustment = NULL;
+ }
+ if (clist->vadjustment)
+ {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (clist->vadjustment), clist);
+ gtk_object_unref (GTK_OBJECT (clist->vadjustment));
+ clist->vadjustment = NULL;
+ }
+
+ remove_grab (clist);
+
+ /* destroy the column buttons */
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].button)
+ {
+ gtk_widget_unparent (clist->column[i].button);
+ clist->column[i].button = NULL;
+ }
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_clist_finalize (GtkObject *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);
+}
+
+/* GTKWIDGET
+ * gtk_clist_realize
+ * 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
+ * gtk_clist_size_request
+ * gtk_clist_size_allocate
+ */
+static void
+gtk_clist_realize (GtkWidget *widget)
+{
+ GtkCList *clist;
+ GdkWindowAttr attributes;
+ GdkGCValues values;
+ GtkCListRow *clist_row;
+ GList *list;
+ gint attributes_mask;
+ gint border_width;
+ gint i;
+ gint j;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_CLIST (widget));
+
+ clist = GTK_CLIST (widget);
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+ border_width = GTK_CONTAINER (widget)->border_width;
+
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = widget->allocation.x + border_width;
+ attributes.y = widget->allocation.y + border_width;
+ attributes.width = widget->allocation.width - border_width * 2;
+ attributes.height = widget->allocation.height - border_width * 2;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+ attributes.event_mask = gtk_widget_get_events (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;
+
+ /* main window */
+ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (widget->window, clist);
+
+ widget->style = gtk_style_attach (widget->style, widget->window);
+
+ gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+
+ /* column-title window */
+
+ attributes.x = clist->column_title_area.x;
+ attributes.y = clist->column_title_area.y;
+ attributes.width = clist->column_title_area.width;
+ attributes.height = clist->column_title_area.height;
+
+ clist->title_window = gdk_window_new (widget->window, &attributes,
+ attributes_mask);
+ gdk_window_set_user_data (clist->title_window, clist);
+
+ gtk_style_set_background (widget->style, clist->title_window,
+ GTK_STATE_NORMAL);
+ gdk_window_show (clist->title_window);
+
+ /* set things up so column buttons are drawn in title window */
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].button)
+ gtk_widget_set_parent_window (clist->column[i].button,
+ clist->title_window);
+
+ /* clist-window */
+ attributes.x = (clist->internal_allocation.x +
+ widget->style->klass->xthickness);
+ attributes.y = (clist->internal_allocation.y +
+ widget->style->klass->ythickness +
+ clist->column_title_area.height);
+ attributes.width = clist->clist_window_width;
+ attributes.height = clist->clist_window_height;
+
+ clist->clist_window = gdk_window_new (widget->window, &attributes,
+ attributes_mask);
+ gdk_window_set_user_data (clist->clist_window, clist);
+
+ gdk_window_set_background (clist->clist_window,
+ &widget->style->base[GTK_STATE_NORMAL]);
+ gdk_window_show (clist->clist_window);
+ gdk_window_get_size (clist->clist_window, &clist->clist_window_width,
+ &clist->clist_window_height);
+
+ /* create resize windows */
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.event_mask = (GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_KEY_PRESS_MASK);
+ attributes_mask = GDK_WA_CURSOR;
+ attributes.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
+ clist->cursor_drag = attributes.cursor;
+
+ attributes.x = LIST_WIDTH (clist) + 1;
+ attributes.y = 0;
+ attributes.width = 0;
+ attributes.height = 0;
+
+ for (i = 0; i < clist->columns; i++)
+ {
+ clist->column[i].window = gdk_window_new (clist->title_window,
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (clist->column[i].window, clist);
+ }
+
+ /* This is slightly less efficient than creating them with the
+ * right size to begin with, but easier
+ */
+ size_allocate_title_buttons (clist);
+
+ /* GCs */
+ clist->fg_gc = gdk_gc_new (widget->window);
+ clist->bg_gc = gdk_gc_new (widget->window);
+
+ /* We'll use this gc to do scrolling as well */
+ gdk_gc_set_exposures (clist->fg_gc, TRUE);
+
+ 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,
+ &values,
+ GDK_GC_FOREGROUND |
+ GDK_GC_FUNCTION |
+ GDK_GC_SUBWINDOW);
+
+ /* attach optional row/cell styles, allocate foreground/background colors */
+ list = clist->row_list;
+ for (i = 0; i < clist->rows; i++)
+ {
+ clist_row = list->data;
+ list = list->next;
+
+ if (clist_row->style)
+ clist_row->style = gtk_style_attach (clist_row->style,
+ clist->clist_window);
+
+ if (clist_row->fg_set || clist_row->bg_set)
+ {
+ GdkColormap *colormap;
+
+ colormap = gtk_widget_get_colormap (widget);
+ if (clist_row->fg_set)
+ gdk_color_alloc (colormap, &clist_row->foreground);
+ if (clist_row->bg_set)
+ gdk_color_alloc (colormap, &clist_row->background);
+ }
+
+ for (j = 0; j < clist->columns; j++)
+ if (clist_row->cell[j].style)
+ clist_row->cell[j].style =
+ gtk_style_attach (clist_row->cell[j].style, clist->clist_window);
+ }
+}
+
+static void
+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);
+
+ /* freeze the list */
+ clist->freeze_count++;
+
+ 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;
+ GList *list;
+ gint j;
+
+ list = clist->row_list;
+ for (i = 0; i < clist->rows; i++)
+ {
+ clist_row = list->data;
+ list = list->next;
+
+ if (clist_row->style)
+ gtk_style_detach (clist_row->style);
+ for (j = 0; j < clist->columns; j++)
+ if (clist_row->cell[j].style)
+ gtk_style_detach (clist_row->cell[j].style);
+ }
+ }
+
+ gdk_cursor_destroy (clist->cursor_drag);
+ gdk_gc_destroy (clist->xor_gc);
+ gdk_gc_destroy (clist->fg_gc);
+ gdk_gc_destroy (clist->bg_gc);
+
+ for (i = 0; i < clist->columns; i++)
+ {
+ 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);
+ clist->clist_window = NULL;
+
+ gdk_window_set_user_data (clist->title_window, NULL);
+ gdk_window_destroy (clist->title_window);
+ clist->title_window = NULL;
+
+ clist->cursor_drag = NULL;
+ clist->xor_gc = NULL;
+ clist->fg_gc = NULL;
+ clist->bg_gc = NULL;
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+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);
+
+ if (!GTK_WIDGET_MAPPED (widget))
+ {
+ GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+ /* 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);
+ }
+
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].window && clist->column[i].button)
+ {
+ gdk_window_raise (clist->column[i].window);
+ gdk_window_show (clist->column[i].window);
+ }
+
+ gdk_window_show (clist->title_window);
+ gdk_window_show (clist->clist_window);
+ gdk_window_show (widget->window);
+
+ /* unfreeze the list */
+ clist->freeze_count = 0;
+ }
+}
+
+static void
+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);
+
+ if (GTK_WIDGET_MAPPED (widget))
+ {
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+
+ if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))
+ {
+ remove_grab (clist);
+
+ GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, NULL);
+
+ clist->click_cell.row = -1;
+ clist->click_cell.column = -1;
+ clist->drag_button = 0;
+
+ if (GTK_CLIST_IN_DRAG(clist))
+ {
+ gpointer drag_data;
+
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
+ drag_data = gtk_object_get_data (GTK_OBJECT (clist),
+ "gtk-site-data");
+ if (drag_data)
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist),
+ drag_data);
+ }
+ }
+
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].window)
+ gdk_window_hide (clist->column[i].window);
+
+ gdk_window_hide (clist->clist_window);
+ gdk_window_hide (clist->title_window);
+ gdk_window_hide (widget->window);
+
+ /* unmap column buttons */
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].button &&
+ GTK_WIDGET_MAPPED (clist->column[i].button))
+ gtk_widget_unmap (clist->column[i].button);
+
+ /* freeze the list */
+ clist->freeze_count++;
+ }
+}
+
+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);