Run entire source base through GNU indent to tidy up the varying
[u/mdw/putty] / windlg.c
1 #include <windows.h>
2 #include <commctrl.h>
3 #include <commdlg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <ctype.h>
7 #include <time.h>
8
9 #include "ssh.h"
10 #include "putty.h"
11 #include "winstuff.h"
12 #include "win_res.h"
13 #include "storage.h"
14
15 static char **events = NULL;
16 static int nevents = 0, negsize = 0;
17
18 static int readytogo;
19
20 void force_normal(HWND hwnd)
21 {
22 static int recurse = 0;
23
24 WINDOWPLACEMENT wp;
25
26 if (recurse)
27 return;
28 recurse = 1;
29
30 wp.length = sizeof(wp);
31 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
34 }
35 recurse = 0;
36 }
37
38 static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
39 {
40 BOOL ok;
41 int n;
42 n = GetDlgItemInt(hwnd, id, &ok, FALSE);
43 if (ok)
44 *result = n;
45 }
46
47 static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
48 {
49 char text[80];
50 BOOL ok;
51 ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
52 if (ok && text[0])
53 *result = (int) (scale * atof(text));
54 }
55
56 static void MySetDlgItemFlt(HWND hwnd, int id, double value)
57 {
58 char text[80];
59 sprintf(text, "%g", value);
60 SetDlgItemText(hwnd, id, text);
61 }
62
63 static int CALLBACK LogProc(HWND hwnd, UINT msg,
64 WPARAM wParam, LPARAM lParam)
65 {
66 int i;
67
68 switch (msg) {
69 case WM_INITDIALOG:
70 {
71 static int tabs[4] = { 78, 108 };
72 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
73 (LPARAM) tabs);
74 }
75 for (i = 0; i < nevents; i++)
76 SendDlgItemMessage(hwnd, IDN_LIST, LB_ADDSTRING,
77 0, (LPARAM) events[i]);
78 return 1;
79 case WM_COMMAND:
80 switch (LOWORD(wParam)) {
81 case IDOK:
82 case IDCANCEL:
83 logbox = NULL;
84 SetActiveWindow(GetParent(hwnd));
85 DestroyWindow(hwnd);
86 return 0;
87 case IDN_COPY:
88 if (HIWORD(wParam) == BN_CLICKED ||
89 HIWORD(wParam) == BN_DOUBLECLICKED) {
90 int selcount;
91 int *selitems;
92 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
93 LB_GETSELCOUNT, 0, 0);
94 if (selcount == 0) { /* don't even try to copy zero items */
95 MessageBeep(0);
96 break;
97 }
98
99 selitems = smalloc(selcount * sizeof(int));
100 if (selitems) {
101 int count = SendDlgItemMessage(hwnd, IDN_LIST,
102 LB_GETSELITEMS,
103 selcount,
104 (LPARAM) selitems);
105 int i;
106 int size;
107 char *clipdata;
108 static unsigned char sel_nl[] = SEL_NL;
109
110 if (count == 0) { /* can't copy zero stuff */
111 MessageBeep(0);
112 break;
113 }
114
115 size = 0;
116 for (i = 0; i < count; i++)
117 size +=
118 strlen(events[selitems[i]]) + sizeof(sel_nl);
119
120 clipdata = smalloc(size);
121 if (clipdata) {
122 char *p = clipdata;
123 for (i = 0; i < count; i++) {
124 char *q = events[selitems[i]];
125 int qlen = strlen(q);
126 memcpy(p, q, qlen);
127 p += qlen;
128 memcpy(p, sel_nl, sizeof(sel_nl));
129 p += sizeof(sel_nl);
130 }
131 write_clip(clipdata, size, TRUE);
132 sfree(clipdata);
133 }
134 sfree(selitems);
135
136 for (i = 0; i < nevents; i++)
137 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
138 FALSE, i);
139 }
140 }
141 return 0;
142 }
143 return 0;
144 case WM_CLOSE:
145 logbox = NULL;
146 SetActiveWindow(GetParent(hwnd));
147 DestroyWindow(hwnd);
148 return 0;
149 }
150 return 0;
151 }
152
153 static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
154 WPARAM wParam, LPARAM lParam)
155 {
156 switch (msg) {
157 case WM_INITDIALOG:
158 return 1;
159 case WM_COMMAND:
160 switch (LOWORD(wParam)) {
161 case IDOK:
162 EndDialog(hwnd, 1);
163 return 0;
164 }
165 return 0;
166 case WM_CLOSE:
167 EndDialog(hwnd, 1);
168 return 0;
169 }
170 return 0;
171 }
172
173 static int CALLBACK AboutProc(HWND hwnd, UINT msg,
174 WPARAM wParam, LPARAM lParam)
175 {
176 switch (msg) {
177 case WM_INITDIALOG:
178 SetDlgItemText(hwnd, IDA_VERSION, ver);
179 return 1;
180 case WM_COMMAND:
181 switch (LOWORD(wParam)) {
182 case IDOK:
183 case IDCANCEL:
184 EndDialog(hwnd, TRUE);
185 return 0;
186 case IDA_LICENCE:
187 EnableWindow(hwnd, 0);
188 DialogBox(hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
189 NULL, LicenceProc);
190 EnableWindow(hwnd, 1);
191 SetActiveWindow(hwnd);
192 return 0;
193
194 case IDA_WEB:
195 /* Load web browser */
196 ShellExecute(hwnd, "open",
197 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
198 0, 0, SW_SHOWDEFAULT);
199 return 0;
200 }
201 return 0;
202 case WM_CLOSE:
203 EndDialog(hwnd, TRUE);
204 return 0;
205 }
206 return 0;
207 }
208
209 /*
210 * Null dialog procedure.
211 */
212 static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
213 WPARAM wParam, LPARAM lParam)
214 {
215 return 0;
216 }
217
218 static char savedsession[2048];
219
220 enum { IDCX_ABOUT =
221 IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
222
223 sessionpanelstart,
224 IDC_TITLE_SESSION,
225 IDC_BOX_SESSION1,
226 IDC_BOX_SESSION2,
227 IDC_BOX_SESSION3,
228 IDC_HOSTSTATIC,
229 IDC_HOST,
230 IDC_PORTSTATIC,
231 IDC_PORT,
232 IDC_PROTSTATIC,
233 IDC_PROTRAW,
234 IDC_PROTTELNET,
235 IDC_PROTRLOGIN,
236 IDC_PROTSSH,
237 IDC_SESSSTATIC,
238 IDC_SESSEDIT,
239 IDC_SESSLIST,
240 IDC_SESSLOAD,
241 IDC_SESSSAVE,
242 IDC_SESSDEL,
243 IDC_CLOSEEXIT,
244 IDC_COEALWAYS,
245 IDC_COENEVER,
246 IDC_COENORMAL,
247 sessionpanelend,
248
249 loggingpanelstart,
250 IDC_TITLE_LOGGING,
251 IDC_BOX_LOGGING1,
252 IDC_LSTATSTATIC,
253 IDC_LSTATOFF,
254 IDC_LSTATASCII,
255 IDC_LSTATRAW,
256 IDC_LGFSTATIC,
257 IDC_LGFEDIT,
258 IDC_LGFBUTTON,
259 IDC_LSTATXIST,
260 IDC_LSTATXOVR,
261 IDC_LSTATXAPN,
262 IDC_LSTATXASK,
263 loggingpanelend,
264
265 keyboardpanelstart,
266 IDC_TITLE_KEYBOARD,
267 IDC_BOX_KEYBOARD1,
268 IDC_BOX_KEYBOARD2,
269 IDC_BOX_KEYBOARD3,
270 IDC_DELSTATIC,
271 IDC_DEL008,
272 IDC_DEL127,
273 IDC_HOMESTATIC,
274 IDC_HOMETILDE,
275 IDC_HOMERXVT,
276 IDC_FUNCSTATIC,
277 IDC_FUNCTILDE,
278 IDC_FUNCLINUX,
279 IDC_FUNCXTERM,
280 IDC_FUNCVT400,
281 IDC_FUNCVT100P,
282 IDC_FUNCSCO,
283 IDC_KPSTATIC,
284 IDC_KPNORMAL,
285 IDC_KPAPPLIC,
286 IDC_KPNH,
287 IDC_NOAPPLICK,
288 IDC_NOAPPLICC,
289 IDC_CURSTATIC,
290 IDC_CURNORMAL,
291 IDC_CURAPPLIC,
292 IDC_COMPOSEKEY,
293 IDC_CTRLALTKEYS,
294 keyboardpanelend,
295
296 terminalpanelstart,
297 IDC_TITLE_TERMINAL,
298 IDC_BOX_TERMINAL1,
299 IDC_BOX_TERMINAL2,
300 IDC_WRAPMODE,
301 IDC_DECOM,
302 IDC_LFHASCR,
303 IDC_BCE,
304 IDC_BLINKTEXT,
305 IDC_ANSWERBACK,
306 IDC_ANSWEREDIT,
307 IDC_ECHOSTATIC,
308 IDC_ECHOBACKEND,
309 IDC_ECHOYES,
310 IDC_ECHONO,
311 IDC_EDITSTATIC,
312 IDC_EDITBACKEND,
313 IDC_EDITYES,
314 IDC_EDITNO,
315 terminalpanelend,
316
317 bellpanelstart,
318 IDC_TITLE_BELL,
319 IDC_BOX_BELL1,
320 IDC_BOX_BELL2,
321 IDC_BELLSTATIC,
322 IDC_BELL_DISABLED,
323 IDC_BELL_DEFAULT,
324 IDC_BELL_WAVEFILE,
325 IDC_BELL_VISUAL,
326 IDC_BELL_WAVESTATIC,
327 IDC_BELL_WAVEEDIT,
328 IDC_BELL_WAVEBROWSE,
329 IDC_BELLOVL,
330 IDC_BELLOVLNSTATIC,
331 IDC_BELLOVLN,
332 IDC_BELLOVLTSTATIC,
333 IDC_BELLOVLT,
334 IDC_BELLOVLEXPLAIN,
335 IDC_BELLOVLSSTATIC,
336 IDC_BELLOVLS,
337 bellpanelend,
338
339 windowpanelstart,
340 IDC_TITLE_WINDOW,
341 IDC_BOX_WINDOW1,
342 IDC_BOX_WINDOW2,
343 IDC_BOX_WINDOW3,
344 IDC_ROWSSTATIC,
345 IDC_ROWSEDIT,
346 IDC_COLSSTATIC,
347 IDC_COLSEDIT,
348 IDC_LOCKSIZE,
349 IDC_SCROLLBAR,
350 IDC_CLOSEWARN,
351 IDC_SAVESTATIC,
352 IDC_SAVEEDIT,
353 IDC_ALTF4,
354 IDC_ALTSPACE,
355 IDC_ALTONLY,
356 IDC_SCROLLKEY,
357 IDC_SCROLLDISP,
358 IDC_ALWAYSONTOP,
359 windowpanelend,
360
361 appearancepanelstart,
362 IDC_TITLE_APPEARANCE,
363 IDC_BOX_APPEARANCE1,
364 IDC_BOX_APPEARANCE2,
365 IDC_BOX_APPEARANCE3,
366 IDC_BOX_APPEARANCE4,
367 IDC_BOX_APPEARANCE5,
368 IDC_CURSORSTATIC,
369 IDC_CURBLOCK,
370 IDC_CURUNDER,
371 IDC_CURVERT,
372 IDC_BLINKCUR,
373 IDC_FONTSTATIC,
374 IDC_CHOOSEFONT,
375 IDC_WINTITLE,
376 IDC_WINEDIT,
377 IDC_WINNAME,
378 IDC_HIDEMOUSE,
379 IDC_SUNKENEDGE,
380 appearancepanelend,
381
382 connectionpanelstart,
383 IDC_TITLE_CONNECTION,
384 IDC_BOX_CONNECTION1,
385 IDC_BOX_CONNECTION2,
386 IDC_TTSTATIC,
387 IDC_TTEDIT,
388 IDC_LOGSTATIC,
389 IDC_LOGEDIT,
390 IDC_PINGSTATIC,
391 IDC_PINGEDIT,
392 connectionpanelend,
393
394 telnetpanelstart,
395 IDC_TITLE_TELNET,
396 IDC_BOX_TELNET1,
397 IDC_BOX_TELNET2,
398 IDC_TSSTATIC,
399 IDC_TSEDIT,
400 IDC_ENVSTATIC,
401 IDC_VARSTATIC,
402 IDC_VAREDIT,
403 IDC_VALSTATIC,
404 IDC_VALEDIT,
405 IDC_ENVLIST,
406 IDC_ENVADD,
407 IDC_ENVREMOVE,
408 IDC_EMSTATIC,
409 IDC_EMBSD,
410 IDC_EMRFC,
411 telnetpanelend,
412
413 rloginpanelstart,
414 IDC_TITLE_RLOGIN,
415 IDC_BOX_RLOGIN1,
416 IDC_BOX_RLOGIN2,
417 IDC_R_TSSTATIC,
418 IDC_R_TSEDIT,
419 IDC_RLLUSERSTATIC,
420 IDC_RLLUSEREDIT,
421 rloginpanelend,
422
423 sshpanelstart,
424 IDC_TITLE_SSH,
425 IDC_BOX_SSH1,
426 IDC_BOX_SSH2,
427 IDC_BOX_SSH3,
428 IDC_NOPTY,
429 IDC_CIPHERSTATIC,
430 IDC_CIPHER3DES,
431 IDC_CIPHERBLOWF,
432 IDC_CIPHERDES,
433 IDC_CIPHERAES,
434 IDC_BUGGYMAC,
435 IDC_AUTHTIS,
436 IDC_PKSTATIC,
437 IDC_PKEDIT,
438 IDC_PKBUTTON,
439 IDC_SSHPROTSTATIC,
440 IDC_SSHPROT1,
441 IDC_SSHPROT2,
442 IDC_AGENTFWD,
443 IDC_CMDSTATIC,
444 IDC_CMDEDIT,
445 IDC_COMPRESS,
446 sshpanelend,
447
448 selectionpanelstart,
449 IDC_TITLE_SELECTION,
450 IDC_BOX_SELECTION1,
451 IDC_BOX_SELECTION2,
452 IDC_BOX_SELECTION3,
453 IDC_MBSTATIC,
454 IDC_MBWINDOWS,
455 IDC_MBXTERM,
456 IDC_CCSTATIC,
457 IDC_CCLIST,
458 IDC_CCSET,
459 IDC_CCSTATIC2,
460 IDC_CCEDIT,
461 IDC_RAWCNP,
462 selectionpanelend,
463
464 colourspanelstart,
465 IDC_TITLE_COLOURS,
466 IDC_BOX_COLOURS1,
467 IDC_BOX_COLOURS2,
468 IDC_BOLDCOLOUR,
469 IDC_PALETTE,
470 IDC_COLOURSTATIC,
471 IDC_COLOURLIST,
472 IDC_RSTATIC,
473 IDC_GSTATIC,
474 IDC_BSTATIC,
475 IDC_RVALUE,
476 IDC_GVALUE,
477 IDC_BVALUE,
478 IDC_CHANGE,
479 colourspanelend,
480
481 translationpanelstart,
482 IDC_TITLE_TRANSLATION,
483 IDC_BOX_TRANSLATION1,
484 IDC_BOX_TRANSLATION2,
485 IDC_BOX_TRANSLATION3,
486 IDC_XLATSTATIC,
487 IDC_NOXLAT,
488 IDC_KOI8WIN1251,
489 IDC_88592WIN1250,
490 IDC_88592CP852,
491 IDC_CAPSLOCKCYR,
492 IDC_VTSTATIC,
493 IDC_VTXWINDOWS,
494 IDC_VTOEMANSI,
495 IDC_VTOEMONLY,
496 IDC_VTPOORMAN,
497 translationpanelend,
498
499 tunnelspanelstart,
500 IDC_TITLE_TUNNELS,
501 IDC_BOX_TUNNELS,
502 IDC_X11_FORWARD,
503 IDC_X11_DISPSTATIC,
504 IDC_X11_DISPLAY,
505 tunnelspanelend,
506
507 controlendvalue
508 };
509
510 static const char *const colours[] = {
511 "Default Foreground", "Default Bold Foreground",
512 "Default Background", "Default Bold Background",
513 "Cursor Text", "Cursor Colour",
514 "ANSI Black", "ANSI Black Bold",
515 "ANSI Red", "ANSI Red Bold",
516 "ANSI Green", "ANSI Green Bold",
517 "ANSI Yellow", "ANSI Yellow Bold",
518 "ANSI Blue", "ANSI Blue Bold",
519 "ANSI Magenta", "ANSI Magenta Bold",
520 "ANSI Cyan", "ANSI Cyan Bold",
521 "ANSI White", "ANSI White Bold"
522 };
523 static const int permcolour[] = {
524 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
525 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
526 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
527 };
528
529 static void fmtfont(char *buf)
530 {
531 sprintf(buf, "Font: %s, ", cfg.font);
532 if (cfg.fontisbold)
533 strcat(buf, "bold, ");
534 if (cfg.fontheight == 0)
535 strcat(buf, "default height");
536 else
537 sprintf(buf + strlen(buf), "%d-point",
538 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
539 }
540
541 static void init_dlg_ctrls(HWND hwnd)
542 {
543 int i;
544 char fontstatic[256];
545
546 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
547 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
548 {
549 int i, n;
550 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
551 for (i = n; i-- > 0;)
552 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
553 for (i = 0; i < nsessions; i++)
554 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
555 0, (LPARAM) (sessions[i]));
556 }
557 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
558 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
559 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
560 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
561 cfg.protocol ==
562 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
563 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
564
565 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
566 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
567 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
568 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
569 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
570 cfg.funky_type == 0 ? IDC_FUNCTILDE :
571 cfg.funky_type == 1 ? IDC_FUNCLINUX :
572 cfg.funky_type == 2 ? IDC_FUNCXTERM :
573 cfg.funky_type == 3 ? IDC_FUNCVT400 :
574 cfg.funky_type == 4 ? IDC_FUNCVT100P :
575 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
576 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
577 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
578 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
579 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
580 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
581 cfg.nethack_keypad ? IDC_KPNH :
582 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
583 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
584 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
585 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
586 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
587 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
588 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
589 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
590 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
591 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
592 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
593 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
594 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
595 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
596 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
597 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
598
599 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
600 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
601 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
602 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
603 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
604 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
605 fmtfont(fontstatic);
606 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
607 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
608 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
609 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
610 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
611 cfg.beep ==
612 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
613 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
614 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
615 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
616 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
617 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
618
619 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
620 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
621
622 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
623 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
624 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
625 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
626 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
627 cfg.cursor_type == 0 ? IDC_CURBLOCK :
628 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
629 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
630 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
631 CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize);
632 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
633 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
634 cfg.close_on_exit ==
635 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
636 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
637
638 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
639 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
640 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
641 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
642 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
643 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
644 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
645 cfg.logtype == 0 ? IDC_LSTATOFF :
646 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
647 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
648 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
649 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
650 IDC_LSTATXAPN);
651 {
652 char *p = cfg.environmt;
653 while (*p) {
654 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
655 (LPARAM) p);
656 p += strlen(p) + 1;
657 }
658 }
659 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
660 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
661
662 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
663 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
664 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
665 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
666 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
667 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
668 CheckRadioButton(hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
669 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
670 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
671 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
672 IDC_CIPHER3DES);
673 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
674 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
675 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
676 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
677 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
678
679 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
680 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
681 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
682 {
683 static int tabs[4] = { 25, 61, 96, 128 };
684 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
685 (LPARAM) tabs);
686 }
687 for (i = 0; i < 256; i++) {
688 char str[100];
689 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
690 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
691 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
692 (LPARAM) str);
693 }
694
695 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
696 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
697 {
698 int i, n;
699 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
700 for (i = n; i-- > 0;)
701 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
702 LB_DELETESTRING, i, 0);
703 for (i = 0; i < 22; i++)
704 if (cfg.bold_colour || permcolour[i])
705 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
706 (LPARAM) colours[i]);
707 }
708 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
709 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
710 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
711 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
712
713 CheckRadioButton(hwnd, IDC_NOXLAT, IDC_88592CP852,
714 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
715 cfg.xlat_88592cp852 ? IDC_88592CP852 :
716 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 : IDC_NOXLAT);
717 CheckDlgButton(hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
718 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
719 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
720 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
721 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
722 IDC_VTPOORMAN);
723
724 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
725 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
726 }
727
728 struct treeview_faff {
729 HWND treeview;
730 HTREEITEM lastat[4];
731 };
732
733 static HTREEITEM treeview_insert(struct treeview_faff *faff,
734 int level, char *text)
735 {
736 TVINSERTSTRUCT ins;
737 int i;
738 HTREEITEM newitem;
739 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
740 ins.hInsertAfter = faff->lastat[level];
741 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
742 #define INSITEM DUMMYUNIONNAME.item
743 #else
744 #define INSITEM item
745 #endif
746 ins.INSITEM.mask = TVIF_TEXT;
747 ins.INSITEM.pszText = text;
748 newitem = TreeView_InsertItem(faff->treeview, &ins);
749 if (level > 0)
750 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
751 TVE_EXPAND);
752 faff->lastat[level] = newitem;
753 for (i = level + 1; i < 4; i++)
754 faff->lastat[i] = NULL;
755 return newitem;
756 }
757
758 /*
759 * Create the panelfuls of controls in the configuration box.
760 */
761 static void create_controls(HWND hwnd, int dlgtype, int panel)
762 {
763 if (panel == sessionpanelstart) {
764 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
765 struct ctlpos cp;
766 ctlposinit(&cp, hwnd, 80, 3, 13);
767 bartitle(&cp, "Basic options for your PuTTY session",
768 IDC_TITLE_SESSION);
769 if (dlgtype == 0) {
770 beginbox(&cp, "Specify your connection by host name",
771 IDC_BOX_SESSION1);
772 multiedit(&cp,
773 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
774 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
775 if (backends[3].backend == NULL) {
776 /* this is PuTTYtel, so only three protocols available */
777 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
778 "&Raw", IDC_PROTRAW,
779 "&Telnet", IDC_PROTTELNET,
780 "Rlog&in", IDC_PROTRLOGIN, NULL);
781 } else {
782 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
783 "&Raw", IDC_PROTRAW,
784 "&Telnet", IDC_PROTTELNET,
785 "Rlog&in", IDC_PROTRLOGIN,
786 #ifdef FWHACK
787 "SS&H/hack",
788 #else
789 "SS&H",
790 #endif
791 IDC_PROTSSH, NULL);
792 }
793 endbox(&cp);
794 beginbox(&cp, "Load, save or delete a stored session",
795 IDC_BOX_SESSION2);
796 sesssaver(&cp, "Sav&ed Sessions",
797 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
798 "&Load", IDC_SESSLOAD,
799 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
800 endbox(&cp);
801 }
802 beginbox(&cp, NULL, IDC_BOX_SESSION3);
803 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
804 "Always", IDC_COEALWAYS,
805 "Never", IDC_COENEVER,
806 "Only on clean exit", IDC_COENORMAL, NULL);
807 endbox(&cp);
808 }
809
810 if (panel == loggingpanelstart) {
811 /* The Logging panel. Accelerators used: [acgo] tplfwe */
812 struct ctlpos cp;
813 ctlposinit(&cp, hwnd, 80, 3, 13);
814 bartitle(&cp, "Options controlling session logging",
815 IDC_TITLE_LOGGING);
816 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
817 radiobig(&cp,
818 "Session logging:", IDC_LSTATSTATIC,
819 "Logging &turned off completely", IDC_LSTATOFF,
820 "Log &printable output only", IDC_LSTATASCII,
821 "&Log all session output", IDC_LSTATRAW, NULL);
822 editbutton(&cp, "Log &file name:",
823 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
824 IDC_LGFBUTTON);
825 radiobig(&cp,
826 "What to do if the log file already &exists:",
827 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
828 "Always append to the end of it", IDC_LSTATXAPN,
829 "Ask the user every time", IDC_LSTATXASK, NULL);
830 endbox(&cp);
831 }
832
833 if (panel == terminalpanelstart) {
834 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
835 struct ctlpos cp;
836 ctlposinit(&cp, hwnd, 80, 3, 13);
837 bartitle(&cp, "Options controlling the terminal emulation",
838 IDC_TITLE_TERMINAL);
839 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
840 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
841 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
842 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
843 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
844 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
845 multiedit(&cp,
846 "An&swerback to ^E:", IDC_ANSWERBACK,
847 IDC_ANSWEREDIT, 100, NULL);
848 endbox(&cp);
849
850 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
851 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
852 "Auto", IDC_ECHOBACKEND,
853 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
854 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
855 "Auto", IDC_EDITBACKEND,
856 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
857 endbox(&cp);
858 }
859
860 if (panel == bellpanelstart) {
861 /* The Bell panel. Accelerators used: [acgo] bdsm wt */
862 struct ctlpos cp;
863 ctlposinit(&cp, hwnd, 80, 3, 13);
864 bartitle(&cp, "Options controlling the terminal bell",
865 IDC_TITLE_BELL);
866 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
867 radiobig(&cp,
868 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
869 "None (bell disabled)", IDC_BELL_DISABLED,
870 "Play Windows Default Sound", IDC_BELL_DEFAULT,
871 "Play a custom sound file", IDC_BELL_WAVEFILE,
872 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
873 editbutton(&cp, "Custom sound file to play as a bell:",
874 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
875 "Bro&wse...", IDC_BELL_WAVEBROWSE);
876 endbox(&cp);
877 beginbox(&cp, "Control the bell overload behaviour",
878 IDC_BOX_BELL2);
879 checkbox(&cp, "Bell is temporarily &disabled when over-used",
880 IDC_BELLOVL);
881 staticedit(&cp, "Over-use means this &many bells...",
882 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
883 staticedit(&cp, "... in &this many seconds",
884 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
885 statictext(&cp,
886 "The bell is re-enabled after a few seconds of silence.",
887 IDC_BELLOVLEXPLAIN);
888 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
889 IDC_BELLOVLS, 20);
890 endbox(&cp);
891 }
892
893 if (panel == keyboardpanelstart) {
894 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
895 struct ctlpos cp;
896 ctlposinit(&cp, hwnd, 80, 3, 13);
897 /*
898 bartitle(&cp, "Options controlling the effects of keys",
899 IDC_TITLE_KEYBOARD);
900 */
901 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
902 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
903 "Control-H", IDC_DEL008,
904 "Control-? (127)", IDC_DEL127, NULL);
905 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
906 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
907 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
908 "ESC[n~", IDC_FUNCTILDE,
909 "Linux", IDC_FUNCLINUX,
910 "Xterm R6", IDC_FUNCXTERM,
911 "VT400", IDC_FUNCVT400,
912 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
913 endbox(&cp);
914 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
915 checkbox(&cp,
916 "Application c&ursor keys totally disabled",
917 IDC_NOAPPLICC);
918 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
919 "Normal", IDC_CURNORMAL,
920 "Application", IDC_CURAPPLIC, NULL);
921 checkbox(&cp,
922 "Application ke&ypad keys totally disabled",
923 IDC_NOAPPLICK);
924 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
925 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
926 "NetHack", IDC_KPNH, NULL);
927 endbox(&cp);
928 beginbox(&cp, "Enable extra keyboard features:",
929 IDC_BOX_KEYBOARD3);
930 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
931 checkbox(&cp, "Control-Alt is &different from AltGr",
932 IDC_CTRLALTKEYS);
933 endbox(&cp);
934 }
935
936 if (panel == windowpanelstart) {
937 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
938 struct ctlpos cp;
939 ctlposinit(&cp, hwnd, 80, 3, 13);
940 bartitle(&cp, "Options controlling PuTTY's window",
941 IDC_TITLE_WINDOW);
942 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
943 multiedit(&cp,
944 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
945 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
946 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
947 endbox(&cp);
948 beginbox(&cp, "Control the scrollback in the window",
949 IDC_BOX_WINDOW2);
950 staticedit(&cp, "Lines of &scrollback",
951 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
952 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
953 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
954 checkbox(&cp, "Reset scrollback on dis&play activity",
955 IDC_SCROLLDISP);
956 endbox(&cp);
957 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
958 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
959 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
960 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
961 checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
962 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
963 endbox(&cp);
964 }
965
966 if (panel == appearancepanelstart) {
967 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
968 struct ctlpos cp;
969 ctlposinit(&cp, hwnd, 80, 3, 13);
970 bartitle(&cp, "Options controlling PuTTY's appearance",
971 IDC_TITLE_APPEARANCE);
972 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
973 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
974 "B&lock", IDC_CURBLOCK,
975 "&Underline", IDC_CURUNDER,
976 "&Vertical line", IDC_CURVERT, NULL);
977 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
978 endbox(&cp);
979 beginbox(&cp, "Set the font used in the terminal window",
980 IDC_BOX_APPEARANCE2);
981 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
982 endbox(&cp);
983 beginbox(&cp, "Adjust the use of the window title",
984 IDC_BOX_APPEARANCE3);
985 multiedit(&cp,
986 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
987 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
988 endbox(&cp);
989 beginbox(&cp, "Adjust the use of the mouse pointer",
990 IDC_BOX_APPEARANCE4);
991 checkbox(&cp, "Hide mouse &pointer when typing in window",
992 IDC_HIDEMOUSE);
993 endbox(&cp);
994 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
995 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
996 IDC_SUNKENEDGE);
997 endbox(&cp);
998 }
999
1000 if (panel == translationpanelstart) {
1001 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1002 struct ctlpos cp;
1003 ctlposinit(&cp, hwnd, 80, 3, 13);
1004 bartitle(&cp, "Options controlling character set translation",
1005 IDC_TITLE_TRANSLATION);
1006 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1007 IDC_BOX_TRANSLATION1);
1008 radiobig(&cp,
1009 "Handling of line drawing characters:", IDC_VTSTATIC,
1010 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1011 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1012 "Use font in O&EM mode only", IDC_VTOEMONLY,
1013 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1014 IDC_VTPOORMAN, NULL);
1015 endbox(&cp);
1016 beginbox(&cp, "Enable character set translation on received data",
1017 IDC_BOX_TRANSLATION2);
1018 radiobig(&cp,
1019 "Character set &translation:", IDC_XLATSTATIC,
1020 "None", IDC_NOXLAT,
1021 "KOI8 / Win-1251", IDC_KOI8WIN1251,
1022 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
1023 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
1024 endbox(&cp);
1025 beginbox(&cp, "Enable character set translation on input data",
1026 IDC_BOX_TRANSLATION3);
1027 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
1028 IDC_CAPSLOCKCYR);
1029 endbox(&cp);
1030 }
1031
1032 if (panel == selectionpanelstart) {
1033 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1034 struct ctlpos cp;
1035 ctlposinit(&cp, hwnd, 80, 3, 13);
1036 bartitle(&cp, "Options controlling copy and paste",
1037 IDC_TITLE_SELECTION);
1038 beginbox(&cp, "Translation of pasted characters",
1039 IDC_BOX_SELECTION1);
1040 checkbox(&cp,
1041 "&Don't translate line drawing chars into +, - and |",
1042 IDC_RAWCNP);
1043 endbox(&cp);
1044 beginbox(&cp, "Control which mouse button does which thing",
1045 IDC_BOX_SELECTION2);
1046 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1047 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1048 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1049 NULL);
1050 endbox(&cp);
1051 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1052 IDC_BOX_SELECTION3);
1053 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1054 "&Set", IDC_CCSET, IDC_CCEDIT,
1055 "&to class", IDC_CCSTATIC2);
1056 endbox(&cp);
1057 }
1058
1059 if (panel == colourspanelstart) {
1060 /* The Colours panel. Accelerators used: [acgo] blum */
1061 struct ctlpos cp;
1062 ctlposinit(&cp, hwnd, 80, 3, 13);
1063 bartitle(&cp, "Options controlling use of colours",
1064 IDC_TITLE_COLOURS);
1065 beginbox(&cp, "General options for colour usage",
1066 IDC_BOX_COLOURS1);
1067 checkbox(&cp, "&Bolded text is a different colour",
1068 IDC_BOLDCOLOUR);
1069 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1070 endbox(&cp);
1071 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1072 IDC_BOX_COLOURS2);
1073 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1074 IDC_COLOURSTATIC, IDC_COLOURLIST,
1075 "&Modify...", IDC_CHANGE,
1076 "Red:", IDC_RSTATIC, IDC_RVALUE,
1077 "Green:", IDC_GSTATIC, IDC_GVALUE,
1078 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1079 endbox(&cp);
1080 }
1081
1082 if (panel == connectionpanelstart) {
1083 /* The Connection panel. Accelerators used: [acgo] tuk */
1084 struct ctlpos cp;
1085 ctlposinit(&cp, hwnd, 80, 3, 13);
1086 bartitle(&cp, "Options controlling the connection",
1087 IDC_TITLE_CONNECTION);
1088 if (dlgtype == 0) {
1089 beginbox(&cp, "Data to send to the server",
1090 IDC_BOX_CONNECTION1);
1091 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1092 IDC_TTEDIT, 50);
1093 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1094 IDC_LOGEDIT, 50);
1095 endbox(&cp);
1096 }
1097 beginbox(&cp, "Sending of null packets to keep session active",
1098 IDC_BOX_CONNECTION2);
1099 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1100 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1101 endbox(&cp);
1102 }
1103
1104 if (panel == telnetpanelstart) {
1105 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
1106 struct ctlpos cp;
1107 ctlposinit(&cp, hwnd, 80, 3, 13);
1108 if (dlgtype == 0) {
1109 bartitle(&cp, "Options controlling Telnet connections",
1110 IDC_TITLE_TELNET);
1111 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1112 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1113 IDC_TSEDIT, 50);
1114 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1115 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1116 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1117 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1118 endbox(&cp);
1119 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1120 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1121 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1122 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1123 endbox(&cp);
1124 }
1125 }
1126
1127 if (panel == rloginpanelstart) {
1128 /* The Rlogin panel. Accelerators used: [acgo] sl */
1129 struct ctlpos cp;
1130 ctlposinit(&cp, hwnd, 80, 3, 13);
1131 if (dlgtype == 0) {
1132 bartitle(&cp, "Options controlling Rlogin connections",
1133 IDC_TITLE_RLOGIN);
1134 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1135 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1136 IDC_R_TSEDIT, 50);
1137 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1138 IDC_RLLUSEREDIT, 50);
1139 endbox(&cp);
1140 }
1141 }
1142
1143 if (panel == sshpanelstart) {
1144 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1145 struct ctlpos cp;
1146 ctlposinit(&cp, hwnd, 80, 3, 13);
1147 if (dlgtype == 0) {
1148 bartitle(&cp, "Options controlling SSH connections",
1149 IDC_TITLE_SSH);
1150 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1151 multiedit(&cp,
1152 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1153 NULL);
1154 endbox(&cp);
1155 beginbox(&cp, "Authentication options", IDC_BOX_SSH2);
1156 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1157 IDC_AUTHTIS);
1158 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1159 editbutton(&cp, "Private &key file for authentication:",
1160 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1161 IDC_PKBUTTON);
1162 endbox(&cp);
1163 beginbox(&cp, "Protocol options", IDC_BOX_SSH3);
1164 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1165 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1166 radioline(&cp, "Preferred SSH protocol version:",
1167 IDC_SSHPROTSTATIC, 2,
1168 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1169 radioline(&cp, "Preferred encryption algorithm:",
1170 IDC_CIPHERSTATIC, 4, "&3DES", IDC_CIPHER3DES,
1171 "&Blowfish", IDC_CIPHERBLOWF, "&DES", IDC_CIPHERDES,
1172 "AE&S", IDC_CIPHERAES, NULL);
1173 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1174 IDC_BUGGYMAC);
1175 endbox(&cp);
1176 }
1177 }
1178
1179 if (panel == tunnelspanelstart) {
1180 /* The Tunnels panel. Accelerators used: [acgo] ex */
1181 struct ctlpos cp;
1182 ctlposinit(&cp, hwnd, 80, 3, 13);
1183 if (dlgtype == 0) {
1184 bartitle(&cp, "Options controlling SSH tunnelling",
1185 IDC_TITLE_TUNNELS);
1186 beginbox(&cp, "X11 forwarding options", IDC_BOX_TUNNELS);
1187 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1188 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1189 IDC_X11_DISPLAY, 50, NULL);
1190 endbox(&cp);
1191 }
1192 }
1193 }
1194
1195 /*
1196 * This function is the configuration box.
1197 */
1198 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1199 WPARAM wParam, LPARAM lParam, int dlgtype)
1200 {
1201 HWND hw, treeview;
1202 struct treeview_faff tvfaff;
1203 HTREEITEM hsession;
1204 OPENFILENAME of;
1205 char filename[sizeof(cfg.keyfile)];
1206 CHOOSEFONT cf;
1207 LOGFONT lf;
1208 char fontstatic[256];
1209 char portname[32];
1210 struct servent *service;
1211 int i;
1212
1213 switch (msg) {
1214 case WM_INITDIALOG:
1215 readytogo = 0;
1216 SetWindowLong(hwnd, GWL_USERDATA, 0);
1217 /*
1218 * Centre the window.
1219 */
1220 { /* centre the window */
1221 RECT rs, rd;
1222
1223 hw = GetDesktopWindow();
1224 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1225 MoveWindow(hwnd,
1226 (rs.right + rs.left + rd.left - rd.right) / 2,
1227 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1228 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1229 }
1230
1231 /*
1232 * Create the tree view.
1233 */
1234 {
1235 RECT r;
1236 WPARAM font;
1237 HWND tvstatic;
1238
1239 r.left = 3;
1240 r.right = r.left + 75;
1241 r.top = 3;
1242 r.bottom = r.top + 10;
1243 MapDialogRect(hwnd, &r);
1244 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1245 WS_CHILD | WS_VISIBLE,
1246 r.left, r.top,
1247 r.right - r.left, r.bottom - r.top,
1248 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1249 NULL);
1250 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1251 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1252
1253 r.left = 3;
1254 r.right = r.left + 75;
1255 r.top = 13;
1256 r.bottom = r.top + 206;
1257 MapDialogRect(hwnd, &r);
1258 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1259 WS_CHILD | WS_VISIBLE |
1260 WS_TABSTOP | TVS_HASLINES |
1261 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1262 | TVS_LINESATROOT |
1263 TVS_SHOWSELALWAYS, r.left, r.top,
1264 r.right - r.left, r.bottom - r.top,
1265 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1266 NULL);
1267 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1268 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1269 tvfaff.treeview = treeview;
1270 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1271 }
1272
1273 /*
1274 * Set up the tree view contents.
1275 */
1276 hsession = treeview_insert(&tvfaff, 0, "Session");
1277 treeview_insert(&tvfaff, 1, "Logging");
1278 treeview_insert(&tvfaff, 0, "Terminal");
1279 treeview_insert(&tvfaff, 1, "Keyboard");
1280 treeview_insert(&tvfaff, 1, "Bell");
1281 treeview_insert(&tvfaff, 0, "Window");
1282 treeview_insert(&tvfaff, 1, "Appearance");
1283 treeview_insert(&tvfaff, 1, "Translation");
1284 treeview_insert(&tvfaff, 1, "Selection");
1285 treeview_insert(&tvfaff, 1, "Colours");
1286 treeview_insert(&tvfaff, 0, "Connection");
1287 if (dlgtype == 0) {
1288 treeview_insert(&tvfaff, 1, "Telnet");
1289 treeview_insert(&tvfaff, 1, "Rlogin");
1290 if (backends[3].backend != NULL) {
1291 treeview_insert(&tvfaff, 1, "SSH");
1292 treeview_insert(&tvfaff, 2, "Tunnels");
1293 }
1294 }
1295
1296 /*
1297 * Put the treeview selection on to the Session panel. This
1298 * should also cause creation of the relevant controls.
1299 */
1300 TreeView_SelectItem(treeview, hsession);
1301
1302 /*
1303 * Set focus into the first available control.
1304 */
1305 {
1306 HWND ctl;
1307 ctl = GetDlgItem(hwnd, IDC_HOST);
1308 if (!ctl)
1309 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1310 SetFocus(ctl);
1311 }
1312
1313 SetWindowLong(hwnd, GWL_USERDATA, 1);
1314 return 0;
1315 case WM_LBUTTONUP:
1316 /*
1317 * Button release should trigger WM_OK if there was a
1318 * previous double click on the session list.
1319 */
1320 ReleaseCapture();
1321 if (readytogo)
1322 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1323 break;
1324 case WM_NOTIFY:
1325 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1326 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1327 HTREEITEM i =
1328 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1329 TVITEM item;
1330 int j;
1331 char buffer[64];
1332 item.hItem = i;
1333 item.pszText = buffer;
1334 item.cchTextMax = sizeof(buffer);
1335 item.mask = TVIF_TEXT;
1336 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1337 for (j = controlstartvalue; j < controlendvalue; j++) {
1338 HWND item = GetDlgItem(hwnd, j);
1339 if (item)
1340 DestroyWindow(item);
1341 }
1342 if (!strcmp(buffer, "Session"))
1343 create_controls(hwnd, dlgtype, sessionpanelstart);
1344 if (!strcmp(buffer, "Logging"))
1345 create_controls(hwnd, dlgtype, loggingpanelstart);
1346 if (!strcmp(buffer, "Keyboard"))
1347 create_controls(hwnd, dlgtype, keyboardpanelstart);
1348 if (!strcmp(buffer, "Terminal"))
1349 create_controls(hwnd, dlgtype, terminalpanelstart);
1350 if (!strcmp(buffer, "Bell"))
1351 create_controls(hwnd, dlgtype, bellpanelstart);
1352 if (!strcmp(buffer, "Window"))
1353 create_controls(hwnd, dlgtype, windowpanelstart);
1354 if (!strcmp(buffer, "Appearance"))
1355 create_controls(hwnd, dlgtype, appearancepanelstart);
1356 if (!strcmp(buffer, "Tunnels"))
1357 create_controls(hwnd, dlgtype, tunnelspanelstart);
1358 if (!strcmp(buffer, "Connection"))
1359 create_controls(hwnd, dlgtype, connectionpanelstart);
1360 if (!strcmp(buffer, "Telnet"))
1361 create_controls(hwnd, dlgtype, telnetpanelstart);
1362 if (!strcmp(buffer, "Rlogin"))
1363 create_controls(hwnd, dlgtype, rloginpanelstart);
1364 if (!strcmp(buffer, "SSH"))
1365 create_controls(hwnd, dlgtype, sshpanelstart);
1366 if (!strcmp(buffer, "Selection"))
1367 create_controls(hwnd, dlgtype, selectionpanelstart);
1368 if (!strcmp(buffer, "Colours"))
1369 create_controls(hwnd, dlgtype, colourspanelstart);
1370 if (!strcmp(buffer, "Translation"))
1371 create_controls(hwnd, dlgtype, translationpanelstart);
1372
1373 init_dlg_ctrls(hwnd);
1374
1375 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1376 return 0;
1377 }
1378 break;
1379 case WM_COMMAND:
1380 /*
1381 * Only process WM_COMMAND once the dialog is fully formed.
1382 */
1383 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1384 switch (LOWORD(wParam)) {
1385 case IDOK:
1386 if (*cfg.host)
1387 EndDialog(hwnd, 1);
1388 else
1389 MessageBeep(0);
1390 return 0;
1391 case IDCANCEL:
1392 EndDialog(hwnd, 0);
1393 return 0;
1394 case IDC_PROTTELNET:
1395 case IDC_PROTRLOGIN:
1396 case IDC_PROTSSH:
1397 case IDC_PROTRAW:
1398 if (HIWORD(wParam) == BN_CLICKED ||
1399 HIWORD(wParam) == BN_DOUBLECLICKED) {
1400 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1401 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1402 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1403 cfg.protocol =
1404 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1405 PROT_RAW;
1406 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1407 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1408 || (cfg.protocol == PROT_RLOGIN
1409 && cfg.port != 513)) {
1410 cfg.port = i ? 22 : j ? 23 : 513;
1411 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1412 }
1413 }
1414 break;
1415 case IDC_HOST:
1416 if (HIWORD(wParam) == EN_CHANGE)
1417 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1418 sizeof(cfg.host) - 1);
1419 break;
1420 case IDC_PORT:
1421 if (HIWORD(wParam) == EN_CHANGE) {
1422 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1423 if (isdigit(portname[0]))
1424 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1425 else {
1426 service = getservbyname(portname, NULL);
1427 if (service)
1428 cfg.port = ntohs(service->s_port);
1429 else
1430 cfg.port = 0;
1431 }
1432 }
1433 break;
1434 case IDC_SESSEDIT:
1435 if (HIWORD(wParam) == EN_CHANGE) {
1436 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1437 (WPARAM) - 1, 0);
1438 GetDlgItemText(hwnd, IDC_SESSEDIT,
1439 savedsession, sizeof(savedsession) - 1);
1440 savedsession[sizeof(savedsession) - 1] = '\0';
1441 }
1442 break;
1443 case IDC_SESSSAVE:
1444 if (HIWORD(wParam) == BN_CLICKED ||
1445 HIWORD(wParam) == BN_DOUBLECLICKED) {
1446 /*
1447 * Save a session
1448 */
1449 char str[2048];
1450 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1451 sizeof(str) - 1);
1452 if (!*str) {
1453 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1454 LB_GETCURSEL, 0, 0);
1455 if (n == LB_ERR) {
1456 MessageBeep(0);
1457 break;
1458 }
1459 strcpy(str, sessions[n]);
1460 }
1461 save_settings(str, !!strcmp(str, "Default Settings"),
1462 &cfg);
1463 get_sesslist(FALSE);
1464 get_sesslist(TRUE);
1465 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1466 0, 0);
1467 for (i = 0; i < nsessions; i++)
1468 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1469 LB_ADDSTRING, 0,
1470 (LPARAM) (sessions[i]));
1471 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1472 (WPARAM) - 1, 0);
1473 }
1474 break;
1475 case IDC_SESSLIST:
1476 case IDC_SESSLOAD:
1477 if (LOWORD(wParam) == IDC_SESSLOAD &&
1478 HIWORD(wParam) != BN_CLICKED &&
1479 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1480 if (LOWORD(wParam) == IDC_SESSLIST &&
1481 HIWORD(wParam) != LBN_DBLCLK) break;
1482 {
1483 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1484 LB_GETCURSEL, 0, 0);
1485 int isdef;
1486 if (n == LB_ERR) {
1487 MessageBeep(0);
1488 break;
1489 }
1490 isdef = !strcmp(sessions[n], "Default Settings");
1491 load_settings(sessions[n], !isdef, &cfg);
1492 init_dlg_ctrls(hwnd);
1493 if (!isdef)
1494 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1495 else
1496 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1497 }
1498 if (LOWORD(wParam) == IDC_SESSLIST) {
1499 /*
1500 * A double-click on a saved session should
1501 * actually start the session, not just load it.
1502 * Unless it's Default Settings or some other
1503 * host-less set of saved settings.
1504 */
1505 if (*cfg.host) {
1506 readytogo = TRUE;
1507 SetCapture(hwnd);
1508 }
1509 }
1510 break;
1511 case IDC_SESSDEL:
1512 if (HIWORD(wParam) == BN_CLICKED ||
1513 HIWORD(wParam) == BN_DOUBLECLICKED) {
1514 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1515 LB_GETCURSEL, 0, 0);
1516 if (n == LB_ERR || n == 0) {
1517 MessageBeep(0);
1518 break;
1519 }
1520 del_settings(sessions[n]);
1521 get_sesslist(FALSE);
1522 get_sesslist(TRUE);
1523 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1524 0, 0);
1525 for (i = 0; i < nsessions; i++)
1526 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1527 LB_ADDSTRING, 0,
1528 (LPARAM) (sessions[i]));
1529 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1530 (WPARAM) - 1, 0);
1531 }
1532 case IDC_PINGEDIT:
1533 if (HIWORD(wParam) == EN_CHANGE)
1534 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1535 &cfg.ping_interval);
1536 break;
1537 case IDC_DEL008:
1538 case IDC_DEL127:
1539 if (HIWORD(wParam) == BN_CLICKED ||
1540 HIWORD(wParam) == BN_DOUBLECLICKED)
1541 cfg.bksp_is_delete =
1542 IsDlgButtonChecked(hwnd, IDC_DEL127);
1543 break;
1544 case IDC_HOMETILDE:
1545 case IDC_HOMERXVT:
1546 if (HIWORD(wParam) == BN_CLICKED ||
1547 HIWORD(wParam) == BN_DOUBLECLICKED)
1548 cfg.rxvt_homeend =
1549 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1550 break;
1551 case IDC_FUNCTILDE:
1552 case IDC_FUNCLINUX:
1553 case IDC_FUNCXTERM:
1554 case IDC_FUNCVT400:
1555 case IDC_FUNCVT100P:
1556 case IDC_FUNCSCO:
1557 if (HIWORD(wParam) == BN_CLICKED ||
1558 HIWORD(wParam) == BN_DOUBLECLICKED)
1559 switch (LOWORD(wParam)) {
1560 case IDC_FUNCTILDE:
1561 cfg.funky_type = 0;
1562 break;
1563 case IDC_FUNCLINUX:
1564 cfg.funky_type = 1;
1565 break;
1566 case IDC_FUNCXTERM:
1567 cfg.funky_type = 2;
1568 break;
1569 case IDC_FUNCVT400:
1570 cfg.funky_type = 3;
1571 break;
1572 case IDC_FUNCVT100P:
1573 cfg.funky_type = 4;
1574 break;
1575 case IDC_FUNCSCO:
1576 cfg.funky_type = 5;
1577 break;
1578 }
1579 break;
1580 case IDC_KPNORMAL:
1581 case IDC_KPAPPLIC:
1582 if (HIWORD(wParam) == BN_CLICKED ||
1583 HIWORD(wParam) == BN_DOUBLECLICKED) {
1584 cfg.app_keypad =
1585 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1586 cfg.nethack_keypad = FALSE;
1587 }
1588 break;
1589 case IDC_KPNH:
1590 if (HIWORD(wParam) == BN_CLICKED ||
1591 HIWORD(wParam) == BN_DOUBLECLICKED) {
1592 cfg.app_keypad = FALSE;
1593 cfg.nethack_keypad = TRUE;
1594 }
1595 break;
1596 case IDC_CURNORMAL:
1597 case IDC_CURAPPLIC:
1598 if (HIWORD(wParam) == BN_CLICKED ||
1599 HIWORD(wParam) == BN_DOUBLECLICKED)
1600 cfg.app_cursor =
1601 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1602 break;
1603 case IDC_NOAPPLICC:
1604 if (HIWORD(wParam) == BN_CLICKED ||
1605 HIWORD(wParam) == BN_DOUBLECLICKED)
1606 cfg.no_applic_c =
1607 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1608 break;
1609 case IDC_NOAPPLICK:
1610 if (HIWORD(wParam) == BN_CLICKED ||
1611 HIWORD(wParam) == BN_DOUBLECLICKED)
1612 cfg.no_applic_k =
1613 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1614 break;
1615 case IDC_ALTF4:
1616 if (HIWORD(wParam) == BN_CLICKED ||
1617 HIWORD(wParam) == BN_DOUBLECLICKED)
1618 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1619 break;
1620 case IDC_ALTSPACE:
1621 if (HIWORD(wParam) == BN_CLICKED ||
1622 HIWORD(wParam) == BN_DOUBLECLICKED)
1623 cfg.alt_space =
1624 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1625 break;
1626 case IDC_ALTONLY:
1627 if (HIWORD(wParam) == BN_CLICKED ||
1628 HIWORD(wParam) == BN_DOUBLECLICKED)
1629 cfg.alt_only =
1630 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1631 break;
1632 case IDC_ECHOBACKEND:
1633 case IDC_ECHOYES:
1634 case IDC_ECHONO:
1635 if (HIWORD(wParam) == BN_CLICKED ||
1636 HIWORD(wParam) == BN_DOUBLECLICKED) {
1637 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1638 cfg.localecho = LD_BACKEND;
1639 if (LOWORD(wParam) == IDC_ECHOYES)
1640 cfg.localecho = LD_YES;
1641 if (LOWORD(wParam) == IDC_ECHONO)
1642 cfg.localecho = LD_NO;
1643 }
1644 break;
1645 case IDC_EDITBACKEND:
1646 case IDC_EDITYES:
1647 case IDC_EDITNO:
1648 if (HIWORD(wParam) == BN_CLICKED ||
1649 HIWORD(wParam) == BN_DOUBLECLICKED) {
1650 if (LOWORD(wParam) == IDC_EDITBACKEND)
1651 cfg.localedit = LD_BACKEND;
1652 if (LOWORD(wParam) == IDC_EDITYES)
1653 cfg.localedit = LD_YES;
1654 if (LOWORD(wParam) == IDC_EDITNO)
1655 cfg.localedit = LD_NO;
1656 }
1657 break;
1658 case IDC_ANSWEREDIT:
1659 if (HIWORD(wParam) == EN_CHANGE)
1660 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1661 sizeof(cfg.answerback) - 1);
1662 break;
1663 case IDC_ALWAYSONTOP:
1664 if (HIWORD(wParam) == BN_CLICKED ||
1665 HIWORD(wParam) == BN_DOUBLECLICKED)
1666 cfg.alwaysontop =
1667 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1668 break;
1669 case IDC_SCROLLKEY:
1670 if (HIWORD(wParam) == BN_CLICKED ||
1671 HIWORD(wParam) == BN_DOUBLECLICKED)
1672 cfg.scroll_on_key =
1673 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1674 break;
1675 case IDC_SCROLLDISP:
1676 if (HIWORD(wParam) == BN_CLICKED ||
1677 HIWORD(wParam) == BN_DOUBLECLICKED)
1678 cfg.scroll_on_disp =
1679 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1680 break;
1681 case IDC_COMPOSEKEY:
1682 if (HIWORD(wParam) == BN_CLICKED ||
1683 HIWORD(wParam) == BN_DOUBLECLICKED)
1684 cfg.compose_key =
1685 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1686 break;
1687 case IDC_CTRLALTKEYS:
1688 if (HIWORD(wParam) == BN_CLICKED ||
1689 HIWORD(wParam) == BN_DOUBLECLICKED)
1690 cfg.ctrlaltkeys =
1691 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1692 break;
1693 case IDC_WRAPMODE:
1694 if (HIWORD(wParam) == BN_CLICKED ||
1695 HIWORD(wParam) == BN_DOUBLECLICKED)
1696 cfg.wrap_mode =
1697 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1698 break;
1699 case IDC_DECOM:
1700 if (HIWORD(wParam) == BN_CLICKED ||
1701 HIWORD(wParam) == BN_DOUBLECLICKED)
1702 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1703 break;
1704 case IDC_LFHASCR:
1705 if (HIWORD(wParam) == BN_CLICKED ||
1706 HIWORD(wParam) == BN_DOUBLECLICKED)
1707 cfg.lfhascr =
1708 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1709 break;
1710 case IDC_ROWSEDIT:
1711 if (HIWORD(wParam) == EN_CHANGE)
1712 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1713 break;
1714 case IDC_COLSEDIT:
1715 if (HIWORD(wParam) == EN_CHANGE)
1716 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1717 break;
1718 case IDC_SAVEEDIT:
1719 if (HIWORD(wParam) == EN_CHANGE)
1720 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1721 break;
1722 case IDC_CHOOSEFONT:
1723 lf.lfHeight = cfg.fontheight;
1724 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1725 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1726 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1727 lf.lfCharSet = cfg.fontcharset;
1728 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1729 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1730 lf.lfQuality = DEFAULT_QUALITY;
1731 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1732 strncpy(lf.lfFaceName, cfg.font,
1733 sizeof(lf.lfFaceName) - 1);
1734 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1735
1736 cf.lStructSize = sizeof(cf);
1737 cf.hwndOwner = hwnd;
1738 cf.lpLogFont = &lf;
1739 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1740 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1741
1742 if (ChooseFont(&cf)) {
1743 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1744 cfg.font[sizeof(cfg.font) - 1] = '\0';
1745 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1746 cfg.fontcharset = lf.lfCharSet;
1747 cfg.fontheight = cf.iPointSize / 10;
1748 fmtfont(fontstatic);
1749 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1750 }
1751 break;
1752 case IDC_BELL_DISABLED:
1753 case IDC_BELL_DEFAULT:
1754 case IDC_BELL_WAVEFILE:
1755 case IDC_BELL_VISUAL:
1756 if (HIWORD(wParam) == BN_CLICKED ||
1757 HIWORD(wParam) == BN_DOUBLECLICKED) {
1758 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1759 cfg.beep = BELL_DISABLED;
1760 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1761 cfg.beep = BELL_DEFAULT;
1762 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1763 cfg.beep = BELL_WAVEFILE;
1764 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1765 cfg.beep = BELL_VISUAL;
1766 }
1767 break;
1768 case IDC_BELL_WAVEBROWSE:
1769 memset(&of, 0, sizeof(of));
1770 #ifdef OPENFILENAME_SIZE_VERSION_400
1771 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1772 #else
1773 of.lStructSize = sizeof(of);
1774 #endif
1775 of.hwndOwner = hwnd;
1776 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1777 of.lpstrCustomFilter = NULL;
1778 of.nFilterIndex = 1;
1779 of.lpstrFile = filename;
1780 strcpy(filename, cfg.bell_wavefile);
1781 of.nMaxFile = sizeof(filename);
1782 of.lpstrFileTitle = NULL;
1783 of.lpstrInitialDir = NULL;
1784 of.lpstrTitle = "Select Bell Sound File";
1785 of.Flags = 0;
1786 if (GetOpenFileName(&of)) {
1787 strcpy(cfg.bell_wavefile, filename);
1788 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1789 cfg.bell_wavefile);
1790 }
1791 break;
1792 case IDC_BELL_WAVEEDIT:
1793 if (HIWORD(wParam) == EN_CHANGE)
1794 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1795 cfg.bell_wavefile,
1796 sizeof(cfg.bell_wavefile) - 1);
1797 break;
1798 case IDC_BELLOVL:
1799 if (HIWORD(wParam) == BN_CLICKED ||
1800 HIWORD(wParam) == BN_DOUBLECLICKED)
1801 cfg.bellovl =
1802 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1803 break;
1804 case IDC_BELLOVLN:
1805 if (HIWORD(wParam) == EN_CHANGE)
1806 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
1807 break;
1808 case IDC_BELLOVLT:
1809 if (HIWORD(wParam) == EN_CHANGE)
1810 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
1811 1000);
1812 break;
1813 case IDC_BELLOVLS:
1814 if (HIWORD(wParam) == EN_CHANGE)
1815 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
1816 1000);
1817 break;
1818 case IDC_BLINKTEXT:
1819 if (HIWORD(wParam) == BN_CLICKED ||
1820 HIWORD(wParam) == BN_DOUBLECLICKED)
1821 cfg.blinktext =
1822 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
1823 break;
1824 case IDC_BCE:
1825 if (HIWORD(wParam) == BN_CLICKED ||
1826 HIWORD(wParam) == BN_DOUBLECLICKED)
1827 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
1828 break;
1829 case IDC_WINNAME:
1830 if (HIWORD(wParam) == BN_CLICKED ||
1831 HIWORD(wParam) == BN_DOUBLECLICKED)
1832 cfg.win_name_always =
1833 IsDlgButtonChecked(hwnd, IDC_WINNAME);
1834 break;
1835 case IDC_HIDEMOUSE:
1836 if (HIWORD(wParam) == BN_CLICKED ||
1837 HIWORD(wParam) == BN_DOUBLECLICKED)
1838 cfg.hide_mouseptr =
1839 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
1840 break;
1841 case IDC_SUNKENEDGE:
1842 if (HIWORD(wParam) == BN_CLICKED ||
1843 HIWORD(wParam) == BN_DOUBLECLICKED)
1844 cfg.sunken_edge =
1845 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
1846 break;
1847 case IDC_CURBLOCK:
1848 if (HIWORD(wParam) == BN_CLICKED ||
1849 HIWORD(wParam) == BN_DOUBLECLICKED)
1850 cfg.cursor_type = 0;
1851 break;
1852 case IDC_CURUNDER:
1853 if (HIWORD(wParam) == BN_CLICKED ||
1854 HIWORD(wParam) == BN_DOUBLECLICKED)
1855 cfg.cursor_type = 1;
1856 break;
1857 case IDC_CURVERT:
1858 if (HIWORD(wParam) == BN_CLICKED ||
1859 HIWORD(wParam) == BN_DOUBLECLICKED)
1860 cfg.cursor_type = 2;
1861 break;
1862 case IDC_BLINKCUR:
1863 if (HIWORD(wParam) == BN_CLICKED ||
1864 HIWORD(wParam) == BN_DOUBLECLICKED)
1865 cfg.blink_cur =
1866 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
1867 break;
1868 case IDC_SCROLLBAR:
1869 if (HIWORD(wParam) == BN_CLICKED ||
1870 HIWORD(wParam) == BN_DOUBLECLICKED)
1871 cfg.scrollbar =
1872 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
1873 break;
1874 case IDC_LOCKSIZE:
1875 if (HIWORD(wParam) == BN_CLICKED ||
1876 HIWORD(wParam) == BN_DOUBLECLICKED)
1877 cfg.locksize =
1878 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
1879 break;
1880 case IDC_WINEDIT:
1881 if (HIWORD(wParam) == EN_CHANGE)
1882 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
1883 sizeof(cfg.wintitle) - 1);
1884 break;
1885 case IDC_COEALWAYS:
1886 case IDC_COENEVER:
1887 case IDC_COENORMAL:
1888 if (HIWORD(wParam) == BN_CLICKED ||
1889 HIWORD(wParam) == BN_DOUBLECLICKED) {
1890 cfg.close_on_exit =
1891 IsDlgButtonChecked(hwnd,
1892 IDC_COEALWAYS) ? COE_ALWAYS :
1893 IsDlgButtonChecked(hwnd,
1894 IDC_COENEVER) ? COE_NEVER :
1895 COE_NORMAL;
1896 }
1897 break;
1898 case IDC_CLOSEWARN:
1899 if (HIWORD(wParam) == BN_CLICKED ||
1900 HIWORD(wParam) == BN_DOUBLECLICKED)
1901 cfg.warn_on_close =
1902 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
1903 break;
1904 case IDC_TTEDIT:
1905 if (HIWORD(wParam) == EN_CHANGE)
1906 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
1907 sizeof(cfg.termtype) - 1);
1908 break;
1909 case IDC_LGFEDIT:
1910 if (HIWORD(wParam) == EN_CHANGE)
1911 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
1912 sizeof(cfg.logfilename) - 1);
1913 break;
1914 case IDC_LGFBUTTON:
1915 memset(&of, 0, sizeof(of));
1916 #ifdef OPENFILENAME_SIZE_VERSION_400
1917 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1918 #else
1919 of.lStructSize = sizeof(of);
1920 #endif
1921 of.hwndOwner = hwnd;
1922 of.lpstrFilter = "All Files\0*\0\0\0";
1923 of.lpstrCustomFilter = NULL;
1924 of.nFilterIndex = 1;
1925 of.lpstrFile = filename;
1926 strcpy(filename, cfg.logfilename);
1927 of.nMaxFile = sizeof(filename);
1928 of.lpstrFileTitle = NULL;
1929 of.lpstrInitialDir = NULL;
1930 of.lpstrTitle = "Select session log file";
1931 of.Flags = 0;
1932 if (GetSaveFileName(&of)) {
1933 strcpy(cfg.logfilename, filename);
1934 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
1935 }
1936 break;
1937 case IDC_LSTATOFF:
1938 case IDC_LSTATASCII:
1939 case IDC_LSTATRAW:
1940 if (HIWORD(wParam) == BN_CLICKED ||
1941 HIWORD(wParam) == BN_DOUBLECLICKED) {
1942 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
1943 cfg.logtype = 0;
1944 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
1945 cfg.logtype = 1;
1946 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
1947 cfg.logtype = 2;
1948 }
1949 break;
1950 case IDC_LSTATXASK:
1951 case IDC_LSTATXAPN:
1952 case IDC_LSTATXOVR:
1953 if (HIWORD(wParam) == BN_CLICKED ||
1954 HIWORD(wParam) == BN_DOUBLECLICKED) {
1955 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
1956 cfg.logxfovr = LGXF_ASK;
1957 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
1958 cfg.logxfovr = LGXF_APN;
1959 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
1960 cfg.logxfovr = LGXF_OVR;
1961 }
1962 break;
1963 case IDC_TSEDIT:
1964 case IDC_R_TSEDIT:
1965 if (HIWORD(wParam) == EN_CHANGE)
1966 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
1967 sizeof(cfg.termspeed) - 1);
1968 break;
1969 case IDC_LOGEDIT:
1970 if (HIWORD(wParam) == EN_CHANGE)
1971 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
1972 sizeof(cfg.username) - 1);
1973 break;
1974 case IDC_RLLUSEREDIT:
1975 if (HIWORD(wParam) == EN_CHANGE)
1976 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
1977 cfg.localusername,
1978 sizeof(cfg.localusername) - 1);
1979 break;
1980 case IDC_EMBSD:
1981 case IDC_EMRFC:
1982 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
1983 break;
1984 case IDC_ENVADD:
1985 if (HIWORD(wParam) == BN_CLICKED ||
1986 HIWORD(wParam) == BN_DOUBLECLICKED) {
1987 char str[sizeof(cfg.environmt)];
1988 char *p;
1989 GetDlgItemText(hwnd, IDC_VAREDIT, str,
1990 sizeof(str) - 1);
1991 if (!*str) {
1992 MessageBeep(0);
1993 break;
1994 }
1995 p = str + strlen(str);
1996 *p++ = '\t';
1997 GetDlgItemText(hwnd, IDC_VALEDIT, p,
1998 sizeof(str) - 1 - (p - str));
1999 if (!*p) {
2000 MessageBeep(0);
2001 break;
2002 }
2003 p = cfg.environmt;
2004 while (*p) {
2005 while (*p)
2006 p++;
2007 p++;
2008 }
2009 if ((p - cfg.environmt) + strlen(str) + 2 <
2010 sizeof(cfg.environmt)) {
2011 strcpy(p, str);
2012 p[strlen(str) + 1] = '\0';
2013 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2014 0, (LPARAM) str);
2015 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2016 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2017 } else {
2018 MessageBox(hwnd, "Environment too big",
2019 "PuTTY Error", MB_OK | MB_ICONERROR);
2020 }
2021 }
2022 break;
2023 case IDC_ENVREMOVE:
2024 if (HIWORD(wParam) != BN_CLICKED &&
2025 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2026 i =
2027 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2028 0);
2029 if (i == LB_ERR)
2030 MessageBeep(0);
2031 else {
2032 char *p, *q;
2033
2034 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2035 i, 0);
2036 p = cfg.environmt;
2037 while (i > 0) {
2038 if (!*p)
2039 goto disaster;
2040 while (*p)
2041 p++;
2042 p++;
2043 i--;
2044 }
2045 q = p;
2046 if (!*p)
2047 goto disaster;
2048 while (*p)
2049 p++;
2050 p++;
2051 while (*p) {
2052 while (*p)
2053 *q++ = *p++;
2054 *q++ = *p++;
2055 }
2056 *q = '\0';
2057 disaster:;
2058 }
2059 break;
2060 case IDC_NOPTY:
2061 if (HIWORD(wParam) == BN_CLICKED ||
2062 HIWORD(wParam) == BN_DOUBLECLICKED)
2063 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2064 break;
2065 case IDC_COMPRESS:
2066 if (HIWORD(wParam) == BN_CLICKED ||
2067 HIWORD(wParam) == BN_DOUBLECLICKED)
2068 cfg.compression =
2069 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2070 break;
2071 case IDC_BUGGYMAC:
2072 if (HIWORD(wParam) == BN_CLICKED ||
2073 HIWORD(wParam) == BN_DOUBLECLICKED)
2074 cfg.buggymac =
2075 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2076 break;
2077 case IDC_AGENTFWD:
2078 if (HIWORD(wParam) == BN_CLICKED ||
2079 HIWORD(wParam) == BN_DOUBLECLICKED)
2080 cfg.agentfwd =
2081 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2082 break;
2083 case IDC_CIPHER3DES:
2084 case IDC_CIPHERBLOWF:
2085 case IDC_CIPHERDES:
2086 case IDC_CIPHERAES:
2087 if (HIWORD(wParam) == BN_CLICKED ||
2088 HIWORD(wParam) == BN_DOUBLECLICKED) {
2089 if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES))
2090 cfg.cipher = CIPHER_3DES;
2091 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF))
2092 cfg.cipher = CIPHER_BLOWFISH;
2093 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES))
2094 cfg.cipher = CIPHER_DES;
2095 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES))
2096 cfg.cipher = CIPHER_AES;
2097 }
2098 break;
2099 case IDC_SSHPROT1:
2100 case IDC_SSHPROT2:
2101 if (HIWORD(wParam) == BN_CLICKED ||
2102 HIWORD(wParam) == BN_DOUBLECLICKED) {
2103 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2104 cfg.sshprot = 1;
2105 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2106 cfg.sshprot = 2;
2107 }
2108 break;
2109 case IDC_AUTHTIS:
2110 if (HIWORD(wParam) == BN_CLICKED ||
2111 HIWORD(wParam) == BN_DOUBLECLICKED)
2112 cfg.try_tis_auth =
2113 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2114 break;
2115 case IDC_PKEDIT:
2116 if (HIWORD(wParam) == EN_CHANGE)
2117 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2118 sizeof(cfg.keyfile) - 1);
2119 break;
2120 case IDC_CMDEDIT:
2121 if (HIWORD(wParam) == EN_CHANGE)
2122 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2123 sizeof(cfg.remote_cmd) - 1);
2124 break;
2125 case IDC_PKBUTTON:
2126 memset(&of, 0, sizeof(of));
2127 #ifdef OPENFILENAME_SIZE_VERSION_400
2128 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2129 #else
2130 of.lStructSize = sizeof(of);
2131 #endif
2132 of.hwndOwner = hwnd;
2133 of.lpstrFilter = "All Files\0*\0\0\0";
2134 of.lpstrCustomFilter = NULL;
2135 of.nFilterIndex = 1;
2136 of.lpstrFile = filename;
2137 strcpy(filename, cfg.keyfile);
2138 of.nMaxFile = sizeof(filename);
2139 of.lpstrFileTitle = NULL;
2140 of.lpstrInitialDir = NULL;
2141 of.lpstrTitle = "Select Public Key File";
2142 of.Flags = 0;
2143 if (GetOpenFileName(&of)) {
2144 strcpy(cfg.keyfile, filename);
2145 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2146 }
2147 break;
2148 case IDC_RAWCNP:
2149 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2150 case IDC_MBWINDOWS:
2151 case IDC_MBXTERM:
2152 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2153 break;
2154 case IDC_CCSET:
2155 {
2156 BOOL ok;
2157 int i;
2158 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2159
2160 if (!ok)
2161 MessageBeep(0);
2162 else {
2163 for (i = 0; i < 256; i++)
2164 if (SendDlgItemMessage
2165 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2166 char str[100];
2167 cfg.wordness[i] = n;
2168 SendDlgItemMessage(hwnd, IDC_CCLIST,
2169 LB_DELETESTRING, i, 0);
2170 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2171 (i >= 0x21 && i != 0x7F) ? i : ' ',
2172 cfg.wordness[i]);
2173 SendDlgItemMessage(hwnd, IDC_CCLIST,
2174 LB_INSERTSTRING, i,
2175 (LPARAM) str);
2176 }
2177 }
2178 }
2179 break;
2180 case IDC_BOLDCOLOUR:
2181 if (HIWORD(wParam) == BN_CLICKED ||
2182 HIWORD(wParam) == BN_DOUBLECLICKED) {
2183 int n, i;
2184 cfg.bold_colour =
2185 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2186 n =
2187 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2188 LB_GETCOUNT, 0, 0);
2189 if (n != 12 + 10 * cfg.bold_colour) {
2190 for (i = n; i-- > 0;)
2191 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2192 LB_DELETESTRING, i, 0);
2193 for (i = 0; i < 22; i++)
2194 if (cfg.bold_colour || permcolour[i])
2195 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2196 LB_ADDSTRING, 0,
2197 (LPARAM) colours[i]);
2198 }
2199 }
2200 break;
2201 case IDC_PALETTE:
2202 if (HIWORD(wParam) == BN_CLICKED ||
2203 HIWORD(wParam) == BN_DOUBLECLICKED)
2204 cfg.try_palette =
2205 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2206 break;
2207 case IDC_COLOURLIST:
2208 if (HIWORD(wParam) == LBN_DBLCLK ||
2209 HIWORD(wParam) == LBN_SELCHANGE) {
2210 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2211 LB_GETCURSEL,
2212 0, 0);
2213 if (!cfg.bold_colour)
2214 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2215 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2216 FALSE);
2217 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2218 FALSE);
2219 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2220 FALSE);
2221 }
2222 break;
2223 case IDC_CHANGE:
2224 if (HIWORD(wParam) == BN_CLICKED ||
2225 HIWORD(wParam) == BN_DOUBLECLICKED) {
2226 static CHOOSECOLOR cc;
2227 static DWORD custom[16] = { 0 }; /* zero initialisers */
2228 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2229 LB_GETCURSEL,
2230 0, 0);
2231 if (!cfg.bold_colour)
2232 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2233 cc.lStructSize = sizeof(cc);
2234 cc.hwndOwner = hwnd;
2235 cc.hInstance = (HWND) hinst;
2236 cc.lpCustColors = custom;
2237 cc.rgbResult =
2238 RGB(cfg.colours[i][0], cfg.colours[i][1],
2239 cfg.colours[i][2]);
2240 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2241 if (ChooseColor(&cc)) {
2242 cfg.colours[i][0] =
2243 (unsigned char) (cc.rgbResult & 0xFF);
2244 cfg.colours[i][1] =
2245 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2246 cfg.colours[i][2] =
2247 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2248 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2249 FALSE);
2250 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2251 FALSE);
2252 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2253 FALSE);
2254 }
2255 }
2256 break;
2257 case IDC_NOXLAT:
2258 case IDC_KOI8WIN1251:
2259 case IDC_88592WIN1250:
2260 case IDC_88592CP852:
2261 cfg.xlat_enablekoiwin =
2262 IsDlgButtonChecked(hwnd, IDC_KOI8WIN1251);
2263 cfg.xlat_88592w1250 =
2264 IsDlgButtonChecked(hwnd, IDC_88592WIN1250);
2265 cfg.xlat_88592cp852 =
2266 IsDlgButtonChecked(hwnd, IDC_88592CP852);
2267 break;
2268 case IDC_CAPSLOCKCYR:
2269 if (HIWORD(wParam) == BN_CLICKED ||
2270 HIWORD(wParam) == BN_DOUBLECLICKED) {
2271 cfg.xlat_capslockcyr =
2272 IsDlgButtonChecked(hwnd, IDC_CAPSLOCKCYR);
2273 }
2274 break;
2275 case IDC_VTXWINDOWS:
2276 case IDC_VTOEMANSI:
2277 case IDC_VTOEMONLY:
2278 case IDC_VTPOORMAN:
2279 cfg.vtmode =
2280 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2281 : IsDlgButtonChecked(hwnd,
2282 IDC_VTOEMANSI) ? VT_OEMANSI :
2283 IsDlgButtonChecked(hwnd,
2284 IDC_VTOEMONLY) ? VT_OEMONLY :
2285 VT_POORMAN);
2286 break;
2287 case IDC_X11_FORWARD:
2288 if (HIWORD(wParam) == BN_CLICKED ||
2289 HIWORD(wParam) == BN_DOUBLECLICKED)
2290 cfg.x11_forward =
2291 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2292 break;
2293 case IDC_X11_DISPLAY:
2294 if (HIWORD(wParam) == EN_CHANGE)
2295 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2296 sizeof(cfg.x11_display) - 1);
2297 break;
2298 }
2299 return 0;
2300 case WM_CLOSE:
2301 EndDialog(hwnd, 0);
2302 return 0;
2303
2304 /* Grrr Explorer will maximize Dialogs! */
2305 case WM_SIZE:
2306 if (wParam == SIZE_MAXIMIZED)
2307 force_normal(hwnd);
2308 return 0;
2309 }
2310 return 0;
2311 }
2312
2313 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2314 WPARAM wParam, LPARAM lParam)
2315 {
2316 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2317 }
2318 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2319 EnableWindow(hwnd, 0);
2320 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2321 GetParent(hwnd), AboutProc);
2322 EnableWindow(hwnd, 1);
2323 SetActiveWindow(hwnd);
2324 }
2325 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2326 }
2327
2328 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2329 WPARAM wParam, LPARAM lParam)
2330 {
2331 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2332 }
2333
2334 void defuse_showwindow(void)
2335 {
2336 /*
2337 * Work around the fact that the app's first call to ShowWindow
2338 * will ignore the default in favour of the shell-provided
2339 * setting.
2340 */
2341 {
2342 HWND hwnd;
2343 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2344 NULL, NullDlgProc);
2345 ShowWindow(hwnd, SW_HIDE);
2346 DestroyWindow(hwnd);
2347 }
2348 }
2349
2350 int do_config(void)
2351 {
2352 int ret;
2353
2354 get_sesslist(TRUE);
2355 savedsession[0] = '\0';
2356 ret =
2357 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2358 get_sesslist(FALSE);
2359
2360 return ret;
2361 }
2362
2363 int do_reconfig(HWND hwnd)
2364 {
2365 Config backup_cfg;
2366 int ret;
2367
2368 backup_cfg = cfg; /* structure copy */
2369 ret =
2370 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2371 if (!ret)
2372 cfg = backup_cfg; /* structure copy */
2373
2374 return ret;
2375 }
2376
2377 void logevent(char *string)
2378 {
2379 char timebuf[40];
2380 time_t t;
2381
2382 if (nevents >= negsize) {
2383 negsize += 64;
2384 events = srealloc(events, negsize * sizeof(*events));
2385 }
2386
2387 time(&t);
2388 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2389 localtime(&t));
2390
2391 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2392 strcpy(events[nevents], timebuf);
2393 strcat(events[nevents], string);
2394 if (logbox) {
2395 int count;
2396 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2397 0, (LPARAM) events[nevents]);
2398 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2399 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2400 }
2401 nevents++;
2402 }
2403
2404 void showeventlog(HWND hwnd)
2405 {
2406 if (!logbox) {
2407 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2408 hwnd, LogProc);
2409 ShowWindow(logbox, SW_SHOWNORMAL);
2410 }
2411 SetActiveWindow(logbox);
2412 }
2413
2414 void showabout(HWND hwnd)
2415 {
2416 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2417 }
2418
2419 void verify_ssh_host_key(char *host, int port, char *keytype,
2420 char *keystr, char *fingerprint)
2421 {
2422 int ret;
2423
2424 static const char absentmsg[] =
2425 "The server's host key is not cached in the registry. You\n"
2426 "have no guarantee that the server is the computer you\n"
2427 "think it is.\n"
2428 "The server's key fingerprint is:\n"
2429 "%s\n"
2430 "If you trust this host, hit Yes to add the key to\n"
2431 "PuTTY's cache and carry on connecting.\n"
2432 "If you do not trust this host, hit No to abandon the\n"
2433 "connection.\n";
2434
2435 static const char wrongmsg[] =
2436 "WARNING - POTENTIAL SECURITY BREACH!\n"
2437 "\n"
2438 "The server's host key does not match the one PuTTY has\n"
2439 "cached in the registry. This means that either the\n"
2440 "server administrator has changed the host key, or you\n"
2441 "have actually connected to another computer pretending\n"
2442 "to be the server.\n"
2443 "The new key fingerprint is:\n"
2444 "%s\n"
2445 "If you were expecting this change and trust the new key,\n"
2446 "hit Yes to update PuTTY's cache and continue connecting.\n"
2447 "If you want to carry on connecting but without updating\n"
2448 "the cache, hit No.\n"
2449 "If you want to abandon the connection completely, hit\n"
2450 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2451
2452 static const char mbtitle[] = "PuTTY Security Alert";
2453
2454
2455 char message[160 +
2456 /* sensible fingerprint max size */
2457 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2458 sizeof(absentmsg) : sizeof(wrongmsg))];
2459
2460 /*
2461 * Verify the key against the registry.
2462 */
2463 ret = verify_host_key(host, port, keytype, keystr);
2464
2465 if (ret == 0) /* success - key matched OK */
2466 return;
2467 if (ret == 2) { /* key was different */
2468 int mbret;
2469 sprintf(message, wrongmsg, fingerprint);
2470 mbret = MessageBox(NULL, message, mbtitle,
2471 MB_ICONWARNING | MB_YESNOCANCEL);
2472 if (mbret == IDYES)
2473 store_host_key(host, port, keytype, keystr);
2474 if (mbret == IDCANCEL)
2475 exit(0);
2476 }
2477 if (ret == 1) { /* key was absent */
2478 int mbret;
2479 sprintf(message, absentmsg, fingerprint);
2480 mbret = MessageBox(NULL, message, mbtitle,
2481 MB_ICONWARNING | MB_YESNO);
2482 if (mbret == IDNO)
2483 exit(0);
2484 store_host_key(host, port, keytype, keystr);
2485 }
2486 }
2487
2488 /*
2489 * Ask whether to wipe a session log file before writing to it.
2490 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2491 */
2492 int askappend(char *filename)
2493 {
2494 static const char mbtitle[] = "PuTTY Log to File";
2495 static const char msgtemplate[] =
2496 "The session log file \"%.*s\" already exists.\n"
2497 "You can overwrite it with a new session log,\n"
2498 "append your session log to the end of it,\n"
2499 "or disable session logging for this session.\n"
2500 "Hit Yes to wipe the file, No to append to it,\n"
2501 "or Cancel to disable logging.";
2502 char message[sizeof(msgtemplate) + FILENAME_MAX];
2503 int mbret;
2504 if (cfg.logxfovr != LGXF_ASK) {
2505 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2506 }
2507 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2508
2509 mbret = MessageBox(NULL, message, mbtitle,
2510 MB_ICONQUESTION | MB_YESNOCANCEL);
2511 if (mbret == IDYES)
2512 return 2;
2513 else if (mbret == IDNO)
2514 return 1;
2515 else
2516 return 0;
2517 }