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