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