]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sercfg.c
Support for Windows PuTTY connecting straight to a local serial port
[PuTTY.git] / sercfg.c
1 /*\r
2  * sercfg.c - the serial-port specific parts of the PuTTY\r
3  * configuration box. Centralised as cross-platform code because\r
4  * more than one platform will want to use it, but not part of the\r
5  * main configuration. The expectation is that each platform's\r
6  * local config function will call out to ser_setup_config_box() if\r
7  * it needs to set up the standard serial stuff. (Of course, it can\r
8  * then apply local tweaks after ser_setup_config_box() returns, if\r
9  * it needs to.)\r
10  */\r
11 \r
12 #include <assert.h>\r
13 #include <stdlib.h>\r
14 \r
15 #include "putty.h"\r
16 #include "dialog.h"\r
17 #include "storage.h"\r
18 \r
19 static void serial_parity_handler(union control *ctrl, void *dlg,\r
20                                   void *data, int event)\r
21 {\r
22     static const struct {\r
23         const char *name;\r
24         int val;\r
25     } parities[] = {\r
26         {"None", SER_PAR_NONE},\r
27         {"Odd", SER_PAR_ODD},\r
28         {"Even", SER_PAR_EVEN},\r
29         {"Mark", SER_PAR_MARK},\r
30         {"Space", SER_PAR_SPACE},\r
31     };\r
32     int i;\r
33     Config *cfg = (Config *)data;\r
34 \r
35     if (event == EVENT_REFRESH) {\r
36         dlg_update_start(ctrl, dlg);\r
37         dlg_listbox_clear(ctrl, dlg);\r
38         for (i = 0; i < lenof(parities); i++)\r
39             dlg_listbox_addwithid(ctrl, dlg, parities[i].name,\r
40                                   parities[i].val);\r
41         for (i = 0; i < lenof(parities); i++)\r
42             if (cfg->serparity == parities[i].val)\r
43                 dlg_listbox_select(ctrl, dlg, i);\r
44         dlg_update_done(ctrl, dlg);\r
45     } else if (event == EVENT_SELCHANGE) {\r
46         int i = dlg_listbox_index(ctrl, dlg);\r
47         if (i < 0)\r
48             i = SER_PAR_NONE;\r
49         else\r
50             i = dlg_listbox_getid(ctrl, dlg, i);\r
51         cfg->serparity = i;\r
52     }\r
53 }\r
54 \r
55 static void serial_flow_handler(union control *ctrl, void *dlg,\r
56                                 void *data, int event)\r
57 {\r
58     static const struct {\r
59         const char *name;\r
60         int val;\r
61     } flows[] = {\r
62         {"None", SER_FLOW_NONE},\r
63         {"XON/XOFF", SER_FLOW_XONXOFF},\r
64         {"RTS/CTS", SER_FLOW_RTSCTS},\r
65         {"DSR/DTR", SER_FLOW_DSRDTR},\r
66     };\r
67     int i;\r
68     Config *cfg = (Config *)data;\r
69 \r
70     if (event == EVENT_REFRESH) {\r
71         dlg_update_start(ctrl, dlg);\r
72         dlg_listbox_clear(ctrl, dlg);\r
73         for (i = 0; i < lenof(flows); i++)\r
74             dlg_listbox_addwithid(ctrl, dlg, flows[i].name,\r
75                                   flows[i].val);\r
76         for (i = 0; i < lenof(flows); i++)\r
77             if (cfg->serflow == flows[i].val)\r
78                 dlg_listbox_select(ctrl, dlg, i);\r
79         dlg_update_done(ctrl, dlg);\r
80     } else if (event == EVENT_SELCHANGE) {\r
81         int i = dlg_listbox_index(ctrl, dlg);\r
82         if (i < 0)\r
83             i = SER_PAR_NONE;\r
84         else\r
85             i = dlg_listbox_getid(ctrl, dlg, i);\r
86         cfg->serflow = i;\r
87     }\r
88 }\r
89 \r
90 void ser_setup_config_box(struct controlbox *b, int midsession)\r
91 {\r
92     struct controlset *s;\r
93     union control *c;\r
94 \r
95     /*\r
96      * Add the serial back end to the protocols list at the top of\r
97      * the config box.\r
98      */\r
99     s = ctrl_getset(b, "Session", "hostport",\r
100                     "Specify your connection by host name or IP address");\r
101     {\r
102         int i;\r
103         extern void config_protocolbuttons_handler(union control *, void *,\r
104                                                    void *, int);\r
105         for (i = 0; i < s->ncontrols; i++) {\r
106             c = s->ctrls[i];\r
107             if (c->generic.type == CTRL_RADIO &&\r
108                 c->generic.handler == config_protocolbuttons_handler) {\r
109                 c->radio.nbuttons++;\r
110                 c->radio.ncolumns++;\r
111                 c->radio.buttons =\r
112                     sresize(c->radio.buttons, c->radio.nbuttons, char *);\r
113                 c->radio.buttons[c->radio.nbuttons-1] =\r
114                     dupstr("Serial");\r
115                 c->radio.buttondata =\r
116                     sresize(c->radio.buttondata, c->radio.nbuttons, intorptr);\r
117                 c->radio.buttondata[c->radio.nbuttons-1] = I(PROT_SERIAL);\r
118                 if (c->radio.shortcuts) {\r
119                     c->radio.shortcuts =\r
120                         sresize(c->radio.shortcuts, c->radio.nbuttons, char);\r
121                     c->radio.shortcuts[c->radio.nbuttons-1] = NO_SHORTCUT;\r
122                 }\r
123             }\r
124         }\r
125     }\r
126 \r
127     /*\r
128      * Entirely new Connection/Serial panel for serial port\r
129      * configuration.\r
130      */\r
131     ctrl_settitle(b, "Connection/Serial",\r
132                   "Options controlling local serial lines");\r
133 \r
134     if (!midsession) {\r
135         /*\r
136          * We don't permit switching to a different serial port in\r
137          * midflight, although we do allow all other\r
138          * reconfiguration.\r
139          */\r
140         s = ctrl_getset(b, "Connection/Serial", "serline",\r
141                         "Select a serial line");\r
142         ctrl_editbox(s, "Serial line to connect to", 'l', 40,\r
143                      HELPCTX(serial_line),\r
144                      dlg_stdeditbox_handler, I(offsetof(Config,serline)),\r
145                      I(sizeof(((Config *)0)->serline)));\r
146     }\r
147 \r
148     s = ctrl_getset(b, "Connection/Serial", "sercfg", "Configure the serial line");\r
149     ctrl_editbox(s, "Speed (baud)", 's', 40,\r
150                  HELPCTX(serial_speed),\r
151                  dlg_stdeditbox_handler, I(offsetof(Config,serspeed)), I(-1));\r
152     ctrl_editbox(s, "Data bits", 'b', 40,\r
153                  HELPCTX(serial_databits),\r
154                  dlg_stdeditbox_handler,I(offsetof(Config,serdatabits)),I(-1));\r
155     /*\r
156      * Stop bits come in units of one half.\r
157      */\r
158     ctrl_editbox(s, "Stop bits", 't', 40,\r
159                  HELPCTX(serial_stopbits),\r
160                  dlg_stdeditbox_handler,I(offsetof(Config,serstopbits)),I(-2));\r
161     ctrl_droplist(s, "Parity", 'p', 40,\r
162                   HELPCTX(serial_parity),\r
163                   serial_parity_handler, I(0));\r
164     ctrl_droplist(s, "Flow control", 'f', 40,\r
165                   HELPCTX(serial_flow),\r
166                   serial_flow_handler, I(0));\r
167 }\r