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