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