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