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