Support for Windows PuTTY connecting straight to a local serial port
[u/mdw/putty] / unix / gtkdlg.c
index 4ca8457..19546d9 100644 (file)
@@ -152,6 +152,8 @@ static void dlg_init(struct dlgparam *dp)
     dp->coloursel_result.ok = FALSE;
     dp->treeitems = NULL;
     dp->window = dp->cancelbutton = dp->currtreeitem = NULL;
+    dp->flags = 0;
+    dp->currfocus = NULL;
 }
 
 static void dlg_cleanup(struct dlgparam *dp)
@@ -547,7 +549,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);
+        }
     }
 }
 
@@ -562,6 +592,17 @@ 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)
+{
+    /*
+     * This function is currently only used by the config box to
+     * switch the labels on the host and port boxes between serial
+     * and network modes. Since Unix does not (yet) have a serial
+     * back end, this function can safely do nothing for the
+     * moment.
+     */
+}
+
 void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn)
 {
     struct dlgparam *dp = (struct dlgparam *)dlg;
@@ -1943,7 +1984,8 @@ int get_listitemheight(void)
     return req.height;
 }
 
-int do_config_box(const char *title, Config *cfg, int midsession)
+int do_config_box(const char *title, Config *cfg, int midsession,
+                 int protcfginfo)
 {
     GtkWidget *window, *hbox, *vbox, *cols, *label,
        *tree, *treescroll, *panels, *panelvbox;
@@ -1953,7 +1995,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;
@@ -1961,8 +2002,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++) {
@@ -1972,8 +2011,9 @@ 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);
-    unix_setup_config_box(ctrlbox, midsession, window);
+    setup_config_box(ctrlbox, midsession, cfg->protocol, protcfginfo);
+    unix_setup_config_box(ctrlbox, midsession);
+    gtk_setup_config_box(ctrlbox, midsession, window);
 
     gtk_window_set_title(GTK_WINDOW(window), title);
     hbox = gtk_hbox_new(FALSE, 4);
@@ -2157,7 +2197,6 @@ int do_config_box(const char *title, Config *cfg, int midsession)
 
     gtk_main();
 
-    get_sesslist(&sl, FALSE);
     dlg_cleanup(&dp);
     sfree(selparams);
 
@@ -2290,8 +2329,9 @@ int reallyclose(void *frontend)
     return ret;
 }
 
-void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
-                        char *keystr, char *fingerprint)
+int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
+                        char *keystr, char *fingerprint,
+                        void (*callback)(void *ctx, int result), void *ctx)
 {
     static const char absenttxt[] =
        "The server's host key is not cached. You have no guarantee "
@@ -2328,7 +2368,7 @@ void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
     ret = verify_host_key(host, port, keytype, keystr);
 
     if (ret == 0)                     /* success - key matched OK */
-       return;
+       return 1;
 
     text = dupprintf((ret == 2 ? wrongtxt : absenttxt), keytype, fingerprint);
 
@@ -2342,29 +2382,29 @@ void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
 
     sfree(text);
 
-    if (ret == 0)
-       cleanup_exit(0);
-    else if (ret == 2)
+    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 */
 }
 
 /*
- * Ask whether the selected cipher is acceptable (since it was
+ * Ask whether the selected algorithm is acceptable (since it was
  * below the configured 'warn' threshold).
- * cs: 0 = both ways, 1 = client->server, 2 = server->client
  */
-void askcipher(void *frontend, char *ciphername, int cs)
+int askalg(void *frontend, const char *algtype, const char *algname,
+          void (*callback)(void *ctx, int result), void *ctx)
 {
     static const char msg[] =
-       "The first %scipher supported by the server is "
+       "The first %s supported by the server is "
        "%s, which is below the configured warning threshold.\n"
        "Continue with connection?";
     char *text;
     int ret;
 
-    text = dupprintf(msg, (cs == 0) ? "" :
-                     (cs == 1) ? "client-to-server " : "server-to-client ",
-                     ciphername);
+    text = dupprintf(msg, algtype, algname);
     ret = messagebox(GTK_WIDGET(get_window(frontend)),
                     "PuTTY Security Alert", text,
                     string_width("Continue with connection?"),
@@ -2374,9 +2414,9 @@ void askcipher(void *frontend, char *ciphername, int cs)
     sfree(text);
 
     if (ret) {
-       return;
+       return 1;
     } else {
-       cleanup_exit(0);
+       return 0;
     }
 }
 
@@ -2419,11 +2459,12 @@ static void licence_clicked(GtkButton *button, gpointer data)
     char *title;
 
     char *licence =
-       "Copyright 1997-2004 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, 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 "
@@ -2499,7 +2540,7 @@ void about_box(void *window)
                       w, FALSE, FALSE, 5);
     gtk_widget_show(w);
 
-    w = gtk_label_new("Copyright 1997-2004 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);
@@ -2728,16 +2769,15 @@ void logevent_dlg(void *estuff, const char *string)
     struct eventlog_stuff *es = (struct eventlog_stuff *)estuff;
 
     char timebuf[40];
-    time_t t;
+    struct tm tm;
 
     if (es->nevents >= es->negsize) {
        es->negsize += 64;
        es->events = sresize(es->events, es->negsize, char *);
     }
 
-    time(&t);
-    strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
-            localtime(&t));
+    tm=ltime();
+    strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", &tm);
 
     es->events[es->nevents] = snewn(strlen(timebuf) + strlen(string) + 1, char);
     strcpy(es->events[es->nevents], timebuf);
@@ -2748,7 +2788,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. "