X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/8b0cb5aaa808f330932a55e8d79bf6eaa5f294ec..79bf227ba7ba02e32ac710621b672e2789f9ef50:/config.c diff --git a/config.c b/config.c index f41e9ec4..d3d76f57 100644 --- a/config.c +++ b/config.c @@ -110,7 +110,7 @@ static void cipherlist_handler(union control *ctrl, void *dlg, break; } } - dlg_listbox_addwithindex(ctrl, dlg, cstr, c); + dlg_listbox_addwithid(ctrl, dlg, cstr, c); } dlg_update_done(ctrl, dlg); @@ -133,12 +133,18 @@ static void printerbox_handler(union control *ctrl, void *dlg, printer_enum *pe; dlg_update_start(ctrl, dlg); - dlg_listbox_clear(ctrl, dlg); - dlg_listbox_add(ctrl, dlg, PRINTER_DISABLED_STRING); - pe = printer_start_enum(&nprinters); - for (i = 0; i < nprinters; i++) - dlg_listbox_add(ctrl, dlg, printer_get_name(pe, i)); - printer_finish_enum(pe); + /* + * Some backends may wish to disable the drop-down list on + * this edit box. Be prepared for this. + */ + if (ctrl->editbox.has_list) { + dlg_listbox_clear(ctrl, dlg); + dlg_listbox_add(ctrl, dlg, PRINTER_DISABLED_STRING); + pe = printer_start_enum(&nprinters); + for (i = 0; i < nprinters; i++) + dlg_listbox_add(ctrl, dlg, printer_get_name(pe, i)); + printer_finish_enum(pe); + } dlg_editbox_set(ctrl, dlg, (*cfg->printer ? cfg->printer : PRINTER_DISABLED_STRING)); @@ -156,7 +162,7 @@ static void codepage_handler(union control *ctrl, void *dlg, Config *cfg = (Config *)data; if (event == EVENT_REFRESH) { int i; - char *cp; + const char *cp; dlg_update_start(ctrl, dlg); strcpy(cfg->line_codepage, cp_name(decode_codepage(cfg->line_codepage))); @@ -179,9 +185,9 @@ static void sshbug_handler(union control *ctrl, void *dlg, if (event == EVENT_REFRESH) { dlg_update_start(ctrl, dlg); dlg_listbox_clear(ctrl, dlg); - dlg_listbox_addwithindex(ctrl, dlg, "Auto", AUTO); - dlg_listbox_addwithindex(ctrl, dlg, "Off", FORCE_OFF); - dlg_listbox_addwithindex(ctrl, dlg, "On", FORCE_ON); + dlg_listbox_addwithid(ctrl, dlg, "Auto", AUTO); + dlg_listbox_addwithid(ctrl, dlg, "Off", FORCE_OFF); + dlg_listbox_addwithid(ctrl, dlg, "On", FORCE_ON); switch (*(int *)ATOFFSET(data, ctrl->listbox.context.i)) { case AUTO: dlg_listbox_select(ctrl, dlg, 0); break; case FORCE_OFF: dlg_listbox_select(ctrl, dlg, 1); break; @@ -198,10 +204,11 @@ static void sshbug_handler(union control *ctrl, void *dlg, } } +#define SAVEDSESSION_LEN 2048 + struct sessionsaver_data { union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton; union control *okbutton, *cancelbutton; - char savedsession[2048]; struct sesslist *sesslist; }; @@ -211,6 +218,7 @@ struct sessionsaver_data { * failure. */ static int load_selected_session(struct sessionsaver_data *ssd, + char *savedsession, void *dlg, Config *cfg) { int i = dlg_listbox_index(ssd->listbox, dlg); @@ -222,11 +230,11 @@ static int load_selected_session(struct sessionsaver_data *ssd, isdef = !strcmp(ssd->sesslist->sessions[i], "Default Settings"); load_settings(ssd->sesslist->sessions[i], !isdef, cfg); if (!isdef) { - strncpy(ssd->savedsession, ssd->sesslist->sessions[i], - sizeof(ssd->savedsession)); - ssd->savedsession[sizeof(ssd->savedsession)-1] = '\0'; + strncpy(savedsession, ssd->sesslist->sessions[i], + SAVEDSESSION_LEN); + savedsession[SAVEDSESSION_LEN-1] = '\0'; } else { - ssd->savedsession[0] = '\0'; + savedsession[0] = '\0'; } dlg_refresh(NULL, dlg); /* Restore the selection, which might have been clobbered by @@ -241,10 +249,29 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, Config *cfg = (Config *)data; struct sessionsaver_data *ssd = (struct sessionsaver_data *)ctrl->generic.context.p; + char *savedsession; + + /* + * The first time we're called in a new dialog, we must + * allocate space to store the current contents of the saved + * session edit box (since it must persist even when we switch + * panels, but is not part of the Config). + * + * Of course, this doesn't need to be done mid-session. + */ + if (!ssd->editbox) { + savedsession = NULL; + } else if (!dlg_get_privdata(ssd->editbox, dlg)) { + savedsession = (char *) + dlg_alloc_privdata(ssd->editbox, dlg, SAVEDSESSION_LEN); + savedsession[0] = '\0'; + } else { + savedsession = dlg_get_privdata(ssd->editbox, dlg); + } if (event == EVENT_REFRESH) { if (ctrl == ssd->editbox) { - dlg_editbox_set(ctrl, dlg, ssd->savedsession); + dlg_editbox_set(ctrl, dlg, savedsession); } else if (ctrl == ssd->listbox) { int i; dlg_update_start(ctrl, dlg); @@ -255,8 +282,8 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, } } else if (event == EVENT_VALCHANGE) { if (ctrl == ssd->editbox) { - dlg_editbox_get(ctrl, dlg, ssd->savedsession, - sizeof(ssd->savedsession)); + dlg_editbox_get(ctrl, dlg, savedsession, + SAVEDSESSION_LEN); } } else if (event == EVENT_ACTION) { if (ctrl == ssd->listbox || ctrl == ssd->loadbutton) { @@ -267,13 +294,13 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, * double-click on the list box _and_ that session * contains a hostname. */ - if (load_selected_session(ssd, dlg, cfg) && + if (load_selected_session(ssd, savedsession, dlg, cfg) && (ctrl == ssd->listbox && cfg->host[0])) { dlg_end(dlg, 1); /* it's all over, and succeeded */ } } else if (ctrl == ssd->savebutton) { - int isdef = !strcmp(ssd->savedsession, "Default Settings"); - if (!ssd->savedsession[0]) { + int isdef = !strcmp(savedsession, "Default Settings"); + if (!savedsession[0]) { int i = dlg_listbox_index(ssd->listbox, dlg); if (i < 0) { dlg_beep(dlg); @@ -281,14 +308,20 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, } isdef = !strcmp(ssd->sesslist->sessions[i], "Default Settings"); if (!isdef) { - strncpy(ssd->savedsession, ssd->sesslist->sessions[i], - sizeof(ssd->savedsession)); - ssd->savedsession[sizeof(ssd->savedsession)-1] = '\0'; + strncpy(savedsession, ssd->sesslist->sessions[i], + SAVEDSESSION_LEN); + savedsession[SAVEDSESSION_LEN-1] = '\0'; } else { - ssd->savedsession[0] = '\0'; + savedsession[0] = '\0'; } } - save_settings(ssd->savedsession, !isdef, cfg); + { + char *errmsg = save_settings(savedsession, !isdef, cfg); + if (errmsg) { + dlg_error_msg(dlg, errmsg); + sfree(errmsg); + } + } get_sesslist(ssd->sesslist, FALSE); get_sesslist(ssd->sesslist, TRUE); dlg_refresh(ssd->editbox, dlg); @@ -304,6 +337,11 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, dlg_refresh(ssd->listbox, dlg); } } else if (ctrl == ssd->okbutton) { + if (!savedsession) { + /* In a mid-session Change Settings, Apply is always OK. */ + dlg_end(dlg, 1); + return; + } /* * Annoying special case. If the `Open' button is * pressed while no host name is currently set, _and_ @@ -311,15 +349,16 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, * there was a session selected in that which had a * valid host name in it, then load it and go. */ - if (dlg_last_focused(dlg) == ssd->listbox && !*cfg->host) { + if (dlg_last_focused(ctrl, dlg) == ssd->listbox && !*cfg->host) { Config cfg2; - if (!load_selected_session(ssd, dlg, &cfg2)) { + if (!load_selected_session(ssd, savedsession, dlg, &cfg2)) { dlg_beep(dlg); return; } /* If at this point we have a valid session, go! */ if (*cfg2.host) { *cfg = cfg2; /* structure copy */ + cfg->remote_cmd_ptr = cfg->remote_cmd; /* nasty */ dlg_end(dlg, 1); } else dlg_beep(dlg); @@ -379,7 +418,7 @@ static void charclass_handler(union control *ctrl, void *dlg, } struct colour_data { - union control *listbox, *rgbtext, *button; + union control *listbox, *redit, *gedit, *bedit, *button; }; static const char *const colours[] = { @@ -412,7 +451,9 @@ static void colour_handler(union control *ctrl, void *dlg, for (i = 0; i < lenof(colours); i++) dlg_listbox_add(ctrl, dlg, colours[i]); dlg_update_done(ctrl, dlg); - dlg_text_set(cd->rgbtext, dlg, ""); + dlg_editbox_set(cd->redit, dlg, ""); + dlg_editbox_set(cd->gedit, dlg, ""); + dlg_editbox_set(cd->bedit, dlg, ""); } } else if (event == EVENT_SELCHANGE) { if (ctrl == cd->listbox) { @@ -427,6 +468,25 @@ static void colour_handler(union control *ctrl, void *dlg, b = cfg->colours[i][2]; update = TRUE; } + } else if (event == EVENT_VALCHANGE) { + if (ctrl == cd->redit || ctrl == cd->gedit || ctrl == cd->bedit) { + /* The user has changed the colour using the edit boxes. */ + char buf[80]; + int i, cval; + + dlg_editbox_get(ctrl, dlg, buf, lenof(buf)); + cval = atoi(buf) & 255; + + i = dlg_listbox_index(cd->listbox, dlg); + if (i >= 0) { + if (ctrl == cd->redit) + cfg->colours[i][0] = cval; + else if (ctrl == cd->gedit) + cfg->colours[i][1] = cval; + else if (ctrl == cd->bedit) + cfg->colours[i][2] = cval; + } + } } else if (event == EVENT_ACTION) { if (ctrl == cd->button) { int i = dlg_listbox_index(cd->listbox, dlg); @@ -463,8 +523,9 @@ static void colour_handler(union control *ctrl, void *dlg, if (update) { char buf[40]; - sprintf(buf, "%02x/%02x/%02x", r, g, b); - dlg_text_set(cd->rgbtext, dlg, buf); + sprintf(buf, "%d", r); dlg_editbox_set(cd->redit, dlg, buf); + sprintf(buf, "%d", g); dlg_editbox_set(cd->gedit, dlg, buf); + sprintf(buf, "%d", b); dlg_editbox_set(cd->bedit, dlg, buf); } } @@ -579,29 +640,41 @@ static void portfwd_handler(union control *ctrl, void *dlg, p += strlen(p) + 1; } dlg_update_done(ctrl, dlg); + } else if (ctrl == pfd->direction) { + /* + * Default is Local. + */ + dlg_radiobutton_set(ctrl, dlg, 0); } } else if (event == EVENT_ACTION) { if (ctrl == pfd->addbutton) { char str[sizeof(cfg->portfwd)]; char *p; - if (dlg_radiobutton_get(pfd->direction, dlg) == 0) + int whichbutton = dlg_radiobutton_get(pfd->direction, dlg); + if (whichbutton == 0) str[0] = 'L'; - else + else if (whichbutton == 1) str[0] = 'R'; + else + str[0] = 'D'; dlg_editbox_get(pfd->sourcebox, dlg, str+1, sizeof(str) - 2); if (!str[1]) { dlg_error_msg(dlg, "You need to specify a source port number"); return; } p = str + strlen(str); - *p++ = '\t'; - dlg_editbox_get(pfd->destbox, dlg, p, sizeof(str)-1 - (p - str)); - if (!*p || !strchr(p, ':')) { - dlg_error_msg(dlg, - "You need to specify a destination address\n" - "in the form \"host.name:port\""); - return; - } + if (str[0] != 'D') { + *p++ = '\t'; + dlg_editbox_get(pfd->destbox, dlg, p, + sizeof(str)-1 - (p - str)); + if (!*p || !strchr(p, ':')) { + dlg_error_msg(dlg, + "You need to specify a destination address\n" + "in the form \"host.name:port\""); + return; + } + } else + *p = '\0'; p = cfg->portfwd; while (*p) { while (*p) @@ -663,9 +736,11 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, struct environ_data *ed; struct portfwd_data *pfd; union control *c; + char *str; ssd = (struct sessionsaver_data *) ctrl_alloc(b, sizeof(struct sessionsaver_data)); + memset(ssd, 0, sizeof(*ssd)); ssd->sesslist = (midsession ? NULL : sesslist); /* @@ -683,6 +758,7 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, ssd->okbutton->generic.column = 3; ssd->cancelbutton = ctrl_pushbutton(s, "Cancel", 'c', HELPCTX(no_help), sessionsaver_handler, P(ssd)); + ssd->cancelbutton->button.iscancel = TRUE; ssd->cancelbutton->generic.column = 4; /* We carefully don't close the 5-column part, so that platform- * specific add-ons can put extra buttons alongside Open and Cancel. */ @@ -690,7 +766,9 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, /* * The Session panel. */ - ctrl_settitle(b, "Session", "Basic options for your PuTTY session"); + str = dupprintf("Basic options for your %s session", appname); + ctrl_settitle(b, "Session", str); + sfree(str); if (!midsession) { s = ctrl_getset(b, "Session", "hostport", @@ -706,7 +784,7 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, I(offsetof(Config,port)), I(-1)); c->generic.column = 1; ctrl_columns(s, 1, 100); - if (backends[3].backend == NULL) { + if (backends[3].name == NULL) { ctrl_radiobuttons(s, "Protocol:", NO_SHORTCUT, 3, HELPCTX(session_hostname), protocolbuttons_handler, P(c), @@ -728,7 +806,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, s = ctrl_getset(b, "Session", "savedsessions", "Load, save or delete a stored session"); ctrl_columns(s, 2, 75, 25); - ssd->savedsession[0] = '\0'; ssd->sesslist = sesslist; ssd->editbox = ctrl_editbox(s, "Saved Sessions", 'e', 100, HELPCTX(session_saved), @@ -738,6 +815,11 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, * than alongside that edit box. */ ctrl_columns(s, 1, 100); ctrl_columns(s, 2, 75, 25); + ssd->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT, + HELPCTX(session_saved), + sessionsaver_handler, P(ssd)); + ssd->listbox->generic.column = 0; + ssd->listbox->listbox.height = 7; ssd->loadbutton = ctrl_pushbutton(s, "Load", 'l', HELPCTX(session_saved), sessionsaver_handler, P(ssd)); @@ -750,11 +832,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, HELPCTX(session_saved), sessionsaver_handler, P(ssd)); ssd->delbutton->generic.column = 1; - ssd->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT, - HELPCTX(session_saved), - sessionsaver_handler, P(ssd)); - ssd->listbox->generic.column = 0; - ssd->listbox->listbox.height = 7; ctrl_columns(s, 1, 100); } @@ -773,14 +850,27 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, ctrl_settitle(b, "Session/Logging", "Options controlling session logging"); s = ctrl_getset(b, "Session/Logging", "main", NULL); - ctrl_radiobuttons(s, "Session logging:", NO_SHORTCUT, 1, - HELPCTX(logging_main), - dlg_stdradiobutton_handler, I(offsetof(Config, logtype)), - "Logging turned off completely", 't', I(LGTYP_NONE), - "Log printable output only", 'p', I(LGTYP_ASCII), - "Log all session output", 'l', I(LGTYP_DEBUG), - "Log SSH packet data", 's', I(LGTYP_PACKETS), - NULL); + /* + * The logging buttons change depending on whether SSH packet + * logging can sensibly be available. + */ + { + char *sshlogname; + if ((midsession && protocol == PROT_SSH) || + (!midsession && backends[3].name != NULL)) + sshlogname = "Log SSH packet data"; + else + sshlogname = NULL; /* this will disable the button */ + ctrl_radiobuttons(s, "Session logging:", NO_SHORTCUT, 1, + HELPCTX(logging_main), + dlg_stdradiobutton_handler, + I(offsetof(Config, logtype)), + "Logging turned off completely", 't', I(LGTYP_NONE), + "Log printable output only", 'p', I(LGTYP_ASCII), + "Log all session output", 'l', I(LGTYP_DEBUG), + sshlogname, 's', I(LGTYP_PACKETS), + NULL); + } ctrl_filesel(s, "Log file name:", 'f', NULL, TRUE, "Select session log file name", HELPCTX(logging_filename), @@ -903,13 +993,13 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, ctrl_editbox(s, "... in this many seconds", 't', 20, HELPCTX(bell_overload), dlg_stdeditbox_handler, I(offsetof(Config,bellovl_t)), - I(-1000)); + I(-TICKSPERSEC)); ctrl_text(s, "The bell is re-enabled after a few seconds of silence.", HELPCTX(bell_overload)); ctrl_editbox(s, "Seconds of silence required", 's', 20, HELPCTX(bell_overload), dlg_stdeditbox_handler, I(offsetof(Config,bellovl_s)), - I(-1000)); + I(-TICKSPERSEC)); /* * The Terminal/Features panel. @@ -938,17 +1028,28 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, HELPCTX(features_retitle), dlg_stdcheckbox_handler, I(offsetof(Config,no_remote_wintitle))); + ctrl_checkbox(s, "Disable remote window title querying (SECURITY)", + 'q', HELPCTX(features_qtitle), dlg_stdcheckbox_handler, + I(offsetof(Config,no_remote_qtitle))); ctrl_checkbox(s, "Disable destructive backspace on server sending ^?",'b', HELPCTX(features_dbackspace), dlg_stdcheckbox_handler, I(offsetof(Config,no_dbackspace))); ctrl_checkbox(s, "Disable remote-controlled character set configuration", 'r', HELPCTX(features_charset), dlg_stdcheckbox_handler, I(offsetof(Config,no_remote_charset))); + ctrl_checkbox(s, "Disable Arabic text shaping", + 'l', HELPCTX(features_arabicshaping), dlg_stdcheckbox_handler, + I(offsetof(Config, arabicshaping))); + ctrl_checkbox(s, "Disable bidirectional text display", + 'd', HELPCTX(features_bidi), dlg_stdcheckbox_handler, + I(offsetof(Config, bidi))); /* * The Window panel. */ - ctrl_settitle(b, "Window", "Options controlling PuTTY's window"); + str = dupprintf("Options controlling %s's window", appname); + ctrl_settitle(b, "Window", str); + sfree(str); s = ctrl_getset(b, "Window", "size", "Set the size of the window"); ctrl_columns(s, 2, 50, 50); @@ -970,10 +1071,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, ctrl_checkbox(s, "Display scrollbar", 'd', HELPCTX(window_scrollback), dlg_stdcheckbox_handler, I(offsetof(Config,scrollbar))); - ctrl_checkbox(s, "Display scrollbar in full screen mode", 'i', - HELPCTX(window_scrollback), - dlg_stdcheckbox_handler, - I(offsetof(Config,scrollbar_in_fullscreen))); ctrl_checkbox(s, "Reset scrollback on keypress", 'k', HELPCTX(window_scrollback), dlg_stdcheckbox_handler, I(offsetof(Config,scroll_on_key))); @@ -988,8 +1085,9 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, /* * The Window/Appearance panel. */ - ctrl_settitle(b, "Window/Appearance", - "Configure the appearance of PuTTY's window"); + str = dupprintf("Configure the appearance of %s's window", appname); + ctrl_settitle(b, "Window/Appearance", str); + sfree(str); s = ctrl_getset(b, "Window/Appearance", "cursor", "Adjust the use of the cursor"); @@ -1026,8 +1124,9 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, /* * The Window/Behaviour panel. */ - ctrl_settitle(b, "Window/Behaviour", - "Configure the behaviour of PuTTY's window"); + str = dupprintf("Configure the behaviour of %s's window", appname); + ctrl_settitle(b, "Window/Behaviour", str); + sfree(str); s = ctrl_getset(b, "Window/Behaviour", "title", "Adjust the behaviour of the window title"); @@ -1057,26 +1156,24 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, 'r', 100, HELPCTX(translation_codepage), codepage_handler, P(NULL), P(NULL)); - s = ctrl_getset(b, "Window/Translation", "linedraw", - "Adjust how PuTTY displays line drawing characters"); + str = dupprintf("Adjust how %s handles line drawing characters", appname); + s = ctrl_getset(b, "Window/Translation", "linedraw", str); + sfree(str); ctrl_radiobuttons(s, "Handling of line drawing characters:", NO_SHORTCUT,1, HELPCTX(translation_linedraw), dlg_stdradiobutton_handler, I(offsetof(Config, vtmode)), - "Font has XWindows encoding", 'x', I(VT_XWINDOWS), + "Use Unicode line drawing code points",'u',I(VT_UNICODE), "Poor man's line drawing (+, - and |)",'p',I(VT_POORMAN), - "Unicode mode", 'u', I(VT_UNICODE), NULL); + NULL); + ctrl_checkbox(s, "Copy and paste line drawing characters as lqqqk",'d', + HELPCTX(selection_linedraw), + dlg_stdcheckbox_handler, I(offsetof(Config,rawcnp))); /* * The Window/Selection panel. */ ctrl_settitle(b, "Window/Selection", "Options controlling copy and paste"); - - s = ctrl_getset(b, "Window/Selection", "trans", - "Translation of pasted characters"); - ctrl_checkbox(s, "Don't translate line drawing chars into +, - and |",'d', - HELPCTX(selection_linedraw), - dlg_stdcheckbox_handler, I(offsetof(Config,rawcnp))); s = ctrl_getset(b, "Window/Selection", "mouse", "Control use of mouse"); @@ -1101,7 +1198,7 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, charclass_handler, P(ccd)); ccd->listbox->listbox.multisel = 1; ccd->listbox->listbox.ncols = 4; - ccd->listbox->listbox.percentages = smalloc(4*sizeof(int)); + ccd->listbox->listbox.percentages = snewn(4, int); ccd->listbox->listbox.percentages[0] = 15; ccd->listbox->listbox.percentages[1] = 25; ccd->listbox->listbox.percentages[2] = 20; @@ -1128,8 +1225,9 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, HELPCTX(colours_bold), dlg_stdcheckbox_handler, I(offsetof(Config,bold_colour))); - s = ctrl_getset(b, "Window/Colours", "adjust", - "Adjust the precise colours PuTTY displays"); + str = dupprintf("Adjust the precise colours %s displays", appname); + s = ctrl_getset(b, "Window/Colours", "adjust", str); + sfree(str); ctrl_text(s, "Select a colour from the list, and then click the" " Modify button to change its appearance.", HELPCTX(colours_config)); @@ -1138,46 +1236,68 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, cd->listbox = ctrl_listbox(s, "Select a colour to adjust:", 'u', HELPCTX(colours_config), colour_handler, P(cd)); cd->listbox->generic.column = 0; + cd->listbox->listbox.height = 7; c = ctrl_text(s, "RGB value:", HELPCTX(colours_config)); c->generic.column = 1; - cd->rgbtext = ctrl_text(s, "00/00/00", HELPCTX(colours_config)); - cd->rgbtext->generic.column = 1; + cd->redit = ctrl_editbox(s, "Red", 'r', 50, HELPCTX(colours_config), + colour_handler, P(cd), P(NULL)); + cd->redit->generic.column = 1; + cd->gedit = ctrl_editbox(s, "Green", 'n', 50, HELPCTX(colours_config), + colour_handler, P(cd), P(NULL)); + cd->gedit->generic.column = 1; + cd->bedit = ctrl_editbox(s, "Blue", 'e', 50, HELPCTX(colours_config), + colour_handler, P(cd), P(NULL)); + cd->bedit->generic.column = 1; cd->button = ctrl_pushbutton(s, "Modify", 'm', HELPCTX(colours_config), colour_handler, P(cd)); cd->button->generic.column = 1; ctrl_columns(s, 1, 100); /* - * The Connection panel. + * The Connection panel. This doesn't show up if we're in a + * non-network utility such as pterm. We tell this by being + * passed a protocol < 0. */ - ctrl_settitle(b, "Connection", "Options controlling the connection"); + if (protocol >= 0) { + ctrl_settitle(b, "Connection", "Options controlling the connection"); - if (!midsession) { - s = ctrl_getset(b, "Connection", "data", "Data to send to the server"); - ctrl_editbox(s, "Terminal-type string", 't', 50, - HELPCTX(connection_termtype), - dlg_stdeditbox_handler, I(offsetof(Config,termtype)), - I(sizeof(((Config *)0)->termtype))); - ctrl_editbox(s, "Auto-login username", 'u', 50, - HELPCTX(connection_username), - dlg_stdeditbox_handler, I(offsetof(Config,username)), - I(sizeof(((Config *)0)->username))); - } + if (!midsession) { + s = ctrl_getset(b, "Connection", "data", + "Data to send to the server"); + ctrl_editbox(s, "Terminal-type string", 't', 50, + HELPCTX(connection_termtype), + dlg_stdeditbox_handler, I(offsetof(Config,termtype)), + I(sizeof(((Config *)0)->termtype))); + ctrl_editbox(s, "Terminal speeds", 's', 50, + HELPCTX(connection_termspeed), + dlg_stdeditbox_handler, I(offsetof(Config,termspeed)), + I(sizeof(((Config *)0)->termspeed))); + ctrl_editbox(s, "Auto-login username", 'u', 50, + HELPCTX(connection_username), + dlg_stdeditbox_handler, I(offsetof(Config,username)), + I(sizeof(((Config *)0)->username))); + } - s = ctrl_getset(b, "Connection", "keepalive", - "Sending of null packets to keep session active"); - ctrl_editbox(s, "Seconds between keepalives (0 to turn off)", 'k', 20, - HELPCTX(connection_keepalive), - dlg_stdeditbox_handler, I(offsetof(Config,ping_interval)), - I(-1)); + s = ctrl_getset(b, "Connection", "keepalive", + "Sending of null packets to keep session active"); + ctrl_editbox(s, "Seconds between keepalives (0 to turn off)", 'k', 20, + HELPCTX(connection_keepalive), + dlg_stdeditbox_handler, I(offsetof(Config,ping_interval)), + I(-1)); + + if (!midsession) { + s = ctrl_getset(b, "Connection", "tcp", + "Low-level TCP connection options"); + ctrl_checkbox(s, "Disable Nagle's algorithm (TCP_NODELAY option)", + 'n', HELPCTX(connection_nodelay), + dlg_stdcheckbox_handler, + I(offsetof(Config,tcp_nodelay))); + ctrl_checkbox(s, "Enable TCP keepalives (SO_KEEPALIVE option)", + 'p', HELPCTX(connection_tcpkeepalive), + dlg_stdcheckbox_handler, + I(offsetof(Config,tcp_keepalives))); + } - if (!midsession) { - s = ctrl_getset(b, "Connection", "tcp", - "Low-level TCP connection options"); - ctrl_checkbox(s, "Disable Nagle's algorithm (TCP_NODELAY option)", 'n', - HELPCTX(connection_nodelay), - dlg_stdcheckbox_handler, - I(offsetof(Config,tcp_nodelay))); } if (!midsession) { @@ -1187,15 +1307,16 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, ctrl_settitle(b, "Connection/Proxy", "Options controlling proxy usage"); - s = ctrl_getset(b, "Connection/Proxy", "basics", "Proxy basics"); - ctrl_radiobuttons(s, "Proxy type:", NO_SHORTCUT, 4, + s = ctrl_getset(b, "Connection/Proxy", "basics", NULL); + ctrl_radiobuttons(s, "Proxy type:", 't', 3, HELPCTX(proxy_type), dlg_stdradiobutton_handler, I(offsetof(Config, proxy_type)), - "None", 'n', I(PROXY_NONE), - "HTTP", 't', I(PROXY_HTTP), - "SOCKS", 's', I(PROXY_SOCKS), - "Telnet", 'l', I(PROXY_TELNET), + "None", I(PROXY_NONE), + "SOCKS 4", I(PROXY_SOCKS4), + "SOCKS 5", I(PROXY_SOCKS5), + "HTTP", I(PROXY_HTTP), + "Telnet", I(PROXY_TELNET), NULL); ctrl_columns(s, 2, 80, 20); c = ctrl_editbox(s, "Proxy hostname", 'y', 100, @@ -1238,19 +1359,11 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, I(offsetof(Config,proxy_password)), I(sizeof(((Config *)0)->proxy_password))); c->editbox.password = 1; - - s = ctrl_getset(b, "Connection/Proxy", "misc", - "Miscellaneous proxy settings"); ctrl_editbox(s, "Telnet command", 'm', 100, HELPCTX(proxy_command), dlg_stdeditbox_handler, I(offsetof(Config,proxy_telnet_command)), I(sizeof(((Config *)0)->proxy_telnet_command))); - ctrl_radiobuttons(s, "SOCKS Version", 'v', 2, - HELPCTX(proxy_socksver), - dlg_stdradiobutton_handler, - I(offsetof(Config, proxy_socks_version)), - "Version 5", I(5), "Version 4", I(4), NULL); } /* @@ -1267,10 +1380,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, if (!midsession) { s = ctrl_getset(b, "Connection/Telnet", "data", "Data to send to the server"); - ctrl_editbox(s, "Terminal-speed string", 's', 50, - HELPCTX(telnet_termspeed), - dlg_stdeditbox_handler, I(offsetof(Config,termspeed)), - I(sizeof(((Config *)0)->termspeed))); ctrl_text(s, "Environment variables:", HELPCTX(telnet_environ)); ctrl_columns(s, 2, 80, 20); ed = (struct environ_data *) @@ -1296,6 +1405,10 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, HELPCTX(telnet_environ), environ_handler, P(ed)); ed->listbox->listbox.height = 3; + ed->listbox->listbox.ncols = 2; + ed->listbox->listbox.percentages = snewn(2, int); + ed->listbox->listbox.percentages[0] = 30; + ed->listbox->listbox.percentages[1] = 70; } s = ctrl_getset(b, "Connection/Telnet", "protocol", @@ -1335,10 +1448,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, s = ctrl_getset(b, "Connection/Rlogin", "data", "Data to send to the server"); - ctrl_editbox(s, "Terminal-speed string", 's', 50, - HELPCTX(rlogin_termspeed), - dlg_stdeditbox_handler, I(offsetof(Config,termspeed)), - I(sizeof(((Config *)0)->termspeed))); ctrl_editbox(s, "Local username:", 'l', 50, HELPCTX(rlogin_localuser), dlg_stdeditbox_handler, I(offsetof(Config,localusername)), @@ -1350,7 +1459,7 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, * All the SSH stuff is omitted in PuTTYtel. */ - if (!midsession && backends[3].backend != NULL) { + if (!midsession && backends[3].name != NULL) { /* * The Connection/SSH panel. @@ -1384,10 +1493,12 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, "2 only", 'n', I(3), NULL); s = ctrl_getset(b, "Connection/SSH", "encryption", "Encryption options"); - ctrl_draglist(s, "Encryption cipher selection policy:", 's', - HELPCTX(ssh_ciphers), - cipherlist_handler, P(NULL)); - ctrl_checkbox(s, "Enable non-standard use of single-DES in SSH 2", 'i', + c = ctrl_draglist(s, "Encryption cipher selection policy:", 's', + HELPCTX(ssh_ciphers), + cipherlist_handler, P(NULL)); + c->listbox.height = 6; + + ctrl_checkbox(s, "Enable legacy use of single-DES in SSH 2", 'i', HELPCTX(ssh_ciphers), dlg_stdcheckbox_handler, I(offsetof(Config,ssh2_des_cbc))); @@ -1470,6 +1581,10 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, HELPCTX(ssh_tunnels_portfwd), portfwd_handler, P(pfd)); pfd->listbox->listbox.height = 3; + pfd->listbox->listbox.ncols = 2; + pfd->listbox->listbox.percentages = snewn(2, int); + pfd->listbox->listbox.percentages[0] = 20; + pfd->listbox->listbox.percentages[1] = 80; ctrl_tabdelay(s, pfd->rembutton); ctrl_text(s, "Add new forwarded port:", HELPCTX(ssh_tunnels_portfwd)); /* You want to enter source, destination and type, _then_ hit Add. @@ -1486,11 +1601,13 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, pfd->destbox = ctrl_editbox(s, "Destination", 'i', 67, HELPCTX(ssh_tunnels_portfwd), portfwd_handler, P(pfd), P(NULL)); - pfd->direction = ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 2, + pfd->direction = ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3, HELPCTX(ssh_tunnels_portfwd), portfwd_handler, P(pfd), "Local", 'l', P(NULL), - "Remote", 'm', P(NULL), NULL); + "Remote", 'm', P(NULL), + "Dynamic", 'y', P(NULL), + NULL); ctrl_tabdelay(s, pfd->addbutton); ctrl_columns(s, 1, 100);