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