if (ctrl->editbox.has_list) { w = gtk_combo_new(); gtk_combo_set_value_in_list(GTK_COMBO(w), FALSE, TRUE); uc->entry = GTK_COMBO(w)->entry; uc->list = GTK_COMBO(w)->list; } else { w = gtk_entry_new(); if (ctrl->editbox.password) gtk_entry_set_visibility(GTK_ENTRY(w), FALSE); uc->entry = w; } gtk_signal_connect(GTK_OBJECT(uc->entry), "changed", GTK_SIGNAL_FUNC(editbox_changed), dp); gtk_signal_connect(GTK_OBJECT(uc->entry), "key_press_event", GTK_SIGNAL_FUNC(editbox_key), dp); gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_in_event", GTK_SIGNAL_FUNC(widget_focus), dp);  {
{
GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,			struct controlset *s, int listitemheight,			GtkWindow *win){    Columns *cols;    GtkWidget *ret;    int i;    if (!s->boxname && s->boxtitle) {        /* This controlset is a panel title. */        return gtk_label_new(s->boxtitle);    }    /*     * Otherwise, we expect to be laying out actual controls, so     * we'll start by creating a Columns for the purpose.     */    cols = COLUMNS(columns_new(4));    ret = GTK_WIDGET(cols);    gtk_widget_show(ret);    /*     * Create a containing frame if we have a box name.     */    if (*s->boxname) {        ret = gtk_frame_new(s->boxtitle);   /* NULL is valid here */        gtk_container_set_border_width(GTK_CONTAINER(cols), 4);        gtk_container_add(GTK_CONTAINER(ret), GTK_WIDGET(cols));        gtk_widget_show(ret);    }    /*     * Now iterate through the controls themselves, create them,     * and add them to the Columns.     */    for (i = 0; i < s->ncontrols; i++) {	union control *ctrl = s->ctrls[i];	struct uctrl *uc;	int left = FALSE;        GtkWidget *w = NULL;        switch (ctrl->generic.type) {          case CTRL_COLUMNS:            {                static const int simplecols[1] = { 100 };                columns_set_cols(cols, ctrl->columns.ncols,                                 (ctrl->columns.percentages ?                                  ctrl->columns.percentages : simplecols));            }            continue;                  /* no actual control created */          case CTRL_TABDELAY:	    {		struct uctrl *uc = dlg_find_byctrl(dp, ctrl->tabdelay.ctrl);		if (uc)		    columns_taborder_last(cols, uc->toplevel);	    }            continue;                  /* no actual control created */	}	uc = smalloc(sizeof(struct uctrl));	uc->ctrl = ctrl;	uc->privdata = NULL;	uc->privdata_needs_free = FALSE;	uc->buttons = NULL;	uc->entry = uc->list = uc->menu = NULL;	uc->button = uc->optmenu = uc->text = NULL;        switch (ctrl->generic.type) {          case CTRL_BUTTON:            w = gtk_button_new_with_label(ctrl->generic.label);	    if (win) {		GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);		if (ctrl->button.isdefault)		    gtk_window_set_default(win, w);		if (ctrl->button.iscancel)		    dp->cancelbutton = w;	    }	    gtk_signal_connect(GTK_OBJECT(w), "clicked",			       GTK_SIGNAL_FUNC(button_clicked), dp);            gtk_signal_connect(GTK_OBJECT(w), "focus_in_event",                               GTK_SIGNAL_FUNC(widget_focus), dp);	    shortcut_add(scs, GTK_BIN(w)->child, ctrl->button.shortcut,			 SHORTCUT_UCTRL, uc);            break;          case CTRL_CHECKBOX:            w = gtk_check_button_new_with_label(ctrl->generic.label);	    gtk_signal_connect(GTK_OBJECT(w), "toggled",			       GTK_SIGNAL_FUNC(button_toggled), dp);            gtk_signal_connect(GTK_OBJECT(w), "focus_in_event",                               GTK_SIGNAL_FUNC(widget_focus), dp);	    shortcut_add(scs, GTK_BIN(w)->child, ctrl->checkbox.shortcut,			 SHORTCUT_UCTRL, uc);	    left = TRUE;            break;          case CTRL_RADIO:            /*             * Radio buttons get to go inside their own Columns, no             * matter what.             */            {                gint i, *percentages;                GSList *group;                w = columns_new(1);                if (ctrl->generic.label) {                    GtkWidget *label = gtk_label_new(ctrl->generic.label);                    columns_add(COLUMNS(w), label, 0, 1);		    columns_force_left_align(COLUMNS(w), label);                    gtk_widget_show(label);		    shortcut_add(scs, label, ctrl->radio.shortcut,				 SHORTCUT_UCTRL, uc);                }                percentages = g_new(gint, ctrl->radio.ncolumns);                for (i = 0; i < ctrl->radio.ncolumns; i++) {                    percentages[i] =                        ((100 * (i+1) / ctrl->radio.ncolumns) -                         100 * i / ctrl->radio.ncolumns);                }                columns_set_cols(COLUMNS(w), ctrl->radio.ncolumns,                                 percentages);                g_free(percentages);                group = NULL;		uc->nbuttons = ctrl->radio.nbuttons;		uc->buttons = smalloc(uc->nbuttons * sizeof(GtkWidget *));                for (i = 0; i < ctrl->radio.nbuttons; i++) {                    GtkWidget *b;                    gint colstart;                    b = (gtk_radio_button_new_with_label                         (group, ctrl->radio.buttons[i]));		    uc->buttons[i] = b;                    group = gtk_radio_button_group(GTK_RADIO_BUTTON(b));                    colstart = i % ctrl->radio.ncolumns;                    columns_add(COLUMNS(w), b, colstart,                                (i == ctrl->radio.nbuttons-1 ?                                 ctrl->radio.ncolumns - colstart : 1));		    columns_force_left_align(COLUMNS(w), b);                    gtk_widget_show(b);		    gtk_signal_connect(GTK_OBJECT(b), "toggled",				       GTK_SIGNAL_FUNC(button_toggled), dp);                    gtk_signal_connect(GTK_OBJECT(b), "focus_in_event",                                       GTK_SIGNAL_FUNC(widget_focus), dp);		    if (ctrl->radio.shortcuts) {			shortcut_add(scs, GTK_BIN(b)->child,				     ctrl->radio.shortcuts[i],				     SHORTCUT_UCTRL, uc);		    }                }            }            break;          case CTRL_EDITBOX:            if (ctrl->editbox.has_list) {                w = gtk_combo_new();		gtk_combo_set_value_in_list(GTK_COMBO(w), FALSE, TRUE);		uc->entry = GTK_COMBO(w)->entry;                uc->list = GTK_COMBO(w)->list;            } else {                w = gtk_entry_new();                if (ctrl->editbox.password)                    gtk_entry_set_visibility(GTK_ENTRY(w), FALSE);		uc->entry = w;            }	    gtk_signal_connect(GTK_OBJECT(uc->entry), "changed",			       GTK_SIGNAL_FUNC(editbox_changed), dp);	    gtk_signal_connect(GTK_OBJECT(uc->entry), "key_press_event",			       GTK_SIGNAL_FUNC(editbox_key), dp);            gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_in_event",                               GTK_SIGNAL_FUNC(widget_focus), dp);            /*             * Edit boxes, for some strange reason, have a minimum             * width of 150 in GTK 1.2. We don't want this - we'd             * rather the edit boxes acquired their natural width             * from the column layout of the rest of the box.             */            {                GtkRequisition req;                gtk_widget_size_request(w, &req);                gtk_widget_set_usize(w, 10, req.height);            }            if (ctrl->generic.label) {                GtkWidget *label, *container;                label = gtk_label_new(ctrl->generic.label);		shortcut_add(scs, label, ctrl->editbox.shortcut,			     SHORTCUT_FOCUS, uc->entry);		container = columns_new(4);                if (ctrl->editbox.percentwidth == 100) {                    columns_add(COLUMNS(container), label, 0, 1);		    columns_force_left_align(COLUMNS(container), label);                    columns_add(COLUMNS(container), w, 0, 1);                } else {                    gint percentages[2];                    percentages[1] = ctrl->editbox.percentwidth;                    percentages[0] = 100 - ctrl->editbox.percentwidth;                    columns_set_cols(COLUMNS(container), 2, percentages);                    columns_add(COLUMNS(container), label, 0, 1);		    columns_force_left_align(COLUMNS(container), label);                    columns_add(COLUMNS(container), w, 1, 1);                }                gtk_widget_show(label);                gtk_widget_show(w);                w = container;            }	    gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_out_event",			       GTK_SIGNAL_FUNC(editbox_lostfocus), dp);            break;          case CTRL_FILESELECT:          case CTRL_FONTSELECT:            {                GtkWidget *ww;                GtkRequisition req;                char *browsebtn =                    (ctrl->generic.type == CTRL_FILESELECT ?                     "Browse..." : "Change...");                gint percentages[] = { 75, 25 };                w = columns_new(4);                columns_set_cols(COLUMNS(w), 2, percentages);                if (ctrl->generic.label) {                    ww = gtk_label_new(ctrl->generic.label);                    columns_add(COLUMNS(w), ww, 0, 2);		    columns_force_left_align(COLUMNS(w), ww);                    gtk_widget_show(ww);		    shortcut_add(scs, ww,				 (ctrl->generic.type == CTRL_FILESELECT ?				  ctrl->fileselect.shortcut :				  ctrl->fontselect.shortcut),				 SHORTCUT_UCTRL, uc);                }                uc->entry = ww = gtk_entry_new();                gtk_widget_size_request(ww, &req);                gtk_widget_set_usize(ww, 10, req.height);                columns_add(COLUMNS(w), ww, 0, 1);                gtk_widget_show(ww);                uc->button = ww = gtk_button_new_with_label(browsebtn);                columns_add(COLUMNS(w), ww, 1, 1);                gtk_widget_show(ww);		gtk_signal_connect(GTK_OBJECT(uc->entry), "key_press_event",				   GTK_SIGNAL_FUNC(editbox_key), dp);		gtk_signal_connect(GTK_OBJECT(uc->entry), "changed",				   GTK_SIGNAL_FUNC(editbox_changed), dp);                gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_in_event",                                   GTK_SIGNAL_FUNC(widget_focus), dp);                gtk_signal_connect(GTK_OBJECT(uc->button), "focus_in_event",                                   GTK_SIGNAL_FUNC(widget_focus), dp);		gtk_signal_connect(GTK_OBJECT(ww), "clicked",				   GTK_SIGNAL_FUNC(filefont_clicked), dp);            }            break;          case CTRL_LISTBOX:            if (ctrl->listbox.height == 0) {                uc->optmenu = w = gtk_option_menu_new();		uc->menu = gtk_menu_new();		gtk_option_menu_set_menu(GTK_OPTION_MENU(w), uc->menu);		gtk_object_set_data(GTK_OBJECT(uc->menu), "user-data",				    (gpointer)uc->optmenu);                gtk_signal_connect(GTK_OBJECT(uc->optmenu), "focus_in_event",                                   GTK_SIGNAL_FUNC(widget_focus), dp);            } else {                uc->list = gtk_list_new();                if (ctrl->listbox.multisel) {                    gtk_list_set_selection_mode(GTK_LIST(uc->list),                                                GTK_SELECTION_MULTIPLE);                } else {                    gtk_list_set_selection_mode(GTK_LIST(uc->list),                                                GTK_SELECTION_SINGLE);                }                w = gtk_scrolled_window_new(NULL, NULL);                gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(w),                                                      uc->list);                gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w),                                               GTK_POLICY_NEVER,                                               GTK_POLICY_AUTOMATIC);                uc->adj = gtk_scrolled_window_get_vadjustment                    (GTK_SCROLLED_WINDOW(w));                gtk_widget_show(uc->list);		gtk_signal_connect(GTK_OBJECT(uc->list), "selection-changed",				   GTK_SIGNAL_FUNC(list_selchange), dp);                gtk_signal_connect(GTK_OBJECT(uc->list), "focus_in_event",                                   GTK_SIGNAL_FUNC(widget_focus), dp);                /*                 * Adjust the height of the scrolled window to the                 * minimum given by the height parameter.                 *                  * This piece of guesswork is a horrid hack based                 * on looking inside the GTK 1.2 sources                 * (specifically gtkviewport.c, which appears to be                 * the widget which provides the border around the                 * scrolling area). Anyone lets me know how I can                 * do this in a way which isn't at risk from GTK                 * upgrades, I'd be grateful.                 */		{		    int edge = GTK_WIDGET(uc->list)->style->klass->ythickness;                    gtk_widget_set_usize(w, 10,                                         2*edge + (ctrl->listbox.height *						   listitemheight));		}                if (ctrl->listbox.draglist) {                    /*                     * GTK doesn't appear to make it easy to                     * implement a proper draggable list; so                     * instead I'm just going to have to put an Up                     * and a Down button to the right of the actual                     * list box. Ah well.                     */                    GtkWidget *cols, *button;                    static const gint percentages[2] = { 80, 20 };                    cols = columns_new(4);                    columns_set_cols(COLUMNS(cols), 2, percentages);                    columns_add(COLUMNS(cols), w, 0, 1);                    gtk_widget_show(w);                    button = gtk_button_new_with_label("Up");                    columns_add(COLUMNS(cols), button, 1, 1);                    gtk_widget_show(button);		    gtk_signal_connect(GTK_OBJECT(button), "clicked",				       GTK_SIGNAL_FUNC(draglist_up), dp);                    gtk_signal_connect(GTK_OBJECT(button), "focus_in_event",                                       GTK_SIGNAL_FUNC(widget_focus), dp);                    button = gtk_button_new_with_label("Down");                    columns_add(COLUMNS(cols), button, 1, 1);                    gtk_widget_show(button);		    gtk_signal_connect(GTK_OBJECT(button), "clicked",				       GTK_SIGNAL_FUNC(draglist_down), dp);                    gtk_signal_connect(GTK_OBJECT(button), "focus_in_event",                                       GTK_SIGNAL_FUNC(widget_focus), dp);                    w = cols;                }            }            if (ctrl->generic.label) {                GtkWidget *label, *container;                label = gtk_label_new(ctrl->generic.label);		container = columns_new(4);                if (ctrl->listbox.percentwidth == 100) {                    columns_add(COLUMNS(container), label, 0, 1);		    columns_force_left_align(COLUMNS(container), label);                    columns_add(COLUMNS(container), w, 0, 1);                } else {                    gint percentages[2];                    percentages[1] = ctrl->listbox.percentwidth;                    percentages[0] = 100 - ctrl->listbox.percentwidth;                    columns_set_cols(COLUMNS(container), 2, percentages);                    columns_add(COLUMNS(container), label, 0, 1);		    columns_force_left_align(COLUMNS(container), label);                    columns_add(COLUMNS(container), w, 1, 1);                }                gtk_widget_show(label);                gtk_widget_show(w);		shortcut_add(scs, label, ctrl->listbox.shortcut,			     SHORTCUT_UCTRL, uc);                w = container;            }            break;          case CTRL_TEXT:            uc->text = w = gtk_label_new(ctrl->generic.label);            gtk_misc_set_alignment(GTK_MISC(w), 0.0, 0.0);            gtk_label_set_line_wrap(GTK_LABEL(w), TRUE);            /* FIXME: deal with wrapping! */            break;        }	assert(w != NULL);	columns_add(cols, w,		    COLUMN_START(ctrl->generic.column),		    COLUMN_SPAN(ctrl->generic.column));	if (left)	    columns_force_left_align(cols, w);	gtk_widget_show(w);	uc->toplevel = w;	dlg_add_uctrl(dp, uc);    }    return ret;}