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