fe8abbf4 |
1 | /* |
2 | * wincfg.c - the Windows-specific parts of the PuTTY configuration |
3 | * box. |
4 | */ |
5 | |
6 | #include <windows.h> |
7 | |
8 | #include <assert.h> |
9 | #include <stdlib.h> |
10 | |
11 | #include "putty.h" |
12 | #include "dialog.h" |
13 | #include "storage.h" |
14 | |
15 | static void about_handler(union control *ctrl, void *dlg, |
16 | void *data, int event) |
17 | { |
18 | HWND *hwndp = (HWND *)ctrl->generic.context.p; |
19 | |
20 | if (event == EVENT_ACTION) { |
21 | modal_about_box(*hwndp); |
22 | } |
23 | } |
24 | |
25 | static void help_handler(union control *ctrl, void *dlg, |
26 | void *data, int event) |
27 | { |
28 | HWND *hwndp = (HWND *)ctrl->generic.context.p; |
29 | |
30 | if (event == EVENT_ACTION) { |
31 | show_help(*hwndp); |
32 | } |
33 | } |
34 | |
35 | void win_setup_config_box(struct controlbox *b, HWND *hwndp, int has_help, |
36 | int midsession) |
37 | { |
38 | struct controlset *s; |
39 | union control *c; |
40 | |
41 | if (!midsession) { |
42 | /* |
43 | * Add the About and Help buttons to the standard panel. |
44 | */ |
45 | s = ctrl_getset(b, "", "", ""); |
46 | c = ctrl_pushbutton(s, "About", 'a', HELPCTX(no_help), |
47 | about_handler, P(hwndp)); |
48 | c->generic.column = 0; |
49 | if (has_help) { |
50 | c = ctrl_pushbutton(s, "Help", 'h', HELPCTX(no_help), |
51 | help_handler, P(hwndp)); |
52 | c->generic.column = 1; |
53 | } |
54 | } |
55 | |
56 | /* |
57 | * Windows has the AltGr key, which has various Windows- |
58 | * specific options. |
59 | */ |
60 | s = ctrl_getset(b, "Terminal/Keyboard", "features", |
61 | "Enable extra keyboard features:"); |
62 | ctrl_checkbox(s, "AltGr acts as Compose key", 't', |
63 | HELPCTX(keyboard_compose), |
64 | dlg_stdcheckbox_handler, I(offsetof(Config,compose_key))); |
65 | ctrl_checkbox(s, "Control-Alt is different from AltGr", 'd', |
66 | HELPCTX(keyboard_ctrlalt), |
67 | dlg_stdcheckbox_handler, I(offsetof(Config,ctrlaltkeys))); |
68 | |
69 | /* |
70 | * Windows allows an arbitrary .WAV to be played as a bell. For |
71 | * this we must search the existing controlset for the |
72 | * radio-button set controlling the `beep' option, and add an |
73 | * extra button to it. |
74 | * |
75 | * Note that although this _looks_ like a hideous hack, it's |
76 | * actually all above board. The well-defined interface to the |
77 | * per-platform dialog box code is the _data structures_ `union |
78 | * control', `struct controlset' and so on; so code like this |
79 | * that reaches into those data structures and changes bits of |
80 | * them is perfectly legitimate and crosses no boundaries. All |
81 | * the ctrl_* routines that create most of the controls are |
82 | * convenient shortcuts provided on the cross-platform side of |
83 | * the interface, and template creation code is under no actual |
84 | * obligation to use them. |
85 | */ |
86 | s = ctrl_getset(b, "Terminal/Bell", "style", "Set the style of bell"); |
87 | { |
88 | int i; |
89 | for (i = 0; i < s->ncontrols; i++) { |
90 | c = s->ctrls[i]; |
91 | if (c->generic.type == CTRL_RADIO && |
92 | c->generic.context.i == offsetof(Config, beep)) { |
93 | assert(c->generic.handler == dlg_stdradiobutton_handler); |
94 | c->radio.nbuttons++; |
95 | c->radio.buttons = |
96 | srealloc(c->radio.buttons, |
97 | c->radio.nbuttons * sizeof(*c->radio.buttons)); |
98 | c->radio.buttons[c->radio.nbuttons-1] = |
99 | dupstr("Play a custom sound file"); |
100 | c->radio.buttondata = |
101 | srealloc(c->radio.buttondata, |
102 | c->radio.nbuttons * sizeof(*c->radio.buttondata)); |
103 | c->radio.buttondata[c->radio.nbuttons-1] = I(BELL_WAVEFILE); |
104 | if (c->radio.shortcuts) { |
105 | c->radio.shortcuts = |
106 | srealloc(c->radio.shortcuts, |
107 | (c->radio.nbuttons * |
108 | sizeof(*c->radio.shortcuts))); |
109 | c->radio.shortcuts[c->radio.nbuttons-1] = NO_SHORTCUT; |
110 | } |
111 | break; |
112 | } |
113 | } |
114 | } |
115 | ctrl_filesel(s, "Custom sound file to play as a bell:", NO_SHORTCUT, |
116 | FILTER_WAVE_FILES, FALSE, "Select bell sound file", |
117 | HELPCTX(bell_style), |
118 | dlg_stdfilesel_handler, I(offsetof(Config, bell_wavefile))); |
119 | |
120 | /* |
121 | * While we've got this box open, taskbar flashing on a bell is |
122 | * also Windows-specific. |
123 | */ |
124 | ctrl_radiobuttons(s, "Taskbar/caption indication on bell:", 'i', 3, |
125 | HELPCTX(bell_taskbar), |
126 | dlg_stdradiobutton_handler, |
127 | I(offsetof(Config, beep_ind)), |
128 | "Disabled", I(B_IND_DISABLED), |
129 | "Flashing", I(B_IND_FLASH), |
130 | "Steady", I(B_IND_STEADY), NULL); |
131 | |
132 | /* |
133 | * The sunken-edge border is a Windows GUI feature. |
134 | */ |
135 | s = ctrl_getset(b, "Window/Appearance", "border", |
136 | "Adjust the window border"); |
137 | ctrl_checkbox(s, "Sunken-edge border (slightly thicker)", 's', |
138 | HELPCTX(appearance_border), |
139 | dlg_stdcheckbox_handler, I(offsetof(Config,sunken_edge))); |
140 | |
141 | /* |
142 | * Cyrillic Lock is a horrid misfeature even on Windows, and |
143 | * the least we can do is ensure it never makes it to any other |
144 | * platform (at least unless someone fixes it!). |
145 | */ |
146 | s = ctrl_getset(b, "Window/Translation", "input", |
147 | "Enable character set translation on input data"); |
148 | ctrl_checkbox(s, "Caps Lock acts as Cyrillic switch", 's', |
149 | HELPCTX(translation_cyrillic), |
150 | dlg_stdcheckbox_handler, |
151 | I(offsetof(Config,xlat_capslockcyr))); |
152 | |
153 | /* |
154 | * Windows has the weird OEM font mode, which gives us some |
155 | * additional options when working with line-drawing |
156 | * characters. |
157 | */ |
158 | s = ctrl_getset(b, "Window/Translation", "linedraw", |
159 | "Adjust how PuTTY displays line drawing characters"); |
160 | { |
161 | int i; |
162 | for (i = 0; i < s->ncontrols; i++) { |
163 | c = s->ctrls[i]; |
164 | if (c->generic.type == CTRL_RADIO && |
165 | c->generic.context.i == offsetof(Config, vtmode)) { |
166 | assert(c->generic.handler == dlg_stdradiobutton_handler); |
167 | c->radio.nbuttons += 2; |
168 | c->radio.buttons = |
169 | srealloc(c->radio.buttons, |
170 | c->radio.nbuttons * sizeof(*c->radio.buttons)); |
171 | c->radio.buttons[c->radio.nbuttons-2] = |
172 | dupstr("Use font in both ANSI and OEM modes"); |
173 | c->radio.buttons[c->radio.nbuttons-1] = |
174 | dupstr("Use font in OEM mode only"); |
175 | c->radio.buttondata = |
176 | srealloc(c->radio.buttondata, |
177 | c->radio.nbuttons * sizeof(*c->radio.buttondata)); |
178 | c->radio.buttondata[c->radio.nbuttons-2] = I(VT_OEMANSI); |
179 | c->radio.buttondata[c->radio.nbuttons-1] = I(VT_OEMONLY); |
180 | if (!c->radio.shortcuts) { |
181 | int j; |
182 | c->radio.shortcuts = |
183 | smalloc((c->radio.nbuttons * |
184 | sizeof(*c->radio.shortcuts))); |
185 | for (j = 0; j < c->radio.nbuttons; j++) |
186 | c->radio.shortcuts[j] = NO_SHORTCUT; |
187 | } else { |
188 | c->radio.shortcuts = |
189 | srealloc(c->radio.shortcuts, |
190 | (c->radio.nbuttons * |
191 | sizeof(*c->radio.shortcuts))); |
192 | } |
193 | c->radio.shortcuts[c->radio.nbuttons-2] = 'b'; |
194 | c->radio.shortcuts[c->radio.nbuttons-1] = 'e'; |
195 | break; |
196 | } |
197 | } |
198 | } |
199 | |
200 | /* |
201 | * RTF paste is Windows-specific. |
202 | */ |
203 | s = ctrl_getset(b, "Window/Selection", "trans", |
204 | "Translation of pasted characters"); |
205 | ctrl_checkbox(s, "Paste to clipboard in RTF as well as plain text", 'f', |
206 | HELPCTX(selection_rtf), |
207 | dlg_stdcheckbox_handler, I(offsetof(Config,rtf_paste))); |
208 | |
209 | /* |
210 | * Windows often has no middle button, so we supply a selection |
211 | * mode in which the more critical Paste action is available on |
212 | * the right button instead. |
213 | */ |
214 | s = ctrl_getset(b, "Window/Selection", "mouse", |
215 | "Control use of mouse"); |
216 | ctrl_radiobuttons(s, "Action of mouse buttons:", NO_SHORTCUT, 1, |
217 | HELPCTX(selection_buttons), |
218 | dlg_stdradiobutton_handler, |
219 | I(offsetof(Config, mouse_is_xterm)), |
220 | "Windows (Right pastes, Middle extends)", 'w', I(0), |
221 | "xterm (Right extends, Middle pastes)", 'x', I(1), NULL); |
222 | /* |
223 | * This really ought to go at the _top_ of its box, not the |
224 | * bottom, so we'll just do some shuffling now we've set it |
225 | * up... |
226 | */ |
227 | c = s->ctrls[s->ncontrols-1]; /* this should be the new control */ |
228 | memmove(s->ctrls+1, s->ctrls, (s->ncontrols-1)*sizeof(union control *)); |
229 | s->ctrls[0] = c; |
230 | |
231 | /* |
232 | * Logical palettes don't even make sense anywhere except Windows. |
233 | */ |
234 | s = ctrl_getset(b, "Window/Colours", "general", |
235 | "General options for colour usage"); |
236 | ctrl_checkbox(s, "Attempt to use logical palettes", 'l', |
237 | HELPCTX(colours_logpal), |
238 | dlg_stdcheckbox_handler, I(offsetof(Config,try_palette))); |
239 | |
240 | /* |
241 | * Resize-by-changing-font is a Windows insanity. |
242 | */ |
243 | s = ctrl_getset(b, "Window", "size", "Set the size of the window"); |
244 | ctrl_radiobuttons(s, "When window is resized:", 'z', 1, |
245 | HELPCTX(window_resize), |
246 | dlg_stdradiobutton_handler, |
247 | I(offsetof(Config, resize_action)), |
248 | "Change the number of rows and columns", I(RESIZE_TERM), |
249 | "Change the size of the font", I(RESIZE_FONT), |
250 | "Change font size only when maximised", I(RESIZE_EITHER), |
251 | "Forbid resizing completely", I(RESIZE_DISABLED), NULL); |
252 | |
253 | /* |
254 | * Most of the Window/Behaviour stuff is there to mimic Windows |
255 | * conventions which PuTTY can optionally disregard. Hence, |
256 | * most of these options are Windows-specific. |
257 | */ |
258 | s = ctrl_getset(b, "Window/Behaviour", "main", NULL); |
259 | ctrl_checkbox(s, "Window closes on ALT-F4", '4', |
260 | HELPCTX(behaviour_altf4), |
261 | dlg_stdcheckbox_handler, I(offsetof(Config,alt_f4))); |
262 | ctrl_checkbox(s, "System menu appears on ALT-Space", 'y', |
263 | HELPCTX(behaviour_altspace), |
264 | dlg_stdcheckbox_handler, I(offsetof(Config,alt_space))); |
265 | ctrl_checkbox(s, "System menu appears on ALT alone", 'l', |
266 | HELPCTX(behaviour_altonly), |
267 | dlg_stdcheckbox_handler, I(offsetof(Config,alt_only))); |
268 | ctrl_checkbox(s, "Ensure window is always on top", 'e', |
269 | HELPCTX(behaviour_alwaysontop), |
270 | dlg_stdcheckbox_handler, I(offsetof(Config,alwaysontop))); |
271 | ctrl_checkbox(s, "Full screen on Alt-Enter", 'f', |
272 | HELPCTX(behaviour_altenter), |
273 | dlg_stdcheckbox_handler, |
274 | I(offsetof(Config,fullscreenonaltenter))); |
275 | } |