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