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