]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windlg.c
Created new data types `Filename' and `FontSpec', intended to be
[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.name);
664     if (cfg.font.isbold)
665         strcat(buf, "bold, ");
666     if (cfg.font.height == 0)
667         strcat(buf, "default height");
668     else
669         sprintf(buf + strlen(buf), "%d-point",
670                 (cfg.font.height < 0 ? -cfg.font.height : cfg.font.height));
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.path);
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.path);
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.path);
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.path)];
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.font.height,
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.font.isbold ? FW_BOLD : 0);
2788                 lf.lfCharSet = cfg.font.charset;
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.name,
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.name, lf.lfFaceName,
2805                             sizeof(cfg.font.name) - 1);
2806                     cfg.font.name[sizeof(cfg.font.name) - 1] = '\0';
2807                     cfg.font.isbold = (lf.lfWeight == FW_BOLD);
2808                     cfg.font.charset = lf.lfCharSet;
2809                     cfg.font.height = cf.iPointSize / 10;
2810                     fmtfont(fontstatic);
2811                     SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
2812                 }
2813                 break;
2814               case IDC_BELL_DISABLED:
2815               case IDC_BELL_DEFAULT:
2816               case IDC_BELL_WAVEFILE:
2817               case IDC_BELL_VISUAL:
2818                 if (HIWORD(wParam) == BN_CLICKED ||
2819                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2820                     if (LOWORD(wParam) == IDC_BELL_DISABLED)
2821                         cfg.beep = BELL_DISABLED;
2822                     if (LOWORD(wParam) == IDC_BELL_DEFAULT)
2823                         cfg.beep = BELL_DEFAULT;
2824                     if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
2825                         cfg.beep = BELL_WAVEFILE;
2826                     if (LOWORD(wParam) == IDC_BELL_VISUAL)
2827                         cfg.beep = BELL_VISUAL;
2828                 }
2829                 break;
2830               case IDC_B_IND_DISABLED:
2831               case IDC_B_IND_FLASH:
2832               case IDC_B_IND_STEADY:
2833                 if (HIWORD(wParam) == BN_CLICKED ||
2834                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2835                     if (LOWORD(wParam) == IDC_B_IND_DISABLED)
2836                         cfg.beep_ind = B_IND_DISABLED;
2837                     if (LOWORD(wParam) == IDC_B_IND_FLASH)
2838                         cfg.beep_ind = B_IND_FLASH;
2839                     if (LOWORD(wParam) == IDC_B_IND_STEADY)
2840                         cfg.beep_ind = B_IND_STEADY;
2841                 }
2842                 break;
2843               case IDC_BELL_WAVEBROWSE:
2844                 memset(&of, 0, sizeof(of));
2845 #ifdef OPENFILENAME_SIZE_VERSION_400
2846                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2847 #else
2848                 of.lStructSize = sizeof(of);
2849 #endif
2850                 of.hwndOwner = hwnd;
2851                 of.lpstrFilter = "Wave Files (*.wav)\0*.WAV\0"
2852                     "All Files (*.*)\0*\0\0\0";
2853                 of.lpstrCustomFilter = NULL;
2854                 of.nFilterIndex = 1;
2855                 of.lpstrFile = filename;
2856                 strcpy(filename, cfg.bell_wavefile.path);
2857                 of.nMaxFile = sizeof(filename);
2858                 of.lpstrFileTitle = NULL;
2859                 of.lpstrInitialDir = NULL;
2860                 of.lpstrTitle = "Select Bell Sound File";
2861                 of.Flags = 0;
2862                 if (GetOpenFileName(&of)) {
2863                     strcpy(cfg.bell_wavefile.path, filename);
2864                     SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2865                                    cfg.bell_wavefile.path);
2866                 }
2867                 break;
2868               case IDC_BELL_WAVEEDIT:
2869                 if (HIWORD(wParam) == EN_CHANGE)
2870                     GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2871                                    cfg.bell_wavefile.path,
2872                                    sizeof(cfg.bell_wavefile.path) - 1);
2873                 break;
2874               case IDC_BELLOVL:
2875                 if (HIWORD(wParam) == BN_CLICKED ||
2876                     HIWORD(wParam) == BN_DOUBLECLICKED)
2877                         cfg.bellovl =
2878                         IsDlgButtonChecked(hwnd, IDC_BELLOVL);
2879                 break;
2880               case IDC_BELLOVLN:
2881                 if (HIWORD(wParam) == EN_CHANGE)
2882                     MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2883                 break;
2884               case IDC_BELLOVLT:
2885                 if (HIWORD(wParam) == EN_CHANGE)
2886                     MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2887                                     1000);
2888                 break;
2889               case IDC_BELLOVLS:
2890                 if (HIWORD(wParam) == EN_CHANGE)
2891                     MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2892                                     1000);
2893                 break;
2894               case IDC_BLINKTEXT:
2895                 if (HIWORD(wParam) == BN_CLICKED ||
2896                     HIWORD(wParam) == BN_DOUBLECLICKED)
2897                         cfg.blinktext =
2898                         IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2899                 break;
2900               case IDC_BCE:
2901                 if (HIWORD(wParam) == BN_CLICKED ||
2902                     HIWORD(wParam) == BN_DOUBLECLICKED)
2903                         cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2904                 break;
2905               case IDC_WINNAME:
2906                 if (HIWORD(wParam) == BN_CLICKED ||
2907                     HIWORD(wParam) == BN_DOUBLECLICKED)
2908                         cfg.win_name_always =
2909                         !IsDlgButtonChecked(hwnd, IDC_WINNAME);
2910                 break;
2911               case IDC_HIDEMOUSE:
2912                 if (HIWORD(wParam) == BN_CLICKED ||
2913                     HIWORD(wParam) == BN_DOUBLECLICKED)
2914                         cfg.hide_mouseptr =
2915                         IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2916                 break;
2917               case IDC_SUNKENEDGE:
2918                 if (HIWORD(wParam) == BN_CLICKED ||
2919                     HIWORD(wParam) == BN_DOUBLECLICKED)
2920                         cfg.sunken_edge =
2921                         IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2922                 break;
2923               case IDC_WINBEDIT:
2924                 if (HIWORD(wParam) == EN_CHANGE)
2925                     MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
2926                                     &cfg.window_border);
2927                 if (cfg.window_border > 32)
2928                     cfg.window_border = 32;
2929                 break;
2930               case IDC_CURBLOCK:
2931                 if (HIWORD(wParam) == BN_CLICKED ||
2932                     HIWORD(wParam) == BN_DOUBLECLICKED)
2933                         cfg.cursor_type = 0;
2934                 break;
2935               case IDC_CURUNDER:
2936                 if (HIWORD(wParam) == BN_CLICKED ||
2937                     HIWORD(wParam) == BN_DOUBLECLICKED)
2938                         cfg.cursor_type = 1;
2939                 break;
2940               case IDC_CURVERT:
2941                 if (HIWORD(wParam) == BN_CLICKED ||
2942                     HIWORD(wParam) == BN_DOUBLECLICKED)
2943                         cfg.cursor_type = 2;
2944                 break;
2945               case IDC_BLINKCUR:
2946                 if (HIWORD(wParam) == BN_CLICKED ||
2947                     HIWORD(wParam) == BN_DOUBLECLICKED)
2948                         cfg.blink_cur =
2949                         IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2950                 break;
2951               case IDC_SCROLLBAR:
2952                 if (HIWORD(wParam) == BN_CLICKED ||
2953                     HIWORD(wParam) == BN_DOUBLECLICKED)
2954                         cfg.scrollbar =
2955                         IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2956                 break;
2957               case IDC_SCROLLBARFULLSCREEN:
2958                 if (HIWORD(wParam) == BN_CLICKED ||
2959                     HIWORD(wParam) == BN_DOUBLECLICKED)
2960                     cfg.scrollbar_in_fullscreen =
2961                     IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN);
2962                 break;
2963               case IDC_RESIZETERM:
2964               case IDC_RESIZEFONT:
2965               case IDC_RESIZENONE:
2966               case IDC_RESIZEEITHER:
2967                 if (HIWORD(wParam) == BN_CLICKED ||
2968                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2969                     cfg.resize_action =
2970                         IsDlgButtonChecked(hwnd,
2971                                            IDC_RESIZETERM) ? RESIZE_TERM :
2972                         IsDlgButtonChecked(hwnd,
2973                                            IDC_RESIZEFONT) ? RESIZE_FONT :
2974                         IsDlgButtonChecked(hwnd,
2975                                            IDC_RESIZEEITHER) ? RESIZE_EITHER :
2976                         RESIZE_DISABLED;
2977                 }
2978                 break;
2979               case IDC_WINEDIT:
2980                 if (HIWORD(wParam) == EN_CHANGE)
2981                     GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2982                                    sizeof(cfg.wintitle) - 1);
2983                 break;
2984               case IDC_COEALWAYS:
2985               case IDC_COENEVER:
2986               case IDC_COENORMAL:
2987                 if (HIWORD(wParam) == BN_CLICKED ||
2988                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2989                     cfg.close_on_exit =
2990                         IsDlgButtonChecked(hwnd,
2991                                            IDC_COEALWAYS) ? FORCE_ON :
2992                         IsDlgButtonChecked(hwnd,
2993                                            IDC_COENEVER) ? FORCE_OFF :
2994                         AUTO;
2995                 }
2996                 break;
2997               case IDC_CLOSEWARN:
2998                 if (HIWORD(wParam) == BN_CLICKED ||
2999                     HIWORD(wParam) == BN_DOUBLECLICKED)
3000                         cfg.warn_on_close =
3001                         IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
3002                 break;
3003               case IDC_TTEDIT:
3004                 if (HIWORD(wParam) == EN_CHANGE)
3005                     GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
3006                                    sizeof(cfg.termtype) - 1);
3007                 break;
3008
3009                 /* proxy config */
3010               case IDC_PROXYHOSTEDIT:
3011                 if (HIWORD(wParam) == EN_CHANGE)
3012                     GetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host, 
3013                                    sizeof(cfg.proxy_host) - 1);
3014                 break;
3015               case IDC_PROXYPORTEDIT:
3016                 if (HIWORD(wParam) == EN_CHANGE) {
3017                     GetDlgItemText(hwnd, IDC_PROXYPORTEDIT, portname, 31);
3018                     if (isdigit(portname[0]))
3019                         MyGetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, &cfg.proxy_port);
3020                     else {
3021                         service = getservbyname(portname, NULL);
3022                         if (service)
3023                             cfg.proxy_port = ntohs(service->s_port);
3024                         else
3025                             cfg.proxy_port = 0;
3026                     }
3027                 }
3028                 break;
3029               case IDC_PROXYEXCLUDEEDIT:
3030                 if (HIWORD(wParam) == EN_CHANGE)
3031                     GetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT,
3032                                    cfg.proxy_exclude_list,
3033                                    sizeof(cfg.proxy_exclude_list) - 1);
3034                 break;
3035               case IDC_PROXYUSEREDIT:
3036                 if (HIWORD(wParam) == EN_CHANGE)
3037                     GetDlgItemText(hwnd, IDC_PROXYUSEREDIT,
3038                                    cfg.proxy_username, 
3039                                    sizeof(cfg.proxy_username) - 1);
3040                 break;
3041               case IDC_PROXYPASSEDIT:
3042                 if (HIWORD(wParam) == EN_CHANGE)
3043                     GetDlgItemText(hwnd, IDC_PROXYPASSEDIT,
3044                                    cfg.proxy_password, 
3045                                    sizeof(cfg.proxy_password) - 1);
3046                 break;
3047               case IDC_PROXYTELNETCMDEDIT:
3048                 if (HIWORD(wParam) == EN_CHANGE)
3049                     GetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT,
3050                                    cfg.proxy_telnet_command,
3051                                    sizeof(cfg.proxy_telnet_command) - 1);
3052                 break;
3053               case IDC_PROXYSOCKSVER5:
3054               case IDC_PROXYSOCKSVER4:
3055                 if (HIWORD(wParam) == BN_CLICKED ||
3056                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3057                     cfg.proxy_socks_version =
3058                         IsDlgButtonChecked(hwnd, IDC_PROXYSOCKSVER4) ? 4 : 5;
3059                 }
3060                 break;
3061               case IDC_PROXYLOCALHOST:
3062                 if (HIWORD(wParam) == BN_CLICKED ||
3063                     HIWORD(wParam) == BN_DOUBLECLICKED)
3064                     cfg.even_proxy_localhost =
3065                     IsDlgButtonChecked(hwnd, IDC_PROXYLOCALHOST);
3066                 break;
3067               case IDC_PROXYDNSNO:
3068               case IDC_PROXYDNSAUTO:
3069               case IDC_PROXYDNSYES:
3070                 if (HIWORD(wParam) == BN_CLICKED ||
3071                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3072                     cfg.proxy_dns =
3073                         IsDlgButtonChecked(hwnd, IDC_PROXYDNSNO) ? FORCE_OFF :
3074                         IsDlgButtonChecked(hwnd, IDC_PROXYDNSYES) ? FORCE_ON :
3075                         AUTO;
3076                 }
3077                 break;
3078               case IDC_PROXYTYPENONE:
3079               case IDC_PROXYTYPEHTTP:
3080               case IDC_PROXYTYPESOCKS:
3081               case IDC_PROXYTYPETELNET:
3082                 if (HIWORD(wParam) == BN_CLICKED ||
3083                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3084                     cfg.proxy_type =
3085                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPEHTTP) ? PROXY_HTTP :
3086                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPESOCKS) ? PROXY_SOCKS :
3087                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPETELNET) ? PROXY_TELNET :
3088                         PROXY_NONE;
3089                 }
3090                 break;
3091
3092               case IDC_LGFEDIT:
3093                 if (HIWORD(wParam) == EN_CHANGE)
3094                     GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path,
3095                                    sizeof(cfg.logfilename.path) - 1);
3096                 break;
3097               case IDC_LGFBUTTON:
3098                 memset(&of, 0, sizeof(of));
3099 #ifdef OPENFILENAME_SIZE_VERSION_400
3100                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
3101 #else
3102                 of.lStructSize = sizeof(of);
3103 #endif
3104                 of.hwndOwner = hwnd;
3105                 of.lpstrFilter = "All Files (*.*)\0*\0\0\0";
3106                 of.lpstrCustomFilter = NULL;
3107                 of.nFilterIndex = 1;
3108                 of.lpstrFile = filename;
3109                 strcpy(filename, cfg.logfilename.path);
3110                 of.nMaxFile = sizeof(filename);
3111                 of.lpstrFileTitle = NULL;
3112                 of.lpstrInitialDir = NULL;
3113                 of.lpstrTitle = "Select session log file";
3114                 of.Flags = 0;
3115                 if (GetSaveFileName(&of)) {
3116                     strcpy(cfg.logfilename.path, filename);
3117                     SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path);
3118                 }
3119                 break;
3120               case IDC_LSTATOFF:
3121               case IDC_LSTATASCII:
3122               case IDC_LSTATRAW:
3123               case IDC_LSTATPACKET:
3124                 if (HIWORD(wParam) == BN_CLICKED ||
3125                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3126                     if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
3127                         cfg.logtype = LGTYP_NONE;
3128                     if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
3129                         cfg.logtype = LGTYP_ASCII;
3130                     if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
3131                         cfg.logtype = LGTYP_DEBUG;
3132                     if (IsDlgButtonChecked(hwnd, IDC_LSTATPACKET))
3133                         cfg.logtype = LGTYP_PACKETS;
3134                 }
3135                 break;
3136               case IDC_LSTATXASK:
3137               case IDC_LSTATXAPN:
3138               case IDC_LSTATXOVR:
3139                 if (HIWORD(wParam) == BN_CLICKED ||
3140                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3141                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
3142                         cfg.logxfovr = LGXF_ASK;
3143                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
3144                         cfg.logxfovr = LGXF_APN;
3145                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
3146                         cfg.logxfovr = LGXF_OVR;
3147                 }
3148                 break;
3149               case IDC_TSEDIT:
3150               case IDC_R_TSEDIT:
3151                 if (HIWORD(wParam) == EN_CHANGE)
3152                     GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
3153                                    sizeof(cfg.termspeed) - 1);
3154                 break;
3155               case IDC_LOGEDIT:
3156                 if (HIWORD(wParam) == EN_CHANGE)
3157                     GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
3158                                    sizeof(cfg.username) - 1);
3159                 break;
3160               case IDC_RLLUSEREDIT:
3161                 if (HIWORD(wParam) == EN_CHANGE)
3162                     GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
3163                                    cfg.localusername,
3164                                    sizeof(cfg.localusername) - 1);
3165                 break;
3166               case IDC_EMBSD:
3167               case IDC_EMRFC:
3168                 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
3169                 break;
3170               case IDC_TPASSIVE:
3171               case IDC_TACTIVE:
3172                 cfg.passive_telnet =
3173                     IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
3174                 break;
3175               case IDC_ENVADD:
3176                 if (HIWORD(wParam) == BN_CLICKED ||
3177                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3178                     char str[sizeof(cfg.environmt)];
3179                     char *p;
3180                     GetDlgItemText(hwnd, IDC_VAREDIT, str,
3181                                    sizeof(str) - 1);
3182                     if (!*str) {
3183                         MessageBeep(0);
3184                         break;
3185                     }
3186                     p = str + strlen(str);
3187                     *p++ = '\t';
3188                     GetDlgItemText(hwnd, IDC_VALEDIT, p,
3189                                    sizeof(str) - 1 - (p - str));
3190                     if (!*p) {
3191                         MessageBeep(0);
3192                         break;
3193                     }
3194                     p = cfg.environmt;
3195                     while (*p) {
3196                         while (*p)
3197                             p++;
3198                         p++;
3199                     }
3200                     if ((p - cfg.environmt) + strlen(str) + 2 <
3201                         sizeof(cfg.environmt)) {
3202                         strcpy(p, str);
3203                         p[strlen(str) + 1] = '\0';
3204                         SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
3205                                            0, (LPARAM) str);
3206                         SetDlgItemText(hwnd, IDC_VAREDIT, "");
3207                         SetDlgItemText(hwnd, IDC_VALEDIT, "");
3208                     } else {
3209                         MessageBox(hwnd, "Environment too big",
3210                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3211                     }
3212                 }
3213                 break;
3214               case IDC_ENVREMOVE:
3215                 if (HIWORD(wParam) != BN_CLICKED &&
3216                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
3217                 i =
3218                     SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
3219                                        0);
3220                 if (i == LB_ERR)
3221                     MessageBeep(0);
3222                 else {
3223                     char *p, *q;
3224
3225                     SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
3226                                        i, 0);
3227                     p = cfg.environmt;
3228                     while (i > 0) {
3229                         if (!*p)
3230                             goto disaster;
3231                         while (*p)
3232                             p++;
3233                         p++;
3234                         i--;
3235                     }
3236                     q = p;
3237                     if (!*p)
3238                         goto disaster;
3239                     while (*p)
3240                         p++;
3241                     p++;
3242                     while (*p) {
3243                         while (*p)
3244                             *q++ = *p++;
3245                         *q++ = *p++;
3246                     }
3247                     *q = '\0';
3248                   disaster:;
3249                 }
3250                 break;
3251               case IDC_NOPTY:
3252                 if (HIWORD(wParam) == BN_CLICKED ||
3253                     HIWORD(wParam) == BN_DOUBLECLICKED)
3254                         cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
3255                 break;
3256               case IDC_COMPRESS:
3257                 if (HIWORD(wParam) == BN_CLICKED ||
3258                     HIWORD(wParam) == BN_DOUBLECLICKED)
3259                         cfg.compression =
3260                         IsDlgButtonChecked(hwnd, IDC_COMPRESS);
3261                 break;
3262               case IDC_SSH2DES:
3263                 if (HIWORD(wParam) == BN_CLICKED ||
3264                     HIWORD(wParam) == BN_DOUBLECLICKED)
3265                         cfg.ssh2_des_cbc =
3266                         IsDlgButtonChecked(hwnd, IDC_SSH2DES);
3267                 break;
3268               case IDC_AGENTFWD:
3269                 if (HIWORD(wParam) == BN_CLICKED ||
3270                     HIWORD(wParam) == BN_DOUBLECLICKED)
3271                         cfg.agentfwd =
3272                         IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
3273                 break;
3274               case IDC_CHANGEUSER:
3275                 if (HIWORD(wParam) == BN_CLICKED ||
3276                     HIWORD(wParam) == BN_DOUBLECLICKED)
3277                         cfg.change_username =
3278                         IsDlgButtonChecked(hwnd, IDC_CHANGEUSER);
3279                 break;
3280               case IDC_CIPHERLIST:
3281               case IDC_CIPHERUP:
3282               case IDC_CIPHERDN:
3283                 handle_prefslist(&cipherlist,
3284                                  cfg.ssh_cipherlist, CIPHER_MAX,
3285                                  0, hwnd, wParam, lParam);
3286                 break;
3287               case IDC_SSHPROT1ONLY:
3288               case IDC_SSHPROT1:
3289               case IDC_SSHPROT2:
3290               case IDC_SSHPROT2ONLY:
3291                 if (HIWORD(wParam) == BN_CLICKED ||
3292                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3293                     if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1ONLY))
3294                         cfg.sshprot = 0;
3295                     if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
3296                         cfg.sshprot = 1;
3297                     else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
3298                         cfg.sshprot = 2;
3299                     else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2ONLY))
3300                         cfg.sshprot = 3;
3301                 }
3302                 break;
3303               case IDC_AUTHTIS:
3304                 if (HIWORD(wParam) == BN_CLICKED ||
3305                     HIWORD(wParam) == BN_DOUBLECLICKED)
3306                         cfg.try_tis_auth =
3307                         IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
3308                 break;
3309               case IDC_AUTHKI:
3310                 if (HIWORD(wParam) == BN_CLICKED ||
3311                     HIWORD(wParam) == BN_DOUBLECLICKED)
3312                         cfg.try_ki_auth =
3313                         IsDlgButtonChecked(hwnd, IDC_AUTHKI);
3314                 break;
3315               case IDC_PKEDIT:
3316                 if (HIWORD(wParam) == EN_CHANGE)
3317                     GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path,
3318                                    sizeof(cfg.keyfile.path) - 1);
3319                 break;
3320               case IDC_CMDEDIT:
3321                 if (HIWORD(wParam) == EN_CHANGE)
3322                     GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
3323                                    sizeof(cfg.remote_cmd) - 1);
3324                 break;
3325               case IDC_PKBUTTON:
3326                 memset(&of, 0, sizeof(of));
3327 #ifdef OPENFILENAME_SIZE_VERSION_400
3328                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
3329 #else
3330                 of.lStructSize = sizeof(of);
3331 #endif
3332                 of.hwndOwner = hwnd;
3333                 of.lpstrFilter = "PuTTY Private Key Files (*.ppk)\0*.ppk\0"
3334                     "All Files (*.*)\0*\0\0\0";
3335                 of.lpstrCustomFilter = NULL;
3336                 of.nFilterIndex = 1;
3337                 of.lpstrFile = filename;
3338                 strcpy(filename, cfg.keyfile.path);
3339                 of.nMaxFile = sizeof(filename);
3340                 of.lpstrFileTitle = NULL;
3341                 of.lpstrInitialDir = NULL;
3342                 of.lpstrTitle = "Select Private Key File";
3343                 of.Flags = 0;
3344                 if (GetOpenFileName(&of)) {
3345                     strcpy(cfg.keyfile.path, filename);
3346                     SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path);
3347                 }
3348                 break;
3349               case IDC_RAWCNP:
3350                 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
3351                 break;
3352               case IDC_RTFPASTE:
3353                 cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE);
3354                 break;
3355               case IDC_MBWINDOWS:
3356               case IDC_MBXTERM:
3357                 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
3358                 break;
3359               case IDC_SELTYPELEX:
3360               case IDC_SELTYPERECT:
3361                 cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
3362                 break;
3363               case IDC_MOUSEOVERRIDE:
3364                 cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
3365                 break;
3366               case IDC_CCSET:
3367                 {
3368                     BOOL ok;
3369                     int i;
3370                     int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
3371
3372                     if (!ok)
3373                         MessageBeep(0);
3374                     else {
3375                         for (i = 0; i < 128; i++)
3376                             if (SendDlgItemMessage
3377                                 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
3378                                 char str[100];
3379                                 cfg.wordness[i] = n;
3380                                 SendDlgItemMessage(hwnd, IDC_CCLIST,
3381                                                    LB_DELETESTRING, i, 0);
3382                                 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
3383                                         (i >= 0x21 && i != 0x7F) ? i : ' ',
3384                                         cfg.wordness[i]);
3385                                 SendDlgItemMessage(hwnd, IDC_CCLIST,
3386                                                    LB_INSERTSTRING, i,
3387                                                    (LPARAM) str);
3388                             }
3389                     }
3390                 }
3391                 break;
3392               case IDC_BOLDCOLOUR:
3393                 if (HIWORD(wParam) == BN_CLICKED ||
3394                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3395                     int n, i;
3396                     cfg.bold_colour =
3397                         IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
3398                 }
3399                 break;
3400               case IDC_PALETTE:
3401                 if (HIWORD(wParam) == BN_CLICKED ||
3402                     HIWORD(wParam) == BN_DOUBLECLICKED)
3403                         cfg.try_palette =
3404                         IsDlgButtonChecked(hwnd, IDC_PALETTE);
3405                 break;
3406               case IDC_COLOURLIST:
3407                 if (HIWORD(wParam) == LBN_DBLCLK ||
3408                     HIWORD(wParam) == LBN_SELCHANGE) {
3409                     int i =
3410                         SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3411                                            LB_GETCURSEL,
3412                                            0, 0);
3413                     if (!cfg.bold_colour)
3414                         i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
3415                     SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
3416                                   FALSE);
3417                     SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
3418                                   FALSE);
3419                     SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
3420                                   FALSE);
3421                 }
3422                 break;
3423               case IDC_CHANGE:
3424                 if (HIWORD(wParam) == BN_CLICKED ||
3425                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3426                     static CHOOSECOLOR cc;
3427                     static DWORD custom[16] = { 0 };    /* zero initialisers */
3428                     int i =
3429                         SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3430                                            LB_GETCURSEL,
3431                                            0, 0);
3432                     if (!cfg.bold_colour)
3433                         i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
3434                     cc.lStructSize = sizeof(cc);
3435                     cc.hwndOwner = hwnd;
3436                     cc.hInstance = (HWND) hinst;
3437                     cc.lpCustColors = custom;
3438                     cc.rgbResult =
3439                         RGB(cfg.colours[i][0], cfg.colours[i][1],
3440                             cfg.colours[i][2]);
3441                     cc.Flags = CC_FULLOPEN | CC_RGBINIT;
3442                     if (ChooseColor(&cc)) {
3443                         cfg.colours[i][0] =
3444                             (unsigned char) (cc.rgbResult & 0xFF);
3445                         cfg.colours[i][1] =
3446                             (unsigned char) (cc.rgbResult >> 8) & 0xFF;
3447                         cfg.colours[i][2] =
3448                             (unsigned char) (cc.rgbResult >> 16) & 0xFF;
3449                         SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
3450                                       FALSE);
3451                         SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
3452                                       FALSE);
3453                         SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
3454                                       FALSE);
3455                     }
3456                 }
3457                 break;
3458               case IDC_CODEPAGE:
3459                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3460                     int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
3461                                                    CB_GETCURSEL, 0, 0);
3462                     SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
3463                                        index, (LPARAM)cfg.line_codepage);
3464                 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
3465                     GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
3466                                    sizeof(cfg.line_codepage) - 1);
3467                 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
3468                     strcpy(cfg.line_codepage,
3469                            cp_name(decode_codepage(cfg.line_codepage)));
3470                     SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
3471                 }
3472                 break;
3473               case IDC_PRINTER:
3474                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3475                     int index = SendDlgItemMessage(hwnd, IDC_PRINTER,
3476                                                    CB_GETCURSEL, 0, 0);
3477                     SendDlgItemMessage(hwnd, IDC_PRINTER, CB_GETLBTEXT,
3478                                        index, (LPARAM)cfg.printer);
3479                 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
3480                     GetDlgItemText(hwnd, IDC_PRINTER, cfg.printer,
3481                                    sizeof(cfg.printer) - 1);
3482                 }
3483                 if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING))
3484                     *cfg.printer = '\0';
3485                 break;
3486               case IDC_CAPSLOCKCYR:
3487                 if (HIWORD(wParam) == BN_CLICKED ||
3488                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3489                     cfg.xlat_capslockcyr =
3490                         IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
3491                 }
3492                 break;
3493               case IDC_VTXWINDOWS:
3494               case IDC_VTOEMANSI:
3495               case IDC_VTOEMONLY:
3496               case IDC_VTPOORMAN:
3497               case IDC_VTUNICODE:
3498                 cfg.vtmode =
3499                     (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
3500                      : IsDlgButtonChecked(hwnd,
3501                                           IDC_VTOEMANSI) ? VT_OEMANSI :
3502                      IsDlgButtonChecked(hwnd,
3503                                         IDC_VTOEMONLY) ? VT_OEMONLY :
3504                      IsDlgButtonChecked(hwnd,
3505                                         IDC_VTUNICODE) ? VT_UNICODE :
3506                      VT_POORMAN);
3507                 break;
3508               case IDC_X11_FORWARD:
3509                 if (HIWORD(wParam) == BN_CLICKED ||
3510                     HIWORD(wParam) == BN_DOUBLECLICKED)
3511                     cfg.x11_forward =
3512                     IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
3513                 break;
3514               case IDC_LPORT_ALL:
3515                 if (HIWORD(wParam) == BN_CLICKED ||
3516                     HIWORD(wParam) == BN_DOUBLECLICKED)
3517                     cfg.lport_acceptall =
3518                     IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
3519                 break;
3520               case IDC_RPORT_ALL:
3521                 if (HIWORD(wParam) == BN_CLICKED ||
3522                     HIWORD(wParam) == BN_DOUBLECLICKED)
3523                     cfg.rport_acceptall =
3524                     IsDlgButtonChecked(hwnd, IDC_RPORT_ALL);
3525                 break;
3526               case IDC_X11_DISPLAY:
3527                 if (HIWORD(wParam) == EN_CHANGE)
3528                     GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
3529                                    sizeof(cfg.x11_display) - 1);
3530                 break;
3531               case IDC_X11MIT:
3532               case IDC_X11XDM:
3533                 if (HIWORD(wParam) == BN_CLICKED ||
3534                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3535                     if (IsDlgButtonChecked(hwnd, IDC_X11MIT))
3536                         cfg.x11_auth = X11_MIT;
3537                     else if (IsDlgButtonChecked(hwnd, IDC_X11XDM))
3538                         cfg.x11_auth = X11_XDM;
3539                 }
3540                 break;
3541               case IDC_PFWDADD:
3542                 if (HIWORD(wParam) == BN_CLICKED ||
3543                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3544                     char str[sizeof(cfg.portfwd)];
3545                     char *p;
3546                     if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
3547                         str[0] = 'L';
3548                     else
3549                         str[0] = 'R';
3550                     GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
3551                                    sizeof(str) - 2);
3552                     if (!str[1]) {
3553                         MessageBox(hwnd,
3554                                    "You need to specify a source port number",
3555                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3556                         break;
3557                     }
3558                     p = str + strlen(str);
3559                     *p++ = '\t';
3560                     GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
3561                                    sizeof(str) - 1 - (p - str));
3562                     if (!*p || !strchr(p, ':')) {
3563                         MessageBox(hwnd,
3564                                    "You need to specify a destination address\n"
3565                                    "in the form \"host.name:port\"",
3566                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3567                         break;
3568                     }
3569                     p = cfg.portfwd;
3570                     while (*p) {
3571                         while (*p)
3572                             p++;
3573                         p++;
3574                     }
3575                     if ((p - cfg.portfwd) + strlen(str) + 2 <
3576                         sizeof(cfg.portfwd)) {
3577                         strcpy(p, str);
3578                         p[strlen(str) + 1] = '\0';
3579                         SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
3580                                            0, (LPARAM) str);
3581                         SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
3582                         SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
3583                     } else {
3584                         MessageBox(hwnd, "Too many forwardings",
3585                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3586                     }
3587                 }
3588                 break;
3589               case IDC_PFWDREMOVE:
3590                 if (HIWORD(wParam) != BN_CLICKED &&
3591                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
3592                 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
3593                                        LB_GETCURSEL, 0, 0);
3594                 if (i == LB_ERR)
3595                     MessageBeep(0);
3596                 else {
3597                     char *p, *q;
3598
3599                     SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
3600                                        i, 0);
3601                     p = cfg.portfwd;
3602                     while (i > 0) {
3603                         if (!*p)
3604                             goto disaster2;
3605                         while (*p)
3606                             p++;
3607                         p++;
3608                         i--;
3609                     }
3610                     q = p;
3611                     if (!*p)
3612                         goto disaster2;
3613                     while (*p)
3614                         p++;
3615                     p++;
3616                     while (*p) {
3617                         while (*p)
3618                             *q++ = *p++;
3619                         *q++ = *p++;
3620                     }
3621                     *q = '\0';
3622                   disaster2:;
3623                 }
3624                 break;
3625               case IDC_BUGD_IGNORE1:
3626                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3627                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1,
3628                                                    CB_GETCURSEL, 0, 0);
3629                     cfg.sshbug_ignore1 = (index == 0 ? AUTO :
3630                                           index == 1 ? FORCE_OFF : FORCE_ON);
3631                 }
3632                 break;
3633               case IDC_BUGD_PLAINPW1:
3634                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3635                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1,
3636                                                    CB_GETCURSEL, 0, 0);
3637                     cfg.sshbug_plainpw1 = (index == 0 ? AUTO :
3638                                            index == 1 ? FORCE_OFF : FORCE_ON);
3639                 }
3640                 break;
3641               case IDC_BUGD_RSA1:
3642                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3643                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSA1,
3644                                                    CB_GETCURSEL, 0, 0);
3645                     cfg.sshbug_rsa1 = (index == 0 ? AUTO :
3646                                        index == 1 ? FORCE_OFF : FORCE_ON);
3647                 }
3648                 break;
3649               case IDC_BUGD_HMAC2:
3650                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3651                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2,
3652                                                    CB_GETCURSEL, 0, 0);
3653                     cfg.sshbug_hmac2 = (index == 0 ? AUTO :
3654                                         index == 1 ? FORCE_OFF : FORCE_ON);
3655                 }
3656                 break;
3657               case IDC_BUGD_DERIVEKEY2:
3658                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3659                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2,
3660                                                    CB_GETCURSEL, 0, 0);
3661                     cfg.sshbug_derivekey2 = (index == 0 ? AUTO :
3662                                              index == 1 ? FORCE_OFF:FORCE_ON);
3663                 }
3664                 break;
3665               case IDC_BUGD_RSAPAD2:
3666                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3667                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2,
3668                                                    CB_GETCURSEL, 0, 0);
3669                     cfg.sshbug_rsapad2 = (index == 0 ? AUTO :
3670                                           index == 1 ? FORCE_OFF : FORCE_ON);
3671                 }
3672                 break;
3673               case IDC_BUGD_DHGEX2:
3674                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3675                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2,
3676                                                    CB_GETCURSEL, 0, 0);
3677                     cfg.sshbug_dhgex2 = (index == 0 ? AUTO :
3678                                          index == 1 ? FORCE_OFF : FORCE_ON);
3679                 }
3680                 break;
3681             }
3682         return 0;
3683       case WM_HELP:
3684         if (help_path) {
3685             int id = ((LPHELPINFO)lParam)->iCtrlId;
3686             char *cmd = help_context_cmd(id);
3687             if (cmd) {
3688                 WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
3689                 requested_help = TRUE;
3690             } else {
3691                 MessageBeep(0);
3692             }
3693         }
3694         break;
3695       case WM_CLOSE:
3696         if (requested_help) {
3697             WinHelp(hwnd, help_path, HELP_QUIT, 0);
3698             requested_help = FALSE;
3699         }
3700         EndDialog(hwnd, 0);
3701         return 0;
3702
3703         /* Grrr Explorer will maximize Dialogs! */
3704       case WM_SIZE:
3705         if (wParam == SIZE_MAXIMIZED)
3706             force_normal(hwnd);
3707         return 0;
3708
3709       default:
3710         /*
3711          * Handle application-defined messages eg. DragListBox
3712          */
3713         /* First find out what the number is (once). */
3714         if (draglistmsg == WM_NULL)
3715             draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
3716
3717         if (msg == draglistmsg) {
3718             /* Only process once dialog is fully formed. */
3719             if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
3720               case IDC_CIPHERLIST:
3721                 return handle_prefslist(&cipherlist,
3722                                         cfg.ssh_cipherlist, CIPHER_MAX,
3723                                         1, hwnd, wParam, lParam);
3724             }
3725         }
3726         return 0;
3727
3728     }
3729     return 0;
3730 }
3731
3732 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
3733                                 WPARAM wParam, LPARAM lParam)
3734 {
3735     if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
3736     }
3737     if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
3738         EnableWindow(hwnd, 0);
3739         DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3740         EnableWindow(hwnd, 1);
3741         SetActiveWindow(hwnd);
3742     }
3743     return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
3744 }
3745
3746 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
3747                                   WPARAM wParam, LPARAM lParam)
3748 {
3749     return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
3750 }
3751
3752 void defuse_showwindow(void)
3753 {
3754     /*
3755      * Work around the fact that the app's first call to ShowWindow
3756      * will ignore the default in favour of the shell-provided
3757      * setting.
3758      */
3759     {
3760         HWND hwnd;
3761         hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
3762                             NULL, NullDlgProc);
3763         ShowWindow(hwnd, SW_HIDE);
3764         SetActiveWindow(hwnd);
3765         DestroyWindow(hwnd);
3766     }
3767 }
3768
3769 int do_config(void)
3770 {
3771     int ret;
3772
3773     get_sesslist(&sesslist, TRUE);
3774     savedsession[0] = '\0';
3775     ret =
3776         DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
3777     get_sesslist(&sesslist, FALSE);
3778
3779     return ret;
3780 }
3781
3782 int do_reconfig(HWND hwnd)
3783 {
3784     Config backup_cfg;
3785     int ret;
3786
3787     backup_cfg = cfg;                  /* structure copy */
3788     ret =
3789         DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
3790     if (!ret)
3791         cfg = backup_cfg;              /* structure copy */
3792
3793     return ret;
3794 }
3795
3796 void logevent(void *frontend, char *string)
3797 {
3798     char timebuf[40];
3799     time_t t;
3800
3801     log_eventlog(logctx, string);
3802
3803     if (nevents >= negsize) {
3804         negsize += 64;
3805         events = srealloc(events, negsize * sizeof(*events));
3806     }
3807
3808     time(&t);
3809     strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
3810              localtime(&t));
3811
3812     events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
3813     strcpy(events[nevents], timebuf);
3814     strcat(events[nevents], string);
3815     if (logbox) {
3816         int count;
3817         SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
3818                            0, (LPARAM) events[nevents]);
3819         count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
3820         SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
3821     }
3822     nevents++;
3823 }
3824
3825 void showeventlog(HWND hwnd)
3826 {
3827     if (!logbox) {
3828         logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
3829                               hwnd, LogProc);
3830         ShowWindow(logbox, SW_SHOWNORMAL);
3831     }
3832     SetActiveWindow(logbox);
3833 }
3834
3835 void showabout(HWND hwnd)
3836 {
3837     DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3838 }
3839
3840 void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
3841                          char *keystr, char *fingerprint)
3842 {
3843     int ret;
3844
3845     static const char absentmsg[] =
3846         "The server's host key is not cached in the registry. You\n"
3847         "have no guarantee that the server is the computer you\n"
3848         "think it is.\n"
3849         "The server's key fingerprint is:\n"
3850         "%s\n"
3851         "If you trust this host, hit Yes to add the key to\n"
3852         "PuTTY's cache and carry on connecting.\n"
3853         "If you want to carry on connecting just once, without\n"
3854         "adding the key to the cache, hit No.\n"
3855         "If you do not trust this host, hit Cancel to abandon the\n"
3856         "connection.\n";
3857
3858     static const char wrongmsg[] =
3859         "WARNING - POTENTIAL SECURITY BREACH!\n"
3860         "\n"
3861         "The server's host key does not match the one PuTTY has\n"
3862         "cached in the registry. This means that either the\n"
3863         "server administrator has changed the host key, or you\n"
3864         "have actually connected to another computer pretending\n"
3865         "to be the server.\n"
3866         "The new key fingerprint is:\n"
3867         "%s\n"
3868         "If you were expecting this change and trust the new key,\n"
3869         "hit Yes to update PuTTY's cache and continue connecting.\n"
3870         "If you want to carry on connecting but without updating\n"
3871         "the cache, hit No.\n"
3872         "If you want to abandon the connection completely, hit\n"
3873         "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
3874
3875     static const char mbtitle[] = "PuTTY Security Alert";
3876
3877     char message[160 +
3878         /* sensible fingerprint max size */
3879         (sizeof(absentmsg) > sizeof(wrongmsg) ?
3880          sizeof(absentmsg) : sizeof(wrongmsg))];
3881
3882     /*
3883      * Verify the key against the registry.
3884      */
3885     ret = verify_host_key(host, port, keytype, keystr);
3886
3887     if (ret == 0)                      /* success - key matched OK */
3888         return;
3889     if (ret == 2) {                    /* key was different */
3890         int mbret;
3891         sprintf(message, wrongmsg, fingerprint);
3892         mbret = MessageBox(NULL, message, mbtitle,
3893                            MB_ICONWARNING | MB_YESNOCANCEL);
3894         if (mbret == IDYES)
3895             store_host_key(host, port, keytype, keystr);
3896         if (mbret == IDCANCEL)
3897             cleanup_exit(0);
3898     }
3899     if (ret == 1) {                    /* key was absent */
3900         int mbret;
3901         sprintf(message, absentmsg, fingerprint);
3902         mbret = MessageBox(NULL, message, mbtitle,
3903                            MB_ICONWARNING | MB_YESNOCANCEL);
3904         if (mbret == IDYES)
3905             store_host_key(host, port, keytype, keystr);
3906         if (mbret == IDCANCEL)
3907             cleanup_exit(0);
3908     }
3909 }
3910
3911 /*
3912  * Ask whether the selected cipher is acceptable (since it was
3913  * below the configured 'warn' threshold).
3914  * cs: 0 = both ways, 1 = client->server, 2 = server->client
3915  */
3916 void askcipher(void *frontend, char *ciphername, int cs)
3917 {
3918     static const char mbtitle[] = "PuTTY Security Alert";
3919     static const char msg[] =
3920         "The first %.35scipher supported by the server\n"
3921         "is %.64s, which is below the configured\n"
3922         "warning threshold.\n"
3923         "Do you want to continue with this connection?\n";
3924     /* guessed cipher name + type max length */
3925     char message[100 + sizeof(msg)];
3926     int mbret;
3927
3928     sprintf(message, msg,
3929             (cs == 0) ? "" :
3930             (cs == 1) ? "client-to-server " :
3931                         "server-to-client ",
3932             ciphername);
3933     mbret = MessageBox(NULL, message, mbtitle,
3934                        MB_ICONWARNING | MB_YESNO);
3935     if (mbret == IDYES)
3936         return;
3937     else
3938         cleanup_exit(0);
3939 }
3940
3941 /*
3942  * Ask whether to wipe a session log file before writing to it.
3943  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
3944  */
3945 int askappend(void *frontend, Filename filename)
3946 {
3947     static const char mbtitle[] = "PuTTY Log to File";
3948     static const char msgtemplate[] =
3949         "The session log file \"%.*s\" already exists.\n"
3950         "You can overwrite it with a new session log,\n"
3951         "append your session log to the end of it,\n"
3952         "or disable session logging for this session.\n"
3953         "Hit Yes to wipe the file, No to append to it,\n"
3954         "or Cancel to disable logging.";
3955     char message[sizeof(msgtemplate) + FILENAME_MAX];
3956     int mbret;
3957
3958     sprintf(message, msgtemplate, FILENAME_MAX, filename.path);
3959
3960     mbret = MessageBox(NULL, message, mbtitle,
3961                        MB_ICONQUESTION | MB_YESNOCANCEL);
3962     if (mbret == IDYES)
3963         return 2;
3964     else if (mbret == IDNO)
3965         return 1;
3966     else
3967         return 0;
3968 }
3969
3970 /*
3971  * Warn about the obsolescent key file format.
3972  * 
3973  * Uniquely among these functions, this one does _not_ expect a
3974  * frontend handle. This means that if PuTTY is ported to a
3975  * platform which requires frontend handles, this function will be
3976  * an anomaly. Fortunately, the problem it addresses will not have
3977  * been present on that platform, so it can plausibly be
3978  * implemented as an empty function.
3979  */
3980 void old_keyfile_warning(void)
3981 {
3982     static const char mbtitle[] = "PuTTY Key File Warning";
3983     static const char message[] =
3984         "You are loading an SSH 2 private key which has an\n"
3985         "old version of the file format. This means your key\n"
3986         "file is not fully tamperproof. Future versions of\n"
3987         "PuTTY may stop supporting this private key format,\n"
3988         "so we recommend you convert your key to the new\n"
3989         "format.\n"
3990         "\n"
3991         "You can perform this conversion by loading the key\n"
3992         "into PuTTYgen and then saving it again.";
3993
3994     MessageBox(NULL, message, mbtitle, MB_OK);
3995 }