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