1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-07 06:22:47 -05:00

Support for Windows PuTTY connecting straight to a local serial port

in place of making a network connection. This has involved a couple
of minor infrastructure changes:
 - New dlg_label_change() function in the dialog.h interface, which
   alters the label on a control. Only used, at present, to switch
   the Host Name and Port boxes into Serial Line and Speed, which
   means that any platform not implementing serial connections (i.e.
   currently all but Windows) does not need to actually do anything
   in this function. Yet.
 - New small piece of infrastructure: cfg_launchable() determines
   whether a Config structure describes a session ready to be
   launched. This was previously determined by seeing if it had a
   non-empty host name, but it has to check the serial line as well
   so there's a centralised function for it. I haven't gone through
   all front ends and arranged for this function to be used
   everywhere it needs to be; so far I've only checked Windows.
 - Similarly, cfg_dest() returns the destination of a connection
   (host name or serial line) in a text format suitable for putting
   into messages such as `Unable to connect to %s'.

[originally from svn r6815]
This commit is contained in:
Simon Tatham
2006-08-28 10:35:12 +00:00
parent 38f003dbe9
commit 34f747421d
23 changed files with 1056 additions and 43 deletions

130
config.c
View File

@ -12,16 +12,94 @@
#define PRINTER_DISABLED_STRING "None (printing disabled)"
static void protocolbuttons_handler(union control *ctrl, void *dlg,
#define HOST_BOX_TITLE "Host Name (or IP address)"
#define PORT_BOX_TITLE "Port"
static void config_host_handler(union control *ctrl, void *dlg,
void *data, int event)
{
Config *cfg = (Config *)data;
/*
* This function works just like the standard edit box handler,
* only it has to choose the control's label and text from two
* different places depending on the protocol.
*/
if (event == EVENT_REFRESH) {
if (cfg->protocol == PROT_SERIAL) {
/*
* This label text is carefully chosen to contain an n,
* since that's the shortcut for the host name control.
*/
dlg_label_change(ctrl, dlg, "Serial line");
dlg_editbox_set(ctrl, dlg, cfg->serline);
} else {
dlg_label_change(ctrl, dlg, HOST_BOX_TITLE);
dlg_editbox_set(ctrl, dlg, cfg->host);
}
} else if (event == EVENT_VALCHANGE) {
if (cfg->protocol == PROT_SERIAL)
dlg_editbox_get(ctrl, dlg, cfg->serline, lenof(cfg->serline));
else
dlg_editbox_get(ctrl, dlg, cfg->host, lenof(cfg->host));
}
}
static void config_port_handler(union control *ctrl, void *dlg,
void *data, int event)
{
Config *cfg = (Config *)data;
char buf[80];
/*
* This function works just like the standard edit box handler,
* only it has to choose the control's label and text from two
* different places depending on the protocol.
*/
if (event == EVENT_REFRESH) {
if (cfg->protocol == PROT_SERIAL) {
/*
* This label text is carefully chosen to contain a p,
* since that's the shortcut for the port control.
*/
dlg_label_change(ctrl, dlg, "Speed");
sprintf(buf, "%d", cfg->serspeed);
} else {
dlg_label_change(ctrl, dlg, PORT_BOX_TITLE);
sprintf(buf, "%d", cfg->port);
}
dlg_editbox_set(ctrl, dlg, buf);
} else if (event == EVENT_VALCHANGE) {
dlg_editbox_get(ctrl, dlg, buf, lenof(buf));
if (cfg->protocol == PROT_SERIAL)
cfg->serspeed = atoi(buf);
else
cfg->port = atoi(buf);
}
}
struct hostport {
union control *host, *port;
};
/*
* We export this function so that platform-specific config
* routines can use it to conveniently identify the protocol radio
* buttons in order to add to them.
*/
void config_protocolbuttons_handler(union control *ctrl, void *dlg,
void *data, int event)
{
int button, defport;
Config *cfg = (Config *)data;
struct hostport *hp = (struct hostport *)ctrl->radio.context.p;
/*
* This function works just like the standard radio-button
* handler, except that it also has to change the setting of
* the port box. We expect the context parameter to point at
* the `union control' structure for the port box.
* the port box, and refresh both host and port boxes when. We
* expect the context parameter to point at a hostport
* structure giving the `union control's for both.
*/
if (event == EVENT_REFRESH) {
for (button = 0; button < ctrl->radio.nbuttons; button++)
@ -44,9 +122,10 @@ static void protocolbuttons_handler(union control *ctrl, void *dlg,
}
if (defport > 0 && cfg->port != defport) {
cfg->port = defport;
dlg_refresh((union control *)ctrl->radio.context.p, dlg);
}
}
dlg_refresh(hp->host, dlg);
dlg_refresh(hp->port, dlg);
}
}
@ -382,7 +461,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
* contains a hostname.
*/
if (load_selected_session(ssd, savedsession, dlg, cfg) &&
(ctrl == ssd->listbox && cfg->host[0])) {
(ctrl == ssd->listbox && cfg_launchable(cfg))) {
dlg_end(dlg, 1); /* it's all over, and succeeded */
}
} else if (ctrl == ssd->savebutton) {
@ -437,7 +516,8 @@ 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(ctrl, dlg) == ssd->listbox && !*cfg->host) {
if (dlg_last_focused(ctrl, dlg) == ssd->listbox &&
!cfg_launchable(cfg)) {
Config cfg2;
if (!load_selected_session(ssd, savedsession, dlg, &cfg2)) {
dlg_beep(dlg);
@ -457,7 +537,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
* Otherwise, do the normal thing: if we have a valid
* session, get going.
*/
if (*cfg->host) {
if (cfg_launchable(cfg)) {
dlg_end(dlg, 1);
} else
dlg_beep(dlg);
@ -977,31 +1057,43 @@ void setup_config_box(struct controlbox *b, int midsession,
sfree(str);
if (!midsession) {
struct hostport *hp = (struct hostport *)
ctrl_alloc(b, sizeof(struct hostport));
int i, gotssh;
s = ctrl_getset(b, "Session", "hostport",
"Specify your connection by host name or IP address");
"Specify the destination you want to connect to");
ctrl_columns(s, 2, 75, 25);
c = ctrl_editbox(s, "Host Name (or IP address)", 'n', 100,
c = ctrl_editbox(s, HOST_BOX_TITLE, 'n', 100,
HELPCTX(session_hostname),
dlg_stdeditbox_handler, I(offsetof(Config,host)),
I(sizeof(((Config *)0)->host)));
config_host_handler, I(0), I(0));
c->generic.column = 0;
c = ctrl_editbox(s, "Port", 'p', 100, HELPCTX(session_hostname),
dlg_stdeditbox_handler,
I(offsetof(Config,port)), I(-1));
hp->host = c;
c = ctrl_editbox(s, PORT_BOX_TITLE, 'p', 100,
HELPCTX(session_hostname),
config_port_handler, I(0), I(0));
c->generic.column = 1;
hp->port = c;
ctrl_columns(s, 1, 100);
if (backends[3].name == NULL) {
ctrl_radiobuttons(s, "Protocol:", NO_SHORTCUT, 3,
gotssh = FALSE;
for (i = 0; backends[i].name; i++)
if (backends[i].protocol == PROT_SSH) {
gotssh = TRUE;
break;
}
if (!gotssh) {
ctrl_radiobuttons(s, "Connection type:", NO_SHORTCUT, 3,
HELPCTX(session_hostname),
protocolbuttons_handler, P(c),
config_protocolbuttons_handler, P(hp),
"Raw", 'r', I(PROT_RAW),
"Telnet", 't', I(PROT_TELNET),
"Rlogin", 'i', I(PROT_RLOGIN),
NULL);
} else {
ctrl_radiobuttons(s, "Protocol:", NO_SHORTCUT, 4,
ctrl_radiobuttons(s, "Connection type:", NO_SHORTCUT, 4,
HELPCTX(session_hostname),
protocolbuttons_handler, P(c),
config_protocolbuttons_handler, P(hp),
"Raw", 'r', I(PROT_RAW),
"Telnet", 't', I(PROT_TELNET),
"Rlogin", 'i', I(PROT_RLOGIN),