return dp.retval;
void do_config_box(void){    GtkWidget *window, *hbox, *vbox, *cols, *label,	*tree, *treescroll, *panels, *panelvbox;    int index, level, listitemheight;    struct controlbox *ctrlbox;    char *path;    GtkTreeItem *treeitemlevels[8];    GtkTree *treelevels[8];    Config cfg;    struct dlgparam dp;    struct sesslist sl;    struct Shortcuts scs;    struct selparam *selparams = NULL;    int nselparams = 0, selparamsize = 0;    do_defaults(NULL, &cfg);    dlg_init(&dp);    {        GtkWidget *listitem = gtk_list_item_new_with_label("foo");        GtkRequisition req;        gtk_widget_size_request(listitem, &req);        listitemheight = req.height;        gtk_widget_unref(listitem);    }    sl.nsessions = 0;    for (index = 0; index < lenof(scs.sc); index++) {	scs.sc[index].action = SHORTCUT_EMPTY;    }    ctrlbox = ctrl_new_box();    setup_config_box(ctrlbox, &sl, FALSE, 0);    unix_setup_config_box(ctrlbox, FALSE);    window = gtk_dialog_new();    hbox = gtk_hbox_new(FALSE, 4);    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), hbox, TRUE, TRUE, 0);    gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);    gtk_widget_show(hbox);    vbox = gtk_vbox_new(FALSE, 4);    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);    gtk_widget_show(vbox);    cols = columns_new(4);    gtk_box_pack_start(GTK_BOX(vbox), cols, FALSE, FALSE, 0);    gtk_widget_show(cols);    label = gtk_label_new("Category:");    columns_add(COLUMNS(cols), label, 0, 1);    columns_force_left_align(COLUMNS(cols), label);    gtk_widget_show(label);    treescroll = gtk_scrolled_window_new(NULL, NULL);    tree = gtk_tree_new();    /* FIXME: focusing treescroll doesn't help */    shortcut_add(&scs, label, 'g', SHORTCUT_FOCUS, tree);    gtk_tree_set_view_mode(GTK_TREE(tree), GTK_TREE_VIEW_ITEM);    gtk_tree_set_selection_mode(GTK_TREE(tree), GTK_SELECTION_BROWSE);    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(treescroll),					  tree);    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(treescroll),				   GTK_POLICY_NEVER,				   GTK_POLICY_AUTOMATIC);    gtk_widget_show(tree);    gtk_widget_show(treescroll);    gtk_box_pack_start(GTK_BOX(vbox), treescroll, TRUE, TRUE, 0);    panels = panels_new();    gtk_box_pack_start(GTK_BOX(hbox), panels, TRUE, TRUE, 0);    gtk_widget_show(panels);    panelvbox = NULL;    path = NULL;    level = 0;    for (index = 0; index < ctrlbox->nctrlsets; index++) {	struct controlset *s = ctrlbox->ctrlsets[index];	GtkWidget *w;	if (!*s->pathname) {	    w = layout_ctrls(&dp, &scs, s, listitemheight, GTK_WINDOW(window));	    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->action_area),			       w, TRUE, TRUE, 0);	} else {	    int j = path ? ctrl_path_compare(s->pathname, path) : 0;	    if (j != INT_MAX) {        /* add to treeview, start new panel */		char *c;		GtkWidget *treeitem;		int first;		/*		 * We expect never to find an implicit path		 * component. For example, we expect never to see		 * A/B/C followed by A/D/E, because that would		 * _implicitly_ create A/D. All our path prefixes		 * are expected to contain actual controls and be		 * selectable in the treeview; so we would expect		 * to see A/D _explicitly_ before encountering		 * A/D/E.		 */		assert(j == ctrl_path_elements(s->pathname) - 1);		c = strrchr(s->pathname, '/');		if (!c)		    c = s->pathname;		else		    c++;		treeitem = gtk_tree_item_new_with_label(c);		assert(j-1 < level);		if (j > 0) {		    if (!treelevels[j-1]) {			treelevels[j-1] = GTK_TREE(gtk_tree_new());			gtk_tree_item_set_subtree			    (treeitemlevels[j-1],			     GTK_WIDGET(treelevels[j-1]));			gtk_tree_item_expand(treeitemlevels[j-1]);		    }		    gtk_tree_append(treelevels[j-1], treeitem);		} else {		    gtk_tree_append(GTK_TREE(tree), treeitem);		}		treeitemlevels[j] = GTK_TREE_ITEM(treeitem);		treelevels[j] = NULL;		level = j+1;		gtk_widget_show(treeitem);		path = s->pathname;		first = (panelvbox == NULL);		panelvbox = gtk_vbox_new(FALSE, 4);		gtk_container_add(GTK_CONTAINER(panels), panelvbox);		if (first) {		    panels_switch_to(PANELS(panels), panelvbox);		    gtk_tree_select_child(GTK_TREE(tree), treeitem);		}		if (nselparams >= selparamsize) {		    selparamsize += 16;		    selparams = srealloc(selparams,					 selparamsize * sizeof(*selparams));		}		selparams[nselparams].dp = &dp;		selparams[nselparams].panels = PANELS(panels);		selparams[nselparams].panel = panelvbox;		selparams[nselparams].shortcuts = scs;   /* structure copy */		selparams[nselparams].treeitem = treeitem;		nselparams++;	    }	    w = layout_ctrls(&dp,			     &selparams[nselparams-1].shortcuts,			     s, listitemheight, NULL);	    gtk_box_pack_start(GTK_BOX(panelvbox), w, FALSE, FALSE, 0);            gtk_widget_show(w);	}    }    for (index = 0; index < nselparams; index++) {	gtk_signal_connect(GTK_OBJECT(selparams[index].treeitem), "select",			   GTK_SIGNAL_FUNC(treeitem_sel),			   &selparams[index]);    }    dp.data = &cfg;    dlg_refresh(NULL, &dp);    dp.shortcuts = &selparams[0].shortcuts;    gtk_widget_show(window);    gtk_signal_connect(GTK_OBJECT(window), "destroy",		       GTK_SIGNAL_FUNC(destroy), NULL);    gtk_signal_connect(GTK_OBJECT(window), "key_press_event",		       GTK_SIGNAL_FUNC(win_key_press), &dp);    gtk_main();    dlg_cleanup(&dp);    sfree(selparams);}