summaryrefslogtreecommitdiff
path: root/gtk/gtkcontainer.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkcontainer.c')
-rw-r--r--gtk/gtkcontainer.c844
1 files changed, 844 insertions, 0 deletions
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
new file mode 100644
index 000000000..977fabc29
--- /dev/null
+++ b/gtk/gtkcontainer.c
@@ -0,0 +1,844 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include "gtkcontainer.h"
+#include "gtksignal.h"
+
+
+enum {
+ ADD,
+ REMOVE,
+ NEED_RESIZE,
+ FOREACH,
+ FOCUS,
+ LAST_SIGNAL
+};
+
+
+typedef void (*GtkContainerSignal1) (GtkObject *object,
+ gpointer arg1,
+ gpointer data);
+typedef void (*GtkContainerSignal2) (GtkObject *object,
+ gpointer arg1,
+ gpointer arg2,
+ gpointer data);
+typedef gint (*GtkContainerSignal3) (GtkObject *object,
+ gint arg1,
+ gpointer data);
+typedef gint (*GtkContainerSignal4) (GtkObject *object,
+ gpointer data);
+
+
+static void gtk_container_marshal_signal_1 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args);
+static void gtk_container_marshal_signal_2 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args);
+static void gtk_container_marshal_signal_3 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args);
+static void gtk_container_marshal_signal_4 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args);
+
+
+static void gtk_container_class_init (GtkContainerClass *klass);
+static void gtk_container_init (GtkContainer *container);
+static void gtk_container_arg (GtkContainer *container,
+ GtkArg *arg);
+static gint gtk_real_container_need_resize (GtkContainer *container);
+static gint gtk_real_container_focus (GtkContainer *container,
+ GtkDirectionType direction);
+static gint gtk_container_focus_tab (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction);
+static gint gtk_container_focus_up_down (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction);
+static gint gtk_container_focus_left_right (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction);
+static gint gtk_container_focus_move (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction);
+static void gtk_container_children_callback (GtkWidget *widget,
+ gpointer client_data);
+
+
+static gint container_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_container_get_type ()
+{
+ static guint container_type = 0;
+
+ if (!container_type)
+ {
+ GtkTypeInfo container_info =
+ {
+ "GtkContainer",
+ sizeof (GtkContainer),
+ sizeof (GtkContainerClass),
+ (GtkClassInitFunc) gtk_container_class_init,
+ (GtkObjectInitFunc) gtk_container_init,
+ (GtkArgFunc) gtk_container_arg,
+ };
+
+ container_type = gtk_type_unique (gtk_widget_get_type (), &container_info);
+ }
+
+ return container_type;
+}
+
+static void
+gtk_container_class_init (GtkContainerClass *class)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = (GtkObjectClass*) class;
+ widget_class = (GtkWidgetClass*) class;
+
+ gtk_object_add_arg_type ("GtkContainer::border_width", GTK_TYPE_LONG);
+ gtk_object_add_arg_type ("GtkContainer::auto_resize", GTK_TYPE_BOOL);
+ gtk_object_add_arg_type ("GtkContainer::block_resize", GTK_TYPE_BOOL);
+ gtk_object_add_arg_type ("GtkContainer::child", GTK_TYPE_WIDGET);
+
+ container_signals[ADD] =
+ gtk_signal_new ("add",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkContainerClass, add),
+ gtk_container_marshal_signal_1,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_WIDGET);
+ container_signals[REMOVE] =
+ gtk_signal_new ("remove",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkContainerClass, remove),
+ gtk_container_marshal_signal_1,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_WIDGET);
+ container_signals[NEED_RESIZE] =
+ gtk_signal_new ("need_resize",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkContainerClass, need_resize),
+ gtk_container_marshal_signal_4,
+ GTK_TYPE_BOOL, 0,
+ GTK_TYPE_WIDGET);
+ container_signals[FOREACH] =
+ gtk_signal_new ("foreach",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkContainerClass, foreach),
+ gtk_container_marshal_signal_2,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_C_CALLBACK);
+ container_signals[FOCUS] =
+ gtk_signal_new ("focus",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkContainerClass, focus),
+ gtk_container_marshal_signal_3,
+ GTK_TYPE_DIRECTION_TYPE, 1,
+ GTK_TYPE_DIRECTION_TYPE);
+
+ gtk_object_class_add_signals (object_class, container_signals, LAST_SIGNAL);
+
+ class->need_resize = gtk_real_container_need_resize;
+ class->focus = gtk_real_container_focus;
+}
+
+static void
+gtk_container_init (GtkContainer *container)
+{
+ container->focus_child = NULL;
+ container->border_width = 0;
+ container->auto_resize = TRUE;
+ container->need_resize = FALSE;
+ container->block_resize = FALSE;
+}
+
+static void
+gtk_container_arg (GtkContainer *container,
+ GtkArg *arg)
+{
+ if (strcmp (arg->name, "border_width") == 0)
+ {
+ gtk_container_border_width (container, GTK_VALUE_LONG (*arg));
+ }
+ else if (strcmp (arg->name, "auto_resize") == 0)
+ {
+ if (GTK_VALUE_BOOL (*arg))
+ gtk_container_enable_resize (container);
+ else
+ gtk_container_disable_resize (container);
+ }
+ else if (strcmp (arg->name, "block_resize") == 0)
+ {
+ if (GTK_VALUE_BOOL (*arg))
+ gtk_container_block_resize (container);
+ else
+ gtk_container_unblock_resize (container);
+ }
+ else if (strcmp (arg->name, "child") == 0)
+ {
+ gtk_container_add (container, GTK_WIDGET (GTK_VALUE_OBJECT (*arg)));
+ }
+}
+
+void
+gtk_container_border_width (GtkContainer *container,
+ gint border_width)
+{
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_CONTAINER (container));
+
+ if (container->border_width != border_width)
+ {
+ container->border_width = border_width;
+
+ if (container->widget.parent && GTK_WIDGET_VISIBLE (container))
+ gtk_container_need_resize (GTK_CONTAINER (container->widget.parent));
+ }
+}
+
+void
+gtk_container_add (GtkContainer *container,
+ GtkWidget *widget)
+{
+ gtk_signal_emit (GTK_OBJECT (container), container_signals[ADD], widget);
+}
+
+void
+gtk_container_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_CONTAINER (container));
+
+ if (container->focus_child == widget)
+ container->focus_child = NULL;
+
+ gtk_signal_emit (GTK_OBJECT (container), container_signals[REMOVE], widget);
+}
+
+void
+gtk_container_disable_resize (GtkContainer *container)
+{
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_CONTAINER (container));
+
+ container->auto_resize = FALSE;
+}
+
+void
+gtk_container_enable_resize (GtkContainer *container)
+{
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_CONTAINER (container));
+
+ container->auto_resize = TRUE;
+ if (container->need_resize)
+ {
+ container->need_resize = FALSE;
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+}
+
+void
+gtk_container_block_resize (GtkContainer *container)
+{
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_CONTAINER (container));
+
+ container->block_resize = TRUE;
+}
+
+void
+gtk_container_unblock_resize (GtkContainer *container)
+{
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_CONTAINER (container));
+
+ container->block_resize = FALSE;
+}
+
+gint
+gtk_container_need_resize (GtkContainer *container)
+{
+ gint return_val;
+
+ g_return_val_if_fail (container != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
+
+ return_val = FALSE;
+
+ if (!container->block_resize)
+ {
+ if (container->auto_resize)
+ gtk_signal_emit (GTK_OBJECT (container),
+ container_signals[NEED_RESIZE],
+ &return_val);
+ else
+ container->need_resize = TRUE;
+ }
+
+ return return_val;
+}
+
+void
+gtk_container_foreach (GtkContainer *container,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ gtk_signal_emit (GTK_OBJECT (container),
+ container_signals[FOREACH],
+ callback, callback_data);
+}
+
+gint
+gtk_container_focus (GtkContainer *container,
+ GtkDirectionType direction)
+{
+ gint return_val;
+
+ gtk_signal_emit (GTK_OBJECT (container),
+ container_signals[FOCUS],
+ direction, &return_val);
+
+ return return_val;
+}
+
+GList*
+gtk_container_children (GtkContainer *container)
+{
+ GList *children;
+
+ children = NULL;
+
+ gtk_container_foreach (container,
+ gtk_container_children_callback,
+ &children);
+
+ return g_list_reverse (children);
+}
+
+
+static void
+gtk_container_marshal_signal_1 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args)
+{
+ GtkContainerSignal1 rfunc;
+
+ rfunc = (GtkContainerSignal1) func;
+
+ (* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
+}
+
+static void
+gtk_container_marshal_signal_2 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args)
+{
+ GtkContainerSignal2 rfunc;
+
+ rfunc = (GtkContainerSignal2) func;
+
+ (* rfunc) (object,
+ GTK_VALUE_C_CALLBACK(args[0]).func,
+ GTK_VALUE_C_CALLBACK(args[0]).func_data,
+ func_data);
+}
+
+static void
+gtk_container_marshal_signal_3 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args)
+{
+ GtkContainerSignal3 rfunc;
+ gint *return_val;
+
+ rfunc = (GtkContainerSignal3) func;
+ return_val = GTK_RETLOC_ENUM (args[1]);
+
+ *return_val = (* rfunc) (object, GTK_VALUE_ENUM(args[0]), func_data);
+}
+
+static void
+gtk_container_marshal_signal_4 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args)
+{
+ GtkContainerSignal4 rfunc;
+ gint *return_val;
+
+ rfunc = (GtkContainerSignal4) func;
+ return_val = GTK_RETLOC_BOOL (args[0]);
+
+ *return_val = (* rfunc) (object, func_data);
+}
+
+static gint
+gtk_real_container_need_resize (GtkContainer *container)
+{
+ g_return_val_if_fail (container != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
+
+ if (GTK_WIDGET_VISIBLE (container) && container->widget.parent)
+ return gtk_container_need_resize (GTK_CONTAINER (container->widget.parent));
+
+ return FALSE;
+}
+
+static gint
+gtk_real_container_focus (GtkContainer *container,
+ GtkDirectionType direction)
+{
+ GList *children;
+ GList *tmp_list;
+ GList *tmp_list2;
+ gint return_val;
+
+ g_return_val_if_fail (container != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
+
+ /* Fail if the container is insensitive
+ */
+ if (!GTK_WIDGET_SENSITIVE (container))
+ return FALSE;
+
+ return_val = FALSE;
+
+ if (GTK_WIDGET_CAN_FOCUS (container))
+ {
+ gtk_widget_grab_focus (GTK_WIDGET (container));
+ return_val = TRUE;
+ }
+ else
+ {
+ /* Get a list of the containers children
+ */
+ children = gtk_container_children (container);
+
+ if (children)
+ {
+ /* Remove any children which are insensitive
+ */
+ tmp_list = children;
+ while (tmp_list)
+ {
+ if (!GTK_WIDGET_SENSITIVE (tmp_list->data))
+ {
+ tmp_list2 = tmp_list;
+ tmp_list = tmp_list->next;
+
+ children = g_list_remove_link (children, tmp_list2);
+ g_list_free_1 (tmp_list2);
+ }
+ else
+ tmp_list = tmp_list->next;
+ }
+
+ switch (direction)
+ {
+ case GTK_DIR_TAB_FORWARD:
+ case GTK_DIR_TAB_BACKWARD:
+ return_val = gtk_container_focus_tab (container, children, direction);
+ break;
+ case GTK_DIR_UP:
+ case GTK_DIR_DOWN:
+ return_val = gtk_container_focus_up_down (container, children, direction);
+ break;
+ case GTK_DIR_LEFT:
+ case GTK_DIR_RIGHT:
+ return_val = gtk_container_focus_left_right (container, children, direction);
+ break;
+ }
+
+ g_list_free (children);
+ }
+ }
+
+ return return_val;
+}
+
+static gint
+gtk_container_focus_tab (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction)
+{
+ GtkWidget *child;
+ GtkWidget *child2;
+ GList *tmp_list;
+ gint length;
+ gint i, j;
+
+ length = g_list_length (children);
+
+ /* sort the children in the y direction */
+ for (i = 1; i < length; i++)
+ {
+ j = i;
+ tmp_list = g_list_nth (children, j);
+ child = tmp_list->data;
+
+ while (j > 0)
+ {
+ child2 = tmp_list->prev->data;
+ if (child->allocation.y < child2->allocation.y)
+ {
+ tmp_list->data = tmp_list->prev->data;
+ tmp_list = tmp_list->prev;
+ j--;
+ }
+ else
+ break;
+ }
+
+ tmp_list->data = child;
+ }
+
+ /* sort the children in the x direction while
+ * maintaining the y direction sort.
+ */
+ for (i = 1; i < length; i++)
+ {
+ j = i;
+ tmp_list = g_list_nth (children, j);
+ child = tmp_list->data;
+
+ while (j > 0)
+ {
+ child2 = tmp_list->prev->data;
+ if ((child->allocation.x < child2->allocation.x) &&
+ (child->allocation.y >= child2->allocation.y))
+ {
+ tmp_list->data = tmp_list->prev->data;
+ tmp_list = tmp_list->prev;
+ j--;
+ }
+ else
+ break;
+ }
+
+ tmp_list->data = child;
+ }
+
+ /* if we are going backwards then reverse the order
+ * of the children.
+ */
+ if (direction == GTK_DIR_TAB_BACKWARD)
+ children = g_list_reverse (children);
+
+ return gtk_container_focus_move (container, children, direction);
+}
+
+static gint
+gtk_container_focus_up_down (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction)
+{
+ GtkWidget *child;
+ GtkWidget *child2;
+ GList *tmp_list;
+ gint dist1, dist2;
+ gint focus_x;
+ gint focus_width;
+ gint length;
+ gint i, j;
+
+ /* return failure if there isn't a focus child */
+ if (container->focus_child)
+ {
+ focus_width = container->focus_child->allocation.width / 2;
+ focus_x = container->focus_child->allocation.x + focus_width;
+ }
+ else
+ {
+ focus_width = GTK_WIDGET (container)->allocation.width;
+ if (GTK_WIDGET_NO_WINDOW (container))
+ focus_x = GTK_WIDGET (container)->allocation.x;
+ else
+ focus_x = 0;
+ }
+
+ length = g_list_length (children);
+
+ /* sort the children in the y direction */
+ for (i = 1; i < length; i++)
+ {
+ j = i;
+ tmp_list = g_list_nth (children, j);
+ child = tmp_list->data;
+
+ while (j > 0)
+ {
+ child2 = tmp_list->prev->data;
+ if (child->allocation.y < child2->allocation.y)
+ {
+ tmp_list->data = tmp_list->prev->data;
+ tmp_list = tmp_list->prev;
+ j--;
+ }
+ else
+ break;
+ }
+
+ tmp_list->data = child;
+ }
+
+ /* sort the children in distance in the x direction
+ * in distance from the current focus child while maintaining the
+ * sort in the y direction
+ */
+ for (i = 1; i < length; i++)
+ {
+ j = i;
+ tmp_list = g_list_nth (children, j);
+ child = tmp_list->data;
+ dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
+
+ while (j > 0)
+ {
+ child2 = tmp_list->prev->data;
+ dist2 = (child2->allocation.x + child2->allocation.width / 2) - focus_x;
+
+ if ((dist1 < dist2) &&
+ (child->allocation.y >= child2->allocation.y))
+ {
+ tmp_list->data = tmp_list->prev->data;
+ tmp_list = tmp_list->prev;
+ j--;
+ }
+ else
+ break;
+ }
+
+ tmp_list->data = child;
+ }
+
+ /* go and invalidate any widget which is too
+ * far from the focus widget.
+ */
+ if (!container->focus_child &&
+ (direction == GTK_DIR_UP))
+ focus_x += focus_width;
+
+ tmp_list = children;
+ while (tmp_list)
+ {
+ child = tmp_list->data;
+
+ dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
+ if (((direction == GTK_DIR_DOWN) && (dist1 < 0)) ||
+ ((direction == GTK_DIR_UP) && (dist1 > 0)))
+ tmp_list->data = NULL;
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (direction == GTK_DIR_UP)
+ children = g_list_reverse (children);
+
+ return gtk_container_focus_move (container, children, direction);
+}
+
+static gint
+gtk_container_focus_left_right (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction)
+{
+ GtkWidget *child;
+ GtkWidget *child2;
+ GList *tmp_list;
+ gint dist1, dist2;
+ gint focus_y;
+ gint focus_height;
+ gint length;
+ gint i, j;
+
+ /* return failure if there isn't a focus child */
+ if (container->focus_child)
+ {
+ focus_height = container->focus_child->allocation.height / 2;
+ focus_y = container->focus_child->allocation.y + focus_height;
+ }
+ else
+ {
+ focus_height = GTK_WIDGET (container)->allocation.height;
+ if (GTK_WIDGET_NO_WINDOW (container))
+ focus_y = GTK_WIDGET (container)->allocation.y;
+ else
+ focus_y = 0;
+ }
+
+ length = g_list_length (children);
+
+ /* sort the children in the x direction */
+ for (i = 1; i < length; i++)
+ {
+ j = i;
+ tmp_list = g_list_nth (children, j);
+ child = tmp_list->data;
+
+ while (j > 0)
+ {
+ child2 = tmp_list->prev->data;
+ if (child->allocation.x < child2->allocation.x)
+ {
+ tmp_list->data = tmp_list->prev->data;
+ tmp_list = tmp_list->prev;
+ j--;
+ }
+ else
+ break;
+ }
+
+ tmp_list->data = child;
+ }
+
+ /* sort the children in distance in the y direction
+ * in distance from the current focus child while maintaining the
+ * sort in the x direction
+ */
+ for (i = 1; i < length; i++)
+ {
+ j = i;
+ tmp_list = g_list_nth (children, j);
+ child = tmp_list->data;
+ dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
+
+ while (j > 0)
+ {
+ child2 = tmp_list->prev->data;
+ dist2 = (child2->allocation.y + child2->allocation.height / 2) - focus_y;
+
+ if ((dist1 < dist2) &&
+ (child->allocation.x >= child2->allocation.x))
+ {
+ tmp_list->data = tmp_list->prev->data;
+ tmp_list = tmp_list->prev;
+ j--;
+ }
+ else
+ break;
+ }
+
+ tmp_list->data = child;
+ }
+
+ /* go and invalidate any widget which is too
+ * far from the focus widget.
+ */
+ if (!container->focus_child &&
+ (direction == GTK_DIR_LEFT))
+ focus_y += focus_height;
+
+ tmp_list = children;
+ while (tmp_list)
+ {
+ child = tmp_list->data;
+
+ dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
+ if (((direction == GTK_DIR_RIGHT) && (dist1 < 0)) ||
+ ((direction == GTK_DIR_LEFT) && (dist1 > 0)))
+ tmp_list->data = NULL;
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (direction == GTK_DIR_LEFT)
+ children = g_list_reverse (children);
+
+ return gtk_container_focus_move (container, children, direction);
+}
+
+static gint
+gtk_container_focus_move (GtkContainer *container,
+ GList *children,
+ GtkDirectionType direction)
+{
+ GtkWidget *focus_child;
+ GtkWidget *child;
+
+ focus_child = container->focus_child;
+ container->focus_child = NULL;
+
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ if (!child)
+ continue;
+
+ if (focus_child)
+ {
+ if (focus_child == child)
+ {
+ focus_child = NULL;
+
+ if (GTK_WIDGET_VISIBLE (child) &&
+ GTK_IS_CONTAINER (child) &&
+ !GTK_WIDGET_HAS_FOCUS (child))
+ if (gtk_container_focus (GTK_CONTAINER (child), direction))
+ return TRUE;
+ }
+ }
+ else if (GTK_WIDGET_VISIBLE (child))
+ {
+ if (GTK_WIDGET_CAN_FOCUS (child))
+ {
+ gtk_widget_grab_focus (child);
+ return TRUE;
+ }
+ else if (GTK_IS_CONTAINER (child))
+ {
+ if (gtk_container_focus (GTK_CONTAINER (child), direction))
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+static void
+gtk_container_children_callback (GtkWidget *widget,
+ gpointer client_data)
+{
+ GList **children;
+
+ children = (GList**) client_data;
+ *children = g_list_prepend (*children, widget);
+}