OSDN Git Service

Add feature to export host settings as FileZilla XML format.
[ffftp/ffftp.git] / putty / 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 mask = ctrl->listbox.context.i;\r
33     int i, j;\r
34     Conf *conf = (Conf *)data;\r
35 \r
36     if (event == EVENT_REFRESH) {\r
37         /* Fetching this once at the start of the function ensures we\r
38          * remember what the right value is supposed to be when\r
39          * operations below cause reentrant calls to this function. */\r
40         int oldparity = conf_get_int(conf, CONF_serparity);\r
41 \r
42         dlg_update_start(ctrl, dlg);\r
43         dlg_listbox_clear(ctrl, dlg);\r
44         for (i = 0; i < lenof(parities); i++)  {\r
45             if (mask & (1 << i))\r
46                 dlg_listbox_addwithid(ctrl, dlg, parities[i].name,\r
47                                       parities[i].val);\r
48         }\r
49         for (i = j = 0; i < lenof(parities); i++) {\r
50             if (mask & (1 << i)) {\r
51                 if (oldparity == parities[i].val) {\r
52                     dlg_listbox_select(ctrl, dlg, j);\r
53                     break;\r
54                 }\r
55                 j++;\r
56             }\r
57         }\r
58         if (i == lenof(parities)) {    /* an unsupported setting was chosen */\r
59             dlg_listbox_select(ctrl, dlg, 0);\r
60             oldparity = SER_PAR_NONE;\r
61         }\r
62         dlg_update_done(ctrl, dlg);\r
63         conf_set_int(conf, CONF_serparity, oldparity);    /* restore */\r
64     } else if (event == EVENT_SELCHANGE) {\r
65         int i = dlg_listbox_index(ctrl, dlg);\r
66         if (i < 0)\r
67             i = SER_PAR_NONE;\r
68         else\r
69             i = dlg_listbox_getid(ctrl, dlg, i);\r
70         conf_set_int(conf, CONF_serparity, i);\r
71     }\r
72 }\r
73 \r
74 static void serial_flow_handler(union control *ctrl, void *dlg,\r
75                                 void *data, int event)\r
76 {\r
77     static const struct {\r
78         const char *name;\r
79         int val;\r
80     } flows[] = {\r
81         {"None", SER_FLOW_NONE},\r
82         {"XON/XOFF", SER_FLOW_XONXOFF},\r
83         {"RTS/CTS", SER_FLOW_RTSCTS},\r
84         {"DSR/DTR", SER_FLOW_DSRDTR},\r
85     };\r
86     int mask = ctrl->listbox.context.i;\r
87     int i, j;\r
88     Conf *conf = (Conf *)data;\r
89 \r
90     if (event == EVENT_REFRESH) {\r
91         /* Fetching this once at the start of the function ensures we\r
92          * remember what the right value is supposed to be when\r
93          * operations below cause reentrant calls to this function. */\r
94         int oldflow = conf_get_int(conf, CONF_serflow);\r
95 \r
96         dlg_update_start(ctrl, dlg);\r
97         dlg_listbox_clear(ctrl, dlg);\r
98         for (i = 0; i < lenof(flows); i++)  {\r
99             if (mask & (1 << i))\r
100                 dlg_listbox_addwithid(ctrl, dlg, flows[i].name, flows[i].val);\r
101         }\r
102         for (i = j = 0; i < lenof(flows); i++) {\r
103             if (mask & (1 << i)) {\r
104                 if (oldflow == flows[i].val) {\r
105                     dlg_listbox_select(ctrl, dlg, j);\r
106                     break;\r
107                 }\r
108                 j++;\r
109             }\r
110         }\r
111         if (i == lenof(flows)) {       /* an unsupported setting was chosen */\r
112             dlg_listbox_select(ctrl, dlg, 0);\r
113             oldflow = SER_FLOW_NONE;\r
114         }\r
115         dlg_update_done(ctrl, dlg);\r
116         conf_set_int(conf, CONF_serflow, oldflow);/* restore */\r
117     } else if (event == EVENT_SELCHANGE) {\r
118         int i = dlg_listbox_index(ctrl, dlg);\r
119         if (i < 0)\r
120             i = SER_FLOW_NONE;\r
121         else\r
122             i = dlg_listbox_getid(ctrl, dlg, i);\r
123         conf_set_int(conf, CONF_serflow, i);\r
124     }\r
125 }\r
126 \r
127 void ser_setup_config_box(struct controlbox *b, int midsession,\r
128                           int parity_mask, int flow_mask)\r
129 {\r
130     struct controlset *s;\r
131     union control *c;\r
132 \r
133     if (!midsession) {\r
134         int i;\r
135         extern void config_protocolbuttons_handler(union control *, void *,\r
136                                                    void *, int);\r
137 \r
138         /*\r
139          * Add the serial back end to the protocols list at the\r
140          * top of the config box.\r
141          */\r
142         s = ctrl_getset(b, "Session", "hostport",\r
143                         "Specify the destination you want to connect to");\r
144 \r
145         for (i = 0; i < s->ncontrols; i++) {\r
146             c = s->ctrls[i];\r
147             if (c->generic.type == CTRL_RADIO &&\r
148                 c->generic.handler == config_protocolbuttons_handler) {\r
149                 c->radio.nbuttons++;\r
150                 c->radio.ncolumns++;\r
151                 c->radio.buttons =\r
152                     sresize(c->radio.buttons, c->radio.nbuttons, char *);\r
153                 c->radio.buttons[c->radio.nbuttons-1] =\r
154                     dupstr("Serial");\r
155                 c->radio.buttondata =\r
156                     sresize(c->radio.buttondata, c->radio.nbuttons, intorptr);\r
157                 c->radio.buttondata[c->radio.nbuttons-1] = I(PROT_SERIAL);\r
158                 if (c->radio.shortcuts) {\r
159                     c->radio.shortcuts =\r
160                         sresize(c->radio.shortcuts, c->radio.nbuttons, char);\r
161                     c->radio.shortcuts[c->radio.nbuttons-1] = 'r';\r
162                 }\r
163             }\r
164         }\r
165     }\r
166 \r
167     /*\r
168      * Entirely new Connection/Serial panel for serial port\r
169      * configuration.\r
170      */\r
171     ctrl_settitle(b, "Connection/Serial",\r
172                   "Options controlling local serial lines");\r
173 \r
174     if (!midsession) {\r
175         /*\r
176          * We don't permit switching to a different serial port in\r
177          * midflight, although we do allow all other\r
178          * reconfiguration.\r
179          */\r
180         s = ctrl_getset(b, "Connection/Serial", "serline",\r
181                         "Select a serial line");\r
182         ctrl_editbox(s, "Serial line to connect to", 'l', 40,\r
183                      HELPCTX(serial_line),\r
184                      conf_editbox_handler, I(CONF_serline), I(1));\r
185     }\r
186 \r
187     s = ctrl_getset(b, "Connection/Serial", "sercfg", "Configure the serial line");\r
188     ctrl_editbox(s, "Speed (baud)", 's', 40,\r
189                  HELPCTX(serial_speed),\r
190                  conf_editbox_handler, I(CONF_serspeed), I(-1));\r
191     ctrl_editbox(s, "Data bits", 'b', 40,\r
192                  HELPCTX(serial_databits),\r
193                  conf_editbox_handler, I(CONF_serdatabits), I(-1));\r
194     /*\r
195      * Stop bits come in units of one half.\r
196      */\r
197     ctrl_editbox(s, "Stop bits", 't', 40,\r
198                  HELPCTX(serial_stopbits),\r
199                  conf_editbox_handler, I(CONF_serstopbits), I(-2));\r
200     ctrl_droplist(s, "Parity", 'p', 40,\r
201                   HELPCTX(serial_parity),\r
202                   serial_parity_handler, I(parity_mask));\r
203     ctrl_droplist(s, "Flow control", 'f', 40,\r
204                   HELPCTX(serial_flow),\r
205                   serial_flow_handler, I(flow_mask));\r
206 }\r