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