Patch from Colin Watson intended to give a clean Unix compile with GCC 4.
[u/mdw/putty] / unix / gtkdlg.c
index 2ef1831..b7947b5 100644 (file)
@@ -22,7 +22,6 @@
 #include <X11/Xutil.h>
 
 #include "gtkcols.h"
-#include "gtkpanel.h"
 
 #ifdef TESTMODE
 #define PUTTY_DO_GLOBALS              /* actually _define_ globals */
@@ -55,6 +54,7 @@ struct uctrl {
     GtkWidget *menu;         /* for optionmenu (==droplist) */
     GtkWidget *optmenu;              /* also for optionmenu */
     GtkWidget *text;         /* for text */
+    GtkWidget *label;         /* for dlg_label_change */
     GtkAdjustment *adj;       /* for the scrollbar in a list box */
     guint textsig;
 };
@@ -90,6 +90,7 @@ static gboolean widget_focus(GtkWidget *widget, GdkEventFocus *event,
                              gpointer data);
 static void shortcut_add(struct Shortcuts *scs, GtkWidget *labelw,
                         int chr, int action, void *ptr);
+static void shortcut_highlight(GtkWidget *label, int chr);
 static int listitem_single_key(GtkWidget *item, GdkEventKey *event,
                                gpointer data);
 static int listitem_multi_key(GtkWidget *item, GdkEventKey *event,
@@ -549,7 +550,35 @@ void dlg_listbox_select(union control *ctrl, void *dlg, int index)
     if (uc->optmenu) {
        gtk_option_menu_set_history(GTK_OPTION_MENU(uc->optmenu), index);
     } else {
+        int nitems;
+        GList *items;
+        gdouble newtop, newbot;
+
        gtk_list_select_item(GTK_LIST(uc->list), index);
+
+        /*
+         * Scroll the list box if necessary to ensure the newly
+         * selected item is visible.
+         */
+        items = gtk_container_children(GTK_CONTAINER(uc->list));
+        nitems = g_list_length(items);
+        if (nitems > 0) {
+            int modified = FALSE;
+            g_list_free(items);
+            newtop = uc->adj->lower +
+                (uc->adj->upper - uc->adj->lower) * index / nitems;
+            newbot = uc->adj->lower +
+                (uc->adj->upper - uc->adj->lower) * (index+1) / nitems;
+            if (uc->adj->value > newtop) {
+                modified = TRUE;
+                uc->adj->value = newtop;
+            } else if (uc->adj->value < newbot - uc->adj->page_size) {
+                modified = TRUE;
+                uc->adj->value = newbot - uc->adj->page_size;
+            }
+            if (modified)
+                gtk_adjustment_value_changed(uc->adj);
+        }
     }
 }
 
@@ -564,6 +593,46 @@ void dlg_text_set(union control *ctrl, void *dlg, char const *text)
     gtk_label_set_text(GTK_LABEL(uc->text), text);
 }
 
+void dlg_label_change(union control *ctrl, void *dlg, char const *text)
+{
+    struct dlgparam *dp = (struct dlgparam *)dlg;
+    struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
+
+    switch (uc->ctrl->generic.type) {
+      case CTRL_BUTTON:
+       gtk_label_set_text(GTK_LABEL(uc->toplevel), text);
+       shortcut_highlight(uc->toplevel, ctrl->button.shortcut);
+       break;
+      case CTRL_CHECKBOX:
+       gtk_label_set_text(GTK_LABEL(uc->toplevel), text);
+       shortcut_highlight(uc->toplevel, ctrl->checkbox.shortcut);
+       break;
+      case CTRL_RADIO:
+       gtk_label_set_text(GTK_LABEL(uc->label), text);
+       shortcut_highlight(uc->label, ctrl->radio.shortcut);
+       break;
+      case CTRL_EDITBOX:
+       gtk_label_set_text(GTK_LABEL(uc->label), text);
+       shortcut_highlight(uc->label, ctrl->editbox.shortcut);
+       break;
+      case CTRL_FILESELECT:
+       gtk_label_set_text(GTK_LABEL(uc->label), text);
+       shortcut_highlight(uc->label, ctrl->fileselect.shortcut);
+       break;
+      case CTRL_FONTSELECT:
+       gtk_label_set_text(GTK_LABEL(uc->label), text);
+       shortcut_highlight(uc->label, ctrl->fontselect.shortcut);
+       break;
+      case CTRL_LISTBOX:
+       gtk_label_set_text(GTK_LABEL(uc->label), text);
+       shortcut_highlight(uc->label, ctrl->listbox.shortcut);
+       break;
+      default:
+       assert(!"This shouldn't happen");
+       break;
+    }
+}
+
 void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn)
 {
     struct dlgparam *dp = (struct dlgparam *)dlg;
@@ -1297,6 +1366,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
        uc->buttons = NULL;
        uc->entry = uc->list = uc->menu = NULL;
        uc->button = uc->optmenu = uc->text = NULL;
+       uc->label = NULL;
 
         switch (ctrl->generic.type) {
           case CTRL_BUTTON:
@@ -1342,6 +1412,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
                     gtk_widget_show(label);
                    shortcut_add(scs, label, ctrl->radio.shortcut,
                                 SHORTCUT_UCTRL, uc);
+                   uc->label = label;
                 }
                 percentages = g_new(gint, ctrl->radio.ncolumns);
                 for (i = 0; i < ctrl->radio.ncolumns; i++) {
@@ -1446,6 +1517,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
                    gtk_widget_show(w);
 
                    w = container;
+                   uc->label = label;
                }
                gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_out_event",
                                   GTK_SIGNAL_FUNC(editbox_lostfocus), dp);
@@ -1474,6 +1546,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
                                  ctrl->fileselect.shortcut :
                                  ctrl->fontselect.shortcut),
                                 SHORTCUT_UCTRL, uc);
+                   uc->label = ww;
                 }
 
                 uc->entry = ww = gtk_entry_new();
@@ -1611,6 +1684,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
                shortcut_add(scs, label, ctrl->listbox.shortcut,
                             SHORTCUT_UCTRL, uc);
                 w = container;
+               uc->label = label;
             }
             break;
           case CTRL_TEXT:
@@ -1666,7 +1740,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
 
 struct selparam {
     struct dlgparam *dp;
-    Panels *panels;
+    GtkNotebook *panels;
     GtkWidget *panel, *treeitem;
     struct Shortcuts shortcuts;
 };
@@ -1674,8 +1748,12 @@ struct selparam {
 static void treeitem_sel(GtkItem *item, gpointer data)
 {
     struct selparam *sp = (struct selparam *)data;
+    gint page_num;
+
+    page_num = gtk_notebook_page_num(sp->panels, sp->panel);
+    gtk_notebook_set_page(sp->panels, page_num);
 
-    panels_switch_to(sp->panels, sp->panel);
+    dlg_refresh(NULL, sp->dp);
 
     sp->dp->shortcuts = &sp->shortcuts;
     sp->dp->currtreeitem = sp->treeitem;
@@ -1896,13 +1974,31 @@ int tree_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
     return FALSE;
 }
 
-void shortcut_add(struct Shortcuts *scs, GtkWidget *labelw,
-                 int chr, int action, void *ptr)
+static void shortcut_highlight(GtkWidget *labelw, int chr)
 {
     GtkLabel *label = GTK_LABEL(labelw);
     gchar *currstr, *pattern;
     int i;
 
+    gtk_label_get(label, &currstr);
+    for (i = 0; currstr[i]; i++)
+       if (tolower((unsigned char)currstr[i]) == chr) {
+           GtkRequisition req;
+
+           pattern = dupprintf("%*s_", i, "");
+
+           gtk_widget_size_request(GTK_WIDGET(label), &req);
+           gtk_label_set_pattern(label, pattern);
+           gtk_widget_set_usize(GTK_WIDGET(label), -1, req.height);
+
+           sfree(pattern);
+           break;
+       }
+}
+
+void shortcut_add(struct Shortcuts *scs, GtkWidget *labelw,
+                 int chr, int action, void *ptr)
+{
     if (chr == NO_SHORTCUT)
        return;
 
@@ -1920,20 +2016,7 @@ void shortcut_add(struct Shortcuts *scs, GtkWidget *labelw,
        scs->sc[chr].uc = (struct uctrl *)ptr;
     }
 
-    gtk_label_get(label, &currstr);
-    for (i = 0; currstr[i]; i++)
-       if (tolower((unsigned char)currstr[i]) == chr) {
-           GtkRequisition req;
-
-           pattern = dupprintf("%*s_", i, "");
-
-           gtk_widget_size_request(GTK_WIDGET(label), &req);
-           gtk_label_set_pattern(label, pattern);
-           gtk_widget_set_usize(GTK_WIDGET(label), -1, req.height);
-
-           sfree(pattern);
-           break;
-       }
+    shortcut_highlight(labelw, chr);
 }
 
 int get_listitemheight(void)
@@ -1956,7 +2039,6 @@ int do_config_box(const char *title, Config *cfg, int midsession,
     GtkTreeItem *treeitemlevels[8];
     GtkTree *treelevels[8];
     struct dlgparam dp;
-    struct sesslist sl;
     struct Shortcuts scs;
 
     struct selparam *selparams = NULL;
@@ -1964,8 +2046,6 @@ int do_config_box(const char *title, Config *cfg, int midsession,
 
     dlg_init(&dp);
 
-    get_sesslist(&sl, TRUE);
-
     listitemheight = get_listitemheight();
 
     for (index = 0; index < lenof(scs.sc); index++) {
@@ -1975,8 +2055,8 @@ int do_config_box(const char *title, Config *cfg, int midsession,
     window = gtk_dialog_new();
 
     ctrlbox = ctrl_new_box();
-    setup_config_box(ctrlbox, &sl, midsession, cfg->protocol, protcfginfo);
-    unix_setup_config_box(ctrlbox, midsession);
+    setup_config_box(ctrlbox, midsession, cfg->protocol, protcfginfo);
+    unix_setup_config_box(ctrlbox, midsession, cfg->protocol);
     gtk_setup_config_box(ctrlbox, midsession, window);
 
     gtk_window_set_title(GTK_WINDOW(window), title);
@@ -2011,7 +2091,9 @@ int do_config_box(const char *title, Config *cfg, int midsession,
     gtk_widget_show(tree);
     gtk_widget_show(treescroll);
     gtk_box_pack_start(GTK_BOX(vbox), treescroll, TRUE, TRUE, 0);
-    panels = panels_new();
+    panels = gtk_notebook_new();
+    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(panels), FALSE);
+    gtk_notebook_set_show_border(GTK_NOTEBOOK(panels), FALSE);
     gtk_box_pack_start(GTK_BOX(hbox), panels, TRUE, TRUE, 0);
     gtk_widget_show(panels);
 
@@ -2081,9 +2163,15 @@ int do_config_box(const char *title, Config *cfg, int midsession,
                first = (panelvbox == NULL);
 
                panelvbox = gtk_vbox_new(FALSE, 4);
-               gtk_container_add(GTK_CONTAINER(panels), panelvbox);
+               gtk_widget_show(panelvbox);
+               gtk_notebook_append_page(GTK_NOTEBOOK(panels), panelvbox,
+                                        NULL);
                if (first) {
-                   panels_switch_to(PANELS(panels), panelvbox);
+                   gint page_num;
+
+                   page_num = gtk_notebook_page_num(GTK_NOTEBOOK(panels),
+                                                    panelvbox);
+                   gtk_notebook_set_page(GTK_NOTEBOOK(panels), page_num);
                    gtk_tree_select_child(GTK_TREE(tree), treeitem);
                }
 
@@ -2093,7 +2181,7 @@ int do_config_box(const char *title, Config *cfg, int midsession,
                                        struct selparam);
                }
                selparams[nselparams].dp = &dp;
-               selparams[nselparams].panels = PANELS(panels);
+               selparams[nselparams].panels = GTK_NOTEBOOK(panels);
                selparams[nselparams].panel = panelvbox;
                selparams[nselparams].shortcuts = scs;   /* structure copy */
                selparams[nselparams].treeitem = treeitem;
@@ -2161,7 +2249,6 @@ int do_config_box(const char *title, Config *cfg, int midsession,
 
     gtk_main();
 
-    get_sesslist(&sl, FALSE);
     dlg_cleanup(&dp);
     sfree(selparams);
 
@@ -2347,13 +2434,12 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
 
     sfree(text);
 
-    if (ret == 0)
-        return 0;                      /* do not continue with connection */
-    else {
-        if (ret == 2)
-            store_host_key(host, port, keytype, keystr);
-        return 1;                      /* continue with connection */
-    }
+    if (ret == 2) {
+       store_host_key(host, port, keytype, keystr);
+       return 1;                      /* continue with connection */
+    } else if (ret == 1)
+       return 1;                      /* continue with connection */
+    return 0;                         /* do not continue with connection */
 }
 
 /*
@@ -2425,11 +2511,12 @@ static void licence_clicked(GtkButton *button, gpointer data)
     char *title;
 
     char *licence =
-       "Copyright 1997-2005 Simon Tatham.\n\n"
+       "Copyright 1997-2006 Simon Tatham.\n\n"
 
        "Portions copyright Robert de Bath, Joris van Rantwijk, Delian "
        "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas "
-       "Barry, Justin Bradford, Ben Harris, Malcolm Smith, and CORE SDI S.A.\n\n"
+       "Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, "
+       "Markus Kuhn, and CORE SDI S.A.\n\n"
 
        "Permission is hereby granted, free of charge, to any person "
        "obtaining a copy of this software and associated documentation "
@@ -2505,7 +2592,7 @@ void about_box(void *window)
                       w, FALSE, FALSE, 5);
     gtk_widget_show(w);
 
-    w = gtk_label_new("Copyright 1997-2005 Simon Tatham. All rights reserved");
+    w = gtk_label_new("Copyright 1997-2006 Simon Tatham. All rights reserved");
     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutbox)->vbox),
                       w, FALSE, FALSE, 5);
     gtk_widget_show(w);
@@ -2609,7 +2696,7 @@ void eventlog_selection_get(GtkWidget *widget, GtkSelectionData *seldata,
     struct eventlog_stuff *es = (struct eventlog_stuff *)data;
 
     gtk_selection_data_set(seldata, seldata->target, 8,
-                           es->seldata, es->sellen);
+                           (unsigned char *)es->seldata, es->sellen);
 }
 
 gint eventlog_selection_clear(GtkWidget *widget, GdkEventSelection *seldata,
@@ -2753,7 +2840,8 @@ void logevent_dlg(void *estuff, const char *string)
     es->nevents++;
 }
 
-int askappend(void *frontend, Filename filename)
+int askappend(void *frontend, Filename filename,
+             void (*callback)(void *ctx, int result), void *ctx)
 {
     static const char msgtemplate[] =
        "The session log file \"%.*s\" already exists. "