break;
}
}
- dlg_listbox_addwithindex(ctrl, dlg, cstr, c);
+ dlg_listbox_addwithid(ctrl, dlg, cstr, c);
}
dlg_update_done(ctrl, 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));
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)));
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;
* 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 (!dlg_get_privdata(ssd->editbox, dlg)) {
+ 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';
savedsession[0] = '\0';
}
}
- save_settings(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);
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_
* 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, savedsession, dlg, &cfg2)) {
dlg_beep(dlg);
}
struct colour_data {
- union control *listbox, *rgbtext, *button;
+ union control *listbox, *redit, *gedit, *bedit, *button;
};
static const char *const colours[] = {
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) {
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);
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);
}
}
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)
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);
/*
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. */
/*
* 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",
* 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));
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);
}
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),
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)));
/*
* 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);
/*
* 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");
/*
* 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");
'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 displays 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);
/*
* The Window/Selection panel.
s = ctrl_getset(b, "Window/Selection", "trans",
"Translation of pasted characters");
- ctrl_checkbox(s, "Don't translate line drawing chars into +, - and |",'d',
+ ctrl_checkbox(s, "Paste VT100 line drawing chars as lqqqk",'d',
HELPCTX(selection_linedraw),
dlg_stdcheckbox_handler, I(offsetof(Config,rawcnp)));
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;
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));
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, "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)));
+ }
- 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) {
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,
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);
}
/*
environ_handler, P(ed));
ed->listbox->listbox.height = 3;
ed->listbox->listbox.ncols = 2;
- ed->listbox->listbox.percentages = smalloc(2*sizeof(int));
+ ed->listbox->listbox.percentages = snewn(2, int);
ed->listbox->listbox.percentages[0] = 30;
ed->listbox->listbox.percentages[1] = 70;
}
portfwd_handler, P(pfd));
pfd->listbox->listbox.height = 3;
pfd->listbox->listbox.ncols = 2;
- pfd->listbox->listbox.percentages = smalloc(2*sizeof(int));
+ pfd->listbox->listbox.percentages = snewn(2, int);
pfd->listbox->listbox.percentages[0] = 20;
pfd->listbox->listbox.percentages[1] = 80;
ctrl_tabdelay(s, pfd->rembutton);
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);