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