]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - windlg.c
89ead9a26aa96db814abcc93292be1f546fbf4a1
[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                       "&Local", IDC_PFWDLOCAL,
2042                       "Re&mote", IDC_PFWDREMOTE);
2043             endbox(&cp);
2044
2045         }
2046     }
2047 }
2048
2049 /* 
2050  * Helper function to load the session selected in SESSLIST
2051  * if any, as this is done in more than one place in
2052  * GenericMainDlgProc(). 0 => failure.
2053  */
2054 static int load_selected_session(HWND hwnd)
2055 {
2056     int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2057                                LB_GETCURSEL, 0, 0);
2058     int isdef;
2059     if (n == LB_ERR) {
2060         MessageBeep(0);
2061         return 0;
2062     }
2063     isdef = !strcmp(sesslist.sessions[n], "Default Settings");
2064     load_settings(sesslist.sessions[n], !isdef, &cfg);
2065     init_dlg_ctrls(hwnd, TRUE);
2066     if (!isdef)
2067         SetDlgItemText(hwnd, IDC_SESSEDIT, sesslist.sessions[n]);
2068     else
2069         SetDlgItemText(hwnd, IDC_SESSEDIT, "");
2070     /* Restore the selection, which will have been clobbered by
2071      * SESSEDIT handling. */
2072     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
2073     return 1;
2074 }
2075
2076 /*
2077  * This function is the configuration box.
2078  */
2079 static int GenericMainDlgProc(HWND hwnd, UINT msg,
2080                               WPARAM wParam, LPARAM lParam, int dlgtype)
2081 {
2082     HWND hw, treeview;
2083     struct treeview_faff tvfaff;
2084     HTREEITEM hsession;
2085     OPENFILENAME of;
2086     char filename[sizeof(cfg.keyfile)];
2087     CHOOSEFONT cf;
2088     LOGFONT lf;
2089     char fontstatic[256];
2090     char portname[32];
2091     struct servent *service;
2092     int i;
2093     static UINT draglistmsg = WM_NULL;
2094
2095     switch (msg) {
2096       case WM_INITDIALOG:
2097         readytogo = 0;
2098         SetWindowLong(hwnd, GWL_USERDATA, 0);
2099         if (help_path)
2100             SetWindowLong(hwnd, GWL_EXSTYLE,
2101                           GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
2102         else {
2103             HWND item = GetDlgItem(hwnd, IDC_HELPBTN);
2104             if (item)
2105                 DestroyWindow(item);
2106         }
2107         requested_help = FALSE;
2108         SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
2109                     (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
2110         /*
2111          * Centre the window.
2112          */
2113         {                              /* centre the window */
2114             RECT rs, rd;
2115
2116             hw = GetDesktopWindow();
2117             if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
2118                 MoveWindow(hwnd,
2119                            (rs.right + rs.left + rd.left - rd.right) / 2,
2120                            (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
2121                            rd.right - rd.left, rd.bottom - rd.top, TRUE);
2122         }
2123
2124         /*
2125          * Create the tree view.
2126          */
2127         {
2128             RECT r;
2129             WPARAM font;
2130             HWND tvstatic;
2131
2132             r.left = 3;
2133             r.right = r.left + 75;
2134             r.top = 3;
2135             r.bottom = r.top + 10;
2136             MapDialogRect(hwnd, &r);
2137             tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
2138                                       WS_CHILD | WS_VISIBLE,
2139                                       r.left, r.top,
2140                                       r.right - r.left, r.bottom - r.top,
2141                                       hwnd, (HMENU) IDCX_TVSTATIC, hinst,
2142                                       NULL);
2143             font = SendMessage(hwnd, WM_GETFONT, 0, 0);
2144             SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
2145
2146             r.left = 3;
2147             r.right = r.left + 75;
2148             r.top = 13;
2149             r.bottom = r.top + 219;
2150             MapDialogRect(hwnd, &r);
2151             treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
2152                                       WS_CHILD | WS_VISIBLE |
2153                                       WS_TABSTOP | TVS_HASLINES |
2154                                       TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
2155                                       | TVS_LINESATROOT |
2156                                       TVS_SHOWSELALWAYS, r.left, r.top,
2157                                       r.right - r.left, r.bottom - r.top,
2158                                       hwnd, (HMENU) IDCX_TREEVIEW, hinst,
2159                                       NULL);
2160             font = SendMessage(hwnd, WM_GETFONT, 0, 0);
2161             SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
2162             tvfaff.treeview = treeview;
2163             memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
2164         }
2165
2166         /*
2167          * Set up the tree view contents.
2168          */
2169         hsession = treeview_insert(&tvfaff, 0, "Session");
2170         treeview_insert(&tvfaff, 1, "Logging");
2171         treeview_insert(&tvfaff, 0, "Terminal");
2172         treeview_insert(&tvfaff, 1, "Keyboard");
2173         treeview_insert(&tvfaff, 1, "Bell");
2174         treeview_insert(&tvfaff, 1, "Features");
2175         treeview_insert(&tvfaff, 0, "Window");
2176         treeview_insert(&tvfaff, 1, "Appearance");
2177         treeview_insert(&tvfaff, 1, "Behaviour");
2178         treeview_insert(&tvfaff, 1, "Translation");
2179         treeview_insert(&tvfaff, 1, "Selection");
2180         treeview_insert(&tvfaff, 1, "Colours");
2181         treeview_insert(&tvfaff, 0, "Connection");
2182         if (dlgtype == 0) {
2183             treeview_insert(&tvfaff, 1, "Proxy");
2184             treeview_insert(&tvfaff, 1, "Telnet");
2185             treeview_insert(&tvfaff, 1, "Rlogin");
2186             if (backends[3].backend != NULL) {
2187                 treeview_insert(&tvfaff, 1, "SSH");
2188                 /* XXX long name is ugly */
2189                 /* XXX make it closed by default? */
2190                 treeview_insert(&tvfaff, 2, "Auth");
2191                 treeview_insert(&tvfaff, 2, "Tunnels");
2192                 treeview_insert(&tvfaff, 2, "Bugs");
2193             }
2194         }
2195
2196         /*
2197          * Put the treeview selection on to the Session panel. This
2198          * should also cause creation of the relevant controls.
2199          */
2200         TreeView_SelectItem(treeview, hsession);
2201
2202         /*
2203          * Set focus into the first available control.
2204          */
2205         {
2206             HWND ctl;
2207             ctl = GetDlgItem(hwnd, IDC_HOST);
2208             if (!ctl)
2209                 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
2210             SetFocus(ctl);
2211         }
2212
2213         SetWindowLong(hwnd, GWL_USERDATA, 1);
2214         sesslist_has_focus = 0;
2215         return 0;
2216       case WM_LBUTTONUP:
2217         /*
2218          * Button release should trigger WM_OK if there was a
2219          * previous double click on the session list.
2220          */
2221         ReleaseCapture();
2222         if (readytogo)
2223             SendMessage(hwnd, WM_COMMAND, IDOK, 0);
2224         break;
2225       case WM_NOTIFY:
2226         if (LOWORD(wParam) == IDCX_TREEVIEW &&
2227             ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
2228             HTREEITEM i =
2229                 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
2230             TVITEM item;
2231             int j;
2232             char buffer[64];
2233  
2234             SendMessage (hwnd, WM_SETREDRAW, FALSE, 0);
2235  
2236             item.hItem = i;
2237             item.pszText = buffer;
2238             item.cchTextMax = sizeof(buffer);
2239             item.mask = TVIF_TEXT;
2240             TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
2241             for (j = controlstartvalue; j < controlendvalue; j++) {
2242                 HWND item = GetDlgItem(hwnd, j);
2243                 if (item)
2244                     DestroyWindow(item);
2245             }
2246             if (!strcmp(buffer, "Session"))
2247                 create_controls(hwnd, dlgtype, sessionpanelstart);
2248             if (!strcmp(buffer, "Logging"))
2249                 create_controls(hwnd, dlgtype, loggingpanelstart);
2250             if (!strcmp(buffer, "Keyboard"))
2251                 create_controls(hwnd, dlgtype, keyboardpanelstart);
2252             if (!strcmp(buffer, "Terminal"))
2253                 create_controls(hwnd, dlgtype, terminalpanelstart);
2254             if (!strcmp(buffer, "Bell"))
2255                 create_controls(hwnd, dlgtype, bellpanelstart);
2256             if (!strcmp(buffer, "Features"))
2257                 create_controls(hwnd, dlgtype, featurespanelstart);
2258             if (!strcmp(buffer, "Window"))
2259                 create_controls(hwnd, dlgtype, windowpanelstart);
2260             if (!strcmp(buffer, "Appearance"))
2261                 create_controls(hwnd, dlgtype, appearancepanelstart);
2262             if (!strcmp(buffer, "Behaviour"))
2263                 create_controls(hwnd, dlgtype, behaviourpanelstart);
2264             if (!strcmp(buffer, "Tunnels"))
2265                 create_controls(hwnd, dlgtype, tunnelspanelstart);
2266             if (!strcmp(buffer, "Connection"))
2267                 create_controls(hwnd, dlgtype, connectionpanelstart);
2268             if (!strcmp(buffer, "Proxy"))
2269                 create_controls(hwnd, dlgtype, proxypanelstart);
2270             if (!strcmp(buffer, "Telnet"))
2271                 create_controls(hwnd, dlgtype, telnetpanelstart);
2272             if (!strcmp(buffer, "Rlogin"))
2273                 create_controls(hwnd, dlgtype, rloginpanelstart);
2274             if (!strcmp(buffer, "SSH"))
2275                 create_controls(hwnd, dlgtype, sshpanelstart);
2276             if (!strcmp(buffer, "Auth"))
2277                 create_controls(hwnd, dlgtype, sshauthpanelstart);
2278             if (!strcmp(buffer, "Bugs"))
2279                 create_controls(hwnd, dlgtype, sshbugspanelstart);
2280             if (!strcmp(buffer, "Selection"))
2281                 create_controls(hwnd, dlgtype, selectionpanelstart);
2282             if (!strcmp(buffer, "Colours"))
2283                 create_controls(hwnd, dlgtype, colourspanelstart);
2284             if (!strcmp(buffer, "Translation"))
2285                 create_controls(hwnd, dlgtype, translationpanelstart);
2286
2287             init_dlg_ctrls(hwnd, FALSE);
2288  
2289             SendMessage (hwnd, WM_SETREDRAW, TRUE, 0);
2290             InvalidateRect (hwnd, NULL, TRUE);
2291
2292             SetFocus(((LPNMHDR) lParam)->hwndFrom);     /* ensure focus stays */
2293             return 0;
2294         }
2295         break;
2296       case WM_COMMAND:
2297         /*
2298          * Only process WM_COMMAND once the dialog is fully formed.
2299          */
2300         if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
2301             switch (LOWORD(wParam)) {
2302               case IDOK:
2303                 /* Behaviour of the "Open" button is different if the
2304                  * session list has focus, *unless* the user just
2305                  * double-clicked... */
2306                 if (sesslist_has_focus && !readytogo) {
2307                     if (!load_selected_session(hwnd)) {
2308                         MessageBeep(0);
2309                         return 0;
2310                     }
2311                 }
2312                 /* If at this point we have a valid session, go! */
2313                 if (*cfg.host) {
2314                     if (requested_help) {
2315                         WinHelp(hwnd, help_path, HELP_QUIT, 0);
2316                         requested_help = FALSE;
2317                     }
2318                     EndDialog(hwnd, 1);
2319                 } else
2320                     MessageBeep(0);
2321                 return 0;
2322               case IDC_HELPBTN:
2323                 if (HIWORD(wParam) == BN_CLICKED ||
2324                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2325                     if (help_path) {
2326                         WinHelp(hwnd, help_path,
2327                                 help_has_contents ? HELP_FINDER : HELP_CONTENTS,
2328                                 0);
2329                         requested_help = TRUE;
2330                     }
2331                 }
2332                 break;
2333               case IDCANCEL:
2334                 if (requested_help) {
2335                     WinHelp(hwnd, help_path, HELP_QUIT, 0);
2336                     requested_help = FALSE;
2337                 }
2338                 EndDialog(hwnd, 0);
2339                 return 0;
2340               case IDC_PROTTELNET:
2341               case IDC_PROTRLOGIN:
2342               case IDC_PROTSSH:
2343               case IDC_PROTRAW:
2344                 if (HIWORD(wParam) == BN_CLICKED ||
2345                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2346                     int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
2347                     int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
2348                     int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
2349                     cfg.protocol =
2350                         i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
2351                         PROT_RAW;
2352                     /*
2353                      * When switching using the arrow keys, we
2354                      * appear to get two of these messages, both
2355                      * mentioning the target button in
2356                      * LOWORD(wParam), but one of them called while
2357                      * the previous button is still checked. This
2358                      * causes an unnecessary reset of the port
2359                      * number field, which we fix by ensuring here
2360                      * that the button selected is indeed the one
2361                      * checked.
2362                      */
2363                     if (IsDlgButtonChecked(hwnd, LOWORD(wParam)) &&
2364                         ((cfg.protocol == PROT_SSH && cfg.port != 22)
2365                          || (cfg.protocol == PROT_TELNET && cfg.port != 23)
2366                          || (cfg.protocol == PROT_RLOGIN
2367                              && cfg.port != 513))) {
2368                         cfg.port = i ? 22 : j ? 23 : 513;
2369                         SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
2370                     }
2371                 }
2372                 break;
2373               case IDC_HOST:
2374                 if (HIWORD(wParam) == EN_CHANGE)
2375                     GetDlgItemText(hwnd, IDC_HOST, cfg.host,
2376                                    sizeof(cfg.host) - 1);
2377                 break;
2378               case IDC_PORT:
2379                 if (HIWORD(wParam) == EN_CHANGE) {
2380                     GetDlgItemText(hwnd, IDC_PORT, portname, 31);
2381                     if (isdigit(portname[0]))
2382                         MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
2383                     else {
2384                         service = getservbyname(portname, NULL);
2385                         if (service)
2386                             cfg.port = ntohs(service->s_port);
2387                         else
2388                             cfg.port = 0;
2389                     }
2390                 }
2391                 break;
2392               case IDC_SESSEDIT:
2393                 if (HIWORD(wParam) == EN_CHANGE) {
2394                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2395                                        (WPARAM) - 1, 0);
2396                     GetDlgItemText(hwnd, IDC_SESSEDIT,
2397                                    savedsession, sizeof(savedsession) - 1);
2398                     savedsession[sizeof(savedsession) - 1] = '\0';
2399                 }
2400                 break;
2401               case IDC_SESSSAVE:
2402                 if (HIWORD(wParam) == BN_CLICKED ||
2403                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2404                     /*
2405                      * Save a session
2406                      */
2407                     char str[2048];
2408                     GetDlgItemText(hwnd, IDC_SESSEDIT, str,
2409                                    sizeof(str) - 1);
2410                     if (!*str) {
2411                         int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2412                                                    LB_GETCURSEL, 0, 0);
2413                         if (n == LB_ERR) {
2414                             MessageBeep(0);
2415                             break;
2416                         }
2417                         strcpy(str, sesslist.sessions[n]);
2418                     }
2419                     save_settings(str, !!strcmp(str, "Default Settings"),
2420                                   &cfg);
2421                     get_sesslist(&sesslist, FALSE);
2422                     get_sesslist(&sesslist, TRUE);
2423                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2424                                        FALSE, 0);
2425                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2426                                        0, 0);
2427                     for (i = 0; i < sesslist.nsessions; i++)
2428                         SendDlgItemMessage(hwnd, IDC_SESSLIST,
2429                                            LB_ADDSTRING, 0,
2430                                            (LPARAM) (sesslist.sessions[i]));
2431                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2432                                        (WPARAM) - 1, 0);
2433                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2434                                        TRUE, 0);
2435                     InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2436                                    TRUE);
2437                 }
2438                 break;
2439               case IDC_SESSLIST:
2440               case IDC_SESSLOAD:
2441                 if (LOWORD(wParam) == IDC_SESSLIST) {
2442                     if (HIWORD(wParam) == LBN_SETFOCUS)
2443                         sesslist_has_focus = 1;
2444                     else if (HIWORD(wParam) == LBN_KILLFOCUS)
2445                         sesslist_has_focus = 0;
2446                 }
2447                 if (LOWORD(wParam) == IDC_SESSLOAD &&
2448                     HIWORD(wParam) != BN_CLICKED &&
2449                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
2450                 if (LOWORD(wParam) == IDC_SESSLIST &&
2451                     HIWORD(wParam) != LBN_DBLCLK) break;
2452                 /* Load the session selected in SESSLIST. */
2453                 if (load_selected_session(hwnd) &&
2454                     LOWORD(wParam) == IDC_SESSLIST) {
2455                     /*
2456                      * A double-click on a saved session should
2457                      * actually start the session, not just load it.
2458                      * Unless it's Default Settings or some other
2459                      * host-less set of saved settings.
2460                      */
2461                     if (*cfg.host) {
2462                         readytogo = TRUE;
2463                         SetCapture(hwnd);
2464                     }
2465                 }
2466                 break;
2467               case IDC_SESSDEL:
2468                 if (HIWORD(wParam) == BN_CLICKED ||
2469                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2470                     int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2471                                                LB_GETCURSEL, 0, 0);
2472                     if (n == LB_ERR || n == 0) {
2473                         MessageBeep(0);
2474                         break;
2475                     }
2476                     del_settings(sesslist.sessions[n]);
2477                     get_sesslist(&sesslist, FALSE);
2478                     get_sesslist(&sesslist, TRUE);
2479                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2480                                        FALSE, 0);
2481                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2482                                        0, 0);
2483                     for (i = 0; i < sesslist.nsessions; i++)
2484                         SendDlgItemMessage(hwnd, IDC_SESSLIST,
2485                                            LB_ADDSTRING, 0,
2486                                            (LPARAM) (sesslist.sessions[i]));
2487                     SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2488                                        (WPARAM) - 1, 0);
2489                     SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2490                                        TRUE, 0);
2491                     InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2492                                    TRUE);
2493                 }
2494               case IDC_PINGEDIT:
2495                 if (HIWORD(wParam) == EN_CHANGE)
2496                     MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
2497                                     &cfg.ping_interval);
2498                 break;
2499               case IDC_NODELAY:
2500                 if (HIWORD(wParam) == BN_CLICKED ||
2501                     HIWORD(wParam) == BN_DOUBLECLICKED)
2502                         cfg.tcp_nodelay =
2503                         IsDlgButtonChecked(hwnd, IDC_NODELAY);
2504                 break;
2505               case IDC_DEL008:
2506               case IDC_DEL127:
2507                 if (HIWORD(wParam) == BN_CLICKED ||
2508                     HIWORD(wParam) == BN_DOUBLECLICKED)
2509                         cfg.bksp_is_delete =
2510                         IsDlgButtonChecked(hwnd, IDC_DEL127);
2511                 break;
2512               case IDC_HOMETILDE:
2513               case IDC_HOMERXVT:
2514                 if (HIWORD(wParam) == BN_CLICKED ||
2515                     HIWORD(wParam) == BN_DOUBLECLICKED)
2516                         cfg.rxvt_homeend =
2517                         IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
2518                 break;
2519               case IDC_FUNCTILDE:
2520               case IDC_FUNCLINUX:
2521               case IDC_FUNCXTERM:
2522               case IDC_FUNCVT400:
2523               case IDC_FUNCVT100P:
2524               case IDC_FUNCSCO:
2525                 if (HIWORD(wParam) == BN_CLICKED ||
2526                     HIWORD(wParam) == BN_DOUBLECLICKED)
2527                         switch (LOWORD(wParam)) {
2528                       case IDC_FUNCTILDE:
2529                         cfg.funky_type = 0;
2530                         break;
2531                       case IDC_FUNCLINUX:
2532                         cfg.funky_type = 1;
2533                         break;
2534                       case IDC_FUNCXTERM:
2535                         cfg.funky_type = 2;
2536                         break;
2537                       case IDC_FUNCVT400:
2538                         cfg.funky_type = 3;
2539                         break;
2540                       case IDC_FUNCVT100P:
2541                         cfg.funky_type = 4;
2542                         break;
2543                       case IDC_FUNCSCO:
2544                         cfg.funky_type = 5;
2545                         break;
2546                     }
2547                 break;
2548               case IDC_KPNORMAL:
2549               case IDC_KPAPPLIC:
2550                 if (HIWORD(wParam) == BN_CLICKED ||
2551                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2552                     cfg.app_keypad =
2553                         IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
2554                     cfg.nethack_keypad = FALSE;
2555                 }
2556                 break;
2557               case IDC_KPNH:
2558                 if (HIWORD(wParam) == BN_CLICKED ||
2559                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2560                     cfg.app_keypad = FALSE;
2561                     cfg.nethack_keypad = TRUE;
2562                 }
2563                 break;
2564               case IDC_CURNORMAL:
2565               case IDC_CURAPPLIC:
2566                 if (HIWORD(wParam) == BN_CLICKED ||
2567                     HIWORD(wParam) == BN_DOUBLECLICKED)
2568                         cfg.app_cursor =
2569                         IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
2570                 break;
2571               case IDC_NOAPPLICC:
2572                 if (HIWORD(wParam) == BN_CLICKED ||
2573                     HIWORD(wParam) == BN_DOUBLECLICKED)
2574                         cfg.no_applic_c =
2575                         IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
2576                 break;
2577               case IDC_NOAPPLICK:
2578                 if (HIWORD(wParam) == BN_CLICKED ||
2579                     HIWORD(wParam) == BN_DOUBLECLICKED)
2580                         cfg.no_applic_k =
2581                         IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
2582                 break;
2583               case IDC_NOMOUSEREP:
2584                 if (HIWORD(wParam) == BN_CLICKED ||
2585                     HIWORD(wParam) == BN_DOUBLECLICKED)
2586                         cfg.no_mouse_rep =
2587                         IsDlgButtonChecked(hwnd, IDC_NOMOUSEREP);
2588                 break;
2589               case IDC_NORESIZE:
2590                 if (HIWORD(wParam) == BN_CLICKED ||
2591                     HIWORD(wParam) == BN_DOUBLECLICKED)
2592                         cfg.no_remote_resize =
2593                         IsDlgButtonChecked(hwnd, IDC_NORESIZE);
2594                 break;
2595               case IDC_NOALTSCREEN:
2596                 if (HIWORD(wParam) == BN_CLICKED ||
2597                     HIWORD(wParam) == BN_DOUBLECLICKED)
2598                         cfg.no_alt_screen =
2599                         IsDlgButtonChecked(hwnd, IDC_NOALTSCREEN);
2600                 break;
2601               case IDC_NOWINTITLE:
2602                 if (HIWORD(wParam) == BN_CLICKED ||
2603                     HIWORD(wParam) == BN_DOUBLECLICKED)
2604                         cfg.no_remote_wintitle =
2605                         IsDlgButtonChecked(hwnd, IDC_NOWINTITLE);
2606                 break;
2607               case IDC_NODBACKSPACE:
2608                 if (HIWORD(wParam) == BN_CLICKED ||
2609                     HIWORD(wParam) == BN_DOUBLECLICKED)
2610                         cfg.no_dbackspace =
2611                         IsDlgButtonChecked(hwnd, IDC_NODBACKSPACE);
2612                 break;
2613               case IDC_NOCHARSET:
2614                 if (HIWORD(wParam) == BN_CLICKED ||
2615                     HIWORD(wParam) == BN_DOUBLECLICKED)
2616                         cfg.no_remote_charset =
2617                         IsDlgButtonChecked(hwnd, IDC_NOCHARSET);
2618                 break;
2619               case IDC_ALTF4:
2620                 if (HIWORD(wParam) == BN_CLICKED ||
2621                     HIWORD(wParam) == BN_DOUBLECLICKED)
2622                         cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
2623                 break;
2624               case IDC_ALTSPACE:
2625                 if (HIWORD(wParam) == BN_CLICKED ||
2626                     HIWORD(wParam) == BN_DOUBLECLICKED)
2627                         cfg.alt_space =
2628                         IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
2629                 break;
2630               case IDC_ALTONLY:
2631                 if (HIWORD(wParam) == BN_CLICKED ||
2632                     HIWORD(wParam) == BN_DOUBLECLICKED)
2633                         cfg.alt_only =
2634                         IsDlgButtonChecked(hwnd, IDC_ALTONLY);
2635                 break;
2636               case IDC_ECHOBACKEND:
2637               case IDC_ECHOYES:
2638               case IDC_ECHONO:
2639                 if (HIWORD(wParam) == BN_CLICKED ||
2640                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2641                     if (LOWORD(wParam) == IDC_ECHOBACKEND)
2642                         cfg.localecho = LD_BACKEND;
2643                     if (LOWORD(wParam) == IDC_ECHOYES)
2644                         cfg.localecho = LD_YES;
2645                     if (LOWORD(wParam) == IDC_ECHONO)
2646                         cfg.localecho = LD_NO;
2647                 }
2648                 break;
2649               case IDC_EDITBACKEND:
2650               case IDC_EDITYES:
2651               case IDC_EDITNO:
2652                 if (HIWORD(wParam) == BN_CLICKED ||
2653                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2654                     if (LOWORD(wParam) == IDC_EDITBACKEND)
2655                         cfg.localedit = LD_BACKEND;
2656                     if (LOWORD(wParam) == IDC_EDITYES)
2657                         cfg.localedit = LD_YES;
2658                     if (LOWORD(wParam) == IDC_EDITNO)
2659                         cfg.localedit = LD_NO;
2660                 }
2661                 break;
2662               case IDC_ANSWEREDIT:
2663                 if (HIWORD(wParam) == EN_CHANGE)
2664                     GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
2665                                    sizeof(cfg.answerback) - 1);
2666                 break;
2667               case IDC_ALWAYSONTOP:
2668                 if (HIWORD(wParam) == BN_CLICKED ||
2669                     HIWORD(wParam) == BN_DOUBLECLICKED)
2670                         cfg.alwaysontop =
2671                         IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
2672                 break;
2673               case IDC_FULLSCREENONALTENTER:
2674                 if (HIWORD(wParam) == BN_CLICKED ||
2675                     HIWORD(wParam) == BN_DOUBLECLICKED)
2676                         cfg.fullscreenonaltenter =
2677                         IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER);
2678                 break;
2679               case IDC_SCROLLKEY:
2680                 if (HIWORD(wParam) == BN_CLICKED ||
2681                     HIWORD(wParam) == BN_DOUBLECLICKED)
2682                         cfg.scroll_on_key =
2683                         IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
2684                 break;
2685               case IDC_SCROLLDISP:
2686                 if (HIWORD(wParam) == BN_CLICKED ||
2687                     HIWORD(wParam) == BN_DOUBLECLICKED)
2688                         cfg.scroll_on_disp =
2689                         IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
2690                 break;
2691               case IDC_COMPOSEKEY:
2692                 if (HIWORD(wParam) == BN_CLICKED ||
2693                     HIWORD(wParam) == BN_DOUBLECLICKED)
2694                         cfg.compose_key =
2695                         IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
2696                 break;
2697               case IDC_CTRLALTKEYS:
2698                 if (HIWORD(wParam) == BN_CLICKED ||
2699                     HIWORD(wParam) == BN_DOUBLECLICKED)
2700                         cfg.ctrlaltkeys =
2701                         IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
2702                 break;
2703               case IDC_TELNETKEY:
2704                 if (HIWORD(wParam) == BN_CLICKED ||
2705                     HIWORD(wParam) == BN_DOUBLECLICKED)
2706                         cfg.telnet_keyboard =
2707                         IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
2708                 break;
2709               case IDC_TELNETRET:
2710                 if (HIWORD(wParam) == BN_CLICKED ||
2711                     HIWORD(wParam) == BN_DOUBLECLICKED)
2712                         cfg.telnet_newline =
2713                         IsDlgButtonChecked(hwnd, IDC_TELNETRET);
2714                 break;
2715               case IDC_WRAPMODE:
2716                 if (HIWORD(wParam) == BN_CLICKED ||
2717                     HIWORD(wParam) == BN_DOUBLECLICKED)
2718                         cfg.wrap_mode =
2719                         IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
2720                 break;
2721               case IDC_DECOM:
2722                 if (HIWORD(wParam) == BN_CLICKED ||
2723                     HIWORD(wParam) == BN_DOUBLECLICKED)
2724                         cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
2725                 break;
2726               case IDC_LFHASCR:
2727                 if (HIWORD(wParam) == BN_CLICKED ||
2728                     HIWORD(wParam) == BN_DOUBLECLICKED)
2729                         cfg.lfhascr =
2730                         IsDlgButtonChecked(hwnd, IDC_LFHASCR);
2731                 break;
2732               case IDC_ROWSEDIT:
2733                 if (HIWORD(wParam) == EN_CHANGE)
2734                     MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
2735                 break;
2736               case IDC_COLSEDIT:
2737                 if (HIWORD(wParam) == EN_CHANGE)
2738                     MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
2739                 break;
2740               case IDC_SAVEEDIT:
2741                 if (HIWORD(wParam) == EN_CHANGE)
2742                     MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
2743                 break;
2744               case IDC_CHOOSEFONT:
2745                 {
2746                     HDC hdc = GetDC(0);
2747                     lf.lfHeight = -MulDiv(cfg.fontheight,
2748                                           GetDeviceCaps(hdc, LOGPIXELSY),
2749                                           72);
2750                     ReleaseDC(0, hdc);
2751                 }
2752                 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
2753                 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
2754                 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
2755                 lf.lfCharSet = cfg.fontcharset;
2756                 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
2757                 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
2758                 lf.lfQuality = DEFAULT_QUALITY;
2759                 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
2760                 strncpy(lf.lfFaceName, cfg.font,
2761                         sizeof(lf.lfFaceName) - 1);
2762                 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
2763
2764                 cf.lStructSize = sizeof(cf);
2765                 cf.hwndOwner = hwnd;
2766                 cf.lpLogFont = &lf;
2767                 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
2768                     CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
2769
2770                 if (ChooseFont(&cf)) {
2771                     strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
2772                     cfg.font[sizeof(cfg.font) - 1] = '\0';
2773                     cfg.fontisbold = (lf.lfWeight == FW_BOLD);
2774                     cfg.fontcharset = lf.lfCharSet;
2775                     cfg.fontheight = cf.iPointSize / 10;
2776                     fmtfont(fontstatic);
2777                     SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
2778                 }
2779                 break;
2780               case IDC_BELL_DISABLED:
2781               case IDC_BELL_DEFAULT:
2782               case IDC_BELL_WAVEFILE:
2783               case IDC_BELL_VISUAL:
2784                 if (HIWORD(wParam) == BN_CLICKED ||
2785                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2786                     if (LOWORD(wParam) == IDC_BELL_DISABLED)
2787                         cfg.beep = BELL_DISABLED;
2788                     if (LOWORD(wParam) == IDC_BELL_DEFAULT)
2789                         cfg.beep = BELL_DEFAULT;
2790                     if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
2791                         cfg.beep = BELL_WAVEFILE;
2792                     if (LOWORD(wParam) == IDC_BELL_VISUAL)
2793                         cfg.beep = BELL_VISUAL;
2794                 }
2795                 break;
2796               case IDC_B_IND_DISABLED:
2797               case IDC_B_IND_FLASH:
2798               case IDC_B_IND_STEADY:
2799                 if (HIWORD(wParam) == BN_CLICKED ||
2800                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2801                     if (LOWORD(wParam) == IDC_B_IND_DISABLED)
2802                         cfg.beep_ind = B_IND_DISABLED;
2803                     if (LOWORD(wParam) == IDC_B_IND_FLASH)
2804                         cfg.beep_ind = B_IND_FLASH;
2805                     if (LOWORD(wParam) == IDC_B_IND_STEADY)
2806                         cfg.beep_ind = B_IND_STEADY;
2807                 }
2808                 break;
2809               case IDC_BELL_WAVEBROWSE:
2810                 memset(&of, 0, sizeof(of));
2811 #ifdef OPENFILENAME_SIZE_VERSION_400
2812                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2813 #else
2814                 of.lStructSize = sizeof(of);
2815 #endif
2816                 of.hwndOwner = hwnd;
2817                 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
2818                 of.lpstrCustomFilter = NULL;
2819                 of.nFilterIndex = 1;
2820                 of.lpstrFile = filename;
2821                 strcpy(filename, cfg.bell_wavefile);
2822                 of.nMaxFile = sizeof(filename);
2823                 of.lpstrFileTitle = NULL;
2824                 of.lpstrInitialDir = NULL;
2825                 of.lpstrTitle = "Select Bell Sound File";
2826                 of.Flags = 0;
2827                 if (GetOpenFileName(&of)) {
2828                     strcpy(cfg.bell_wavefile, filename);
2829                     SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2830                                    cfg.bell_wavefile);
2831                 }
2832                 break;
2833               case IDC_BELL_WAVEEDIT:
2834                 if (HIWORD(wParam) == EN_CHANGE)
2835                     GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2836                                    cfg.bell_wavefile,
2837                                    sizeof(cfg.bell_wavefile) - 1);
2838                 break;
2839               case IDC_BELLOVL:
2840                 if (HIWORD(wParam) == BN_CLICKED ||
2841                     HIWORD(wParam) == BN_DOUBLECLICKED)
2842                         cfg.bellovl =
2843                         IsDlgButtonChecked(hwnd, IDC_BELLOVL);
2844                 break;
2845               case IDC_BELLOVLN:
2846                 if (HIWORD(wParam) == EN_CHANGE)
2847                     MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2848                 break;
2849               case IDC_BELLOVLT:
2850                 if (HIWORD(wParam) == EN_CHANGE)
2851                     MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2852                                     1000);
2853                 break;
2854               case IDC_BELLOVLS:
2855                 if (HIWORD(wParam) == EN_CHANGE)
2856                     MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2857                                     1000);
2858                 break;
2859               case IDC_BLINKTEXT:
2860                 if (HIWORD(wParam) == BN_CLICKED ||
2861                     HIWORD(wParam) == BN_DOUBLECLICKED)
2862                         cfg.blinktext =
2863                         IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2864                 break;
2865               case IDC_BCE:
2866                 if (HIWORD(wParam) == BN_CLICKED ||
2867                     HIWORD(wParam) == BN_DOUBLECLICKED)
2868                         cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2869                 break;
2870               case IDC_WINNAME:
2871                 if (HIWORD(wParam) == BN_CLICKED ||
2872                     HIWORD(wParam) == BN_DOUBLECLICKED)
2873                         cfg.win_name_always =
2874                         IsDlgButtonChecked(hwnd, IDC_WINNAME);
2875                 break;
2876               case IDC_HIDEMOUSE:
2877                 if (HIWORD(wParam) == BN_CLICKED ||
2878                     HIWORD(wParam) == BN_DOUBLECLICKED)
2879                         cfg.hide_mouseptr =
2880                         IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2881                 break;
2882               case IDC_SUNKENEDGE:
2883                 if (HIWORD(wParam) == BN_CLICKED ||
2884                     HIWORD(wParam) == BN_DOUBLECLICKED)
2885                         cfg.sunken_edge =
2886                         IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2887                 break;
2888               case IDC_WINBEDIT:
2889                 if (HIWORD(wParam) == EN_CHANGE)
2890                     MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
2891                                     &cfg.window_border);
2892                 if (cfg.window_border > 32)
2893                     cfg.window_border = 32;
2894                 break;
2895               case IDC_CURBLOCK:
2896                 if (HIWORD(wParam) == BN_CLICKED ||
2897                     HIWORD(wParam) == BN_DOUBLECLICKED)
2898                         cfg.cursor_type = 0;
2899                 break;
2900               case IDC_CURUNDER:
2901                 if (HIWORD(wParam) == BN_CLICKED ||
2902                     HIWORD(wParam) == BN_DOUBLECLICKED)
2903                         cfg.cursor_type = 1;
2904                 break;
2905               case IDC_CURVERT:
2906                 if (HIWORD(wParam) == BN_CLICKED ||
2907                     HIWORD(wParam) == BN_DOUBLECLICKED)
2908                         cfg.cursor_type = 2;
2909                 break;
2910               case IDC_BLINKCUR:
2911                 if (HIWORD(wParam) == BN_CLICKED ||
2912                     HIWORD(wParam) == BN_DOUBLECLICKED)
2913                         cfg.blink_cur =
2914                         IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2915                 break;
2916               case IDC_SCROLLBAR:
2917                 if (HIWORD(wParam) == BN_CLICKED ||
2918                     HIWORD(wParam) == BN_DOUBLECLICKED)
2919                         cfg.scrollbar =
2920                         IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2921                 break;
2922               case IDC_SCROLLBARFULLSCREEN:
2923                 if (HIWORD(wParam) == BN_CLICKED ||
2924                     HIWORD(wParam) == BN_DOUBLECLICKED)
2925                     cfg.scrollbar_in_fullscreen =
2926                     IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN);
2927                 break;
2928               case IDC_RESIZETERM:
2929               case IDC_RESIZEFONT:
2930               case IDC_RESIZENONE:
2931               case IDC_RESIZEEITHER:
2932                 if (HIWORD(wParam) == BN_CLICKED ||
2933                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2934                     cfg.resize_action =
2935                         IsDlgButtonChecked(hwnd,
2936                                            IDC_RESIZETERM) ? RESIZE_TERM :
2937                         IsDlgButtonChecked(hwnd,
2938                                            IDC_RESIZEFONT) ? RESIZE_FONT :
2939                         IsDlgButtonChecked(hwnd,
2940                                            IDC_RESIZEEITHER) ? RESIZE_EITHER :
2941                         RESIZE_DISABLED;
2942                 }
2943                 break;
2944               case IDC_WINEDIT:
2945                 if (HIWORD(wParam) == EN_CHANGE)
2946                     GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2947                                    sizeof(cfg.wintitle) - 1);
2948                 break;
2949               case IDC_COEALWAYS:
2950               case IDC_COENEVER:
2951               case IDC_COENORMAL:
2952                 if (HIWORD(wParam) == BN_CLICKED ||
2953                     HIWORD(wParam) == BN_DOUBLECLICKED) {
2954                     cfg.close_on_exit =
2955                         IsDlgButtonChecked(hwnd,
2956                                            IDC_COEALWAYS) ? COE_ALWAYS :
2957                         IsDlgButtonChecked(hwnd,
2958                                            IDC_COENEVER) ? COE_NEVER :
2959                         COE_NORMAL;
2960                 }
2961                 break;
2962               case IDC_CLOSEWARN:
2963                 if (HIWORD(wParam) == BN_CLICKED ||
2964                     HIWORD(wParam) == BN_DOUBLECLICKED)
2965                         cfg.warn_on_close =
2966                         IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
2967                 break;
2968               case IDC_TTEDIT:
2969                 if (HIWORD(wParam) == EN_CHANGE)
2970                     GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
2971                                    sizeof(cfg.termtype) - 1);
2972                 break;
2973
2974                 /* proxy config */
2975               case IDC_PROXYHOSTEDIT:
2976                 if (HIWORD(wParam) == EN_CHANGE)
2977                     GetDlgItemText(hwnd, IDC_PROXYHOSTEDIT, cfg.proxy_host, 
2978                                    sizeof(cfg.proxy_host) - 1);
2979                 break;
2980               case IDC_PROXYPORTEDIT:
2981                 if (HIWORD(wParam) == EN_CHANGE) {
2982                     GetDlgItemText(hwnd, IDC_PROXYPORTEDIT, portname, 31);
2983                     if (isdigit(portname[0]))
2984                         MyGetDlgItemInt(hwnd, IDC_PROXYPORTEDIT, &cfg.proxy_port);
2985                     else {
2986                         service = getservbyname(portname, NULL);
2987                         if (service)
2988                             cfg.proxy_port = ntohs(service->s_port);
2989                         else
2990                             cfg.proxy_port = 0;
2991                     }
2992                 }
2993                 break;
2994               case IDC_PROXYEXCLUDEEDIT:
2995                 if (HIWORD(wParam) == EN_CHANGE)
2996                     GetDlgItemText(hwnd, IDC_PROXYEXCLUDEEDIT,
2997                                    cfg.proxy_exclude_list,
2998                                    sizeof(cfg.proxy_exclude_list) - 1);
2999                 break;
3000               case IDC_PROXYUSEREDIT:
3001                 if (HIWORD(wParam) == EN_CHANGE)
3002                     GetDlgItemText(hwnd, IDC_PROXYUSEREDIT,
3003                                    cfg.proxy_username, 
3004                                    sizeof(cfg.proxy_username) - 1);
3005                 break;
3006               case IDC_PROXYPASSEDIT:
3007                 if (HIWORD(wParam) == EN_CHANGE)
3008                     GetDlgItemText(hwnd, IDC_PROXYPASSEDIT,
3009                                    cfg.proxy_password, 
3010                                    sizeof(cfg.proxy_password) - 1);
3011                 break;
3012               case IDC_PROXYTELNETCMDEDIT:
3013                 if (HIWORD(wParam) == EN_CHANGE)
3014                     GetDlgItemText(hwnd, IDC_PROXYTELNETCMDEDIT,
3015                                    cfg.proxy_telnet_command,
3016                                    sizeof(cfg.proxy_telnet_command) - 1);
3017                 break;
3018               case IDC_PROXYSOCKSVER5:
3019               case IDC_PROXYSOCKSVER4:
3020                 if (HIWORD(wParam) == BN_CLICKED ||
3021                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3022                     cfg.proxy_socks_version =
3023                         IsDlgButtonChecked(hwnd, IDC_PROXYSOCKSVER4) ? 4 : 5;
3024                 }
3025                 break;
3026               case IDC_PROXYTYPENONE:
3027               case IDC_PROXYTYPEHTTP:
3028               case IDC_PROXYTYPESOCKS:
3029               case IDC_PROXYTYPETELNET:
3030                 if (HIWORD(wParam) == BN_CLICKED ||
3031                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3032                     cfg.proxy_type =
3033                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPEHTTP) ? PROXY_HTTP :
3034                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPESOCKS) ? PROXY_SOCKS :
3035                         IsDlgButtonChecked(hwnd, IDC_PROXYTYPETELNET) ? PROXY_TELNET :
3036                         PROXY_NONE;
3037                 }
3038                 break;
3039
3040               case IDC_LGFEDIT:
3041                 if (HIWORD(wParam) == EN_CHANGE)
3042                     GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
3043                                    sizeof(cfg.logfilename) - 1);
3044                 break;
3045               case IDC_LGFBUTTON:
3046                 memset(&of, 0, sizeof(of));
3047 #ifdef OPENFILENAME_SIZE_VERSION_400
3048                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
3049 #else
3050                 of.lStructSize = sizeof(of);
3051 #endif
3052                 of.hwndOwner = hwnd;
3053                 of.lpstrFilter = "All Files\0*\0\0\0";
3054                 of.lpstrCustomFilter = NULL;
3055                 of.nFilterIndex = 1;
3056                 of.lpstrFile = filename;
3057                 strcpy(filename, cfg.logfilename);
3058                 of.nMaxFile = sizeof(filename);
3059                 of.lpstrFileTitle = NULL;
3060                 of.lpstrInitialDir = NULL;
3061                 of.lpstrTitle = "Select session log file";
3062                 of.Flags = 0;
3063                 if (GetSaveFileName(&of)) {
3064                     strcpy(cfg.logfilename, filename);
3065                     SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
3066                 }
3067                 break;
3068               case IDC_LSTATOFF:
3069               case IDC_LSTATASCII:
3070               case IDC_LSTATRAW:
3071               case IDC_LSTATPACKET:
3072                 if (HIWORD(wParam) == BN_CLICKED ||
3073                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3074                     if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
3075                         cfg.logtype = LGTYP_NONE;
3076                     if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
3077                         cfg.logtype = LGTYP_ASCII;
3078                     if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
3079                         cfg.logtype = LGTYP_DEBUG;
3080                     if (IsDlgButtonChecked(hwnd, IDC_LSTATPACKET))
3081                         cfg.logtype = LGTYP_PACKETS;
3082                 }
3083                 break;
3084               case IDC_LSTATXASK:
3085               case IDC_LSTATXAPN:
3086               case IDC_LSTATXOVR:
3087                 if (HIWORD(wParam) == BN_CLICKED ||
3088                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3089                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
3090                         cfg.logxfovr = LGXF_ASK;
3091                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
3092                         cfg.logxfovr = LGXF_APN;
3093                     if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
3094                         cfg.logxfovr = LGXF_OVR;
3095                 }
3096                 break;
3097               case IDC_TSEDIT:
3098               case IDC_R_TSEDIT:
3099                 if (HIWORD(wParam) == EN_CHANGE)
3100                     GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
3101                                    sizeof(cfg.termspeed) - 1);
3102                 break;
3103               case IDC_LOGEDIT:
3104                 if (HIWORD(wParam) == EN_CHANGE)
3105                     GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
3106                                    sizeof(cfg.username) - 1);
3107                 break;
3108               case IDC_RLLUSEREDIT:
3109                 if (HIWORD(wParam) == EN_CHANGE)
3110                     GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
3111                                    cfg.localusername,
3112                                    sizeof(cfg.localusername) - 1);
3113                 break;
3114               case IDC_EMBSD:
3115               case IDC_EMRFC:
3116                 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
3117                 break;
3118               case IDC_TPASSIVE:
3119               case IDC_TACTIVE:
3120                 cfg.passive_telnet =
3121                     IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
3122                 break;
3123               case IDC_ENVADD:
3124                 if (HIWORD(wParam) == BN_CLICKED ||
3125                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3126                     char str[sizeof(cfg.environmt)];
3127                     char *p;
3128                     GetDlgItemText(hwnd, IDC_VAREDIT, str,
3129                                    sizeof(str) - 1);
3130                     if (!*str) {
3131                         MessageBeep(0);
3132                         break;
3133                     }
3134                     p = str + strlen(str);
3135                     *p++ = '\t';
3136                     GetDlgItemText(hwnd, IDC_VALEDIT, p,
3137                                    sizeof(str) - 1 - (p - str));
3138                     if (!*p) {
3139                         MessageBeep(0);
3140                         break;
3141                     }
3142                     p = cfg.environmt;
3143                     while (*p) {
3144                         while (*p)
3145                             p++;
3146                         p++;
3147                     }
3148                     if ((p - cfg.environmt) + strlen(str) + 2 <
3149                         sizeof(cfg.environmt)) {
3150                         strcpy(p, str);
3151                         p[strlen(str) + 1] = '\0';
3152                         SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
3153                                            0, (LPARAM) str);
3154                         SetDlgItemText(hwnd, IDC_VAREDIT, "");
3155                         SetDlgItemText(hwnd, IDC_VALEDIT, "");
3156                     } else {
3157                         MessageBox(hwnd, "Environment too big",
3158                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3159                     }
3160                 }
3161                 break;
3162               case IDC_ENVREMOVE:
3163                 if (HIWORD(wParam) != BN_CLICKED &&
3164                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
3165                 i =
3166                     SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
3167                                        0);
3168                 if (i == LB_ERR)
3169                     MessageBeep(0);
3170                 else {
3171                     char *p, *q;
3172
3173                     SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
3174                                        i, 0);
3175                     p = cfg.environmt;
3176                     while (i > 0) {
3177                         if (!*p)
3178                             goto disaster;
3179                         while (*p)
3180                             p++;
3181                         p++;
3182                         i--;
3183                     }
3184                     q = p;
3185                     if (!*p)
3186                         goto disaster;
3187                     while (*p)
3188                         p++;
3189                     p++;
3190                     while (*p) {
3191                         while (*p)
3192                             *q++ = *p++;
3193                         *q++ = *p++;
3194                     }
3195                     *q = '\0';
3196                   disaster:;
3197                 }
3198                 break;
3199               case IDC_NOPTY:
3200                 if (HIWORD(wParam) == BN_CLICKED ||
3201                     HIWORD(wParam) == BN_DOUBLECLICKED)
3202                         cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
3203                 break;
3204               case IDC_COMPRESS:
3205                 if (HIWORD(wParam) == BN_CLICKED ||
3206                     HIWORD(wParam) == BN_DOUBLECLICKED)
3207                         cfg.compression =
3208                         IsDlgButtonChecked(hwnd, IDC_COMPRESS);
3209                 break;
3210               case IDC_SSH2DES:
3211                 if (HIWORD(wParam) == BN_CLICKED ||
3212                     HIWORD(wParam) == BN_DOUBLECLICKED)
3213                         cfg.ssh2_des_cbc =
3214                         IsDlgButtonChecked(hwnd, IDC_SSH2DES);
3215                 break;
3216               case IDC_AGENTFWD:
3217                 if (HIWORD(wParam) == BN_CLICKED ||
3218                     HIWORD(wParam) == BN_DOUBLECLICKED)
3219                         cfg.agentfwd =
3220                         IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
3221                 break;
3222               case IDC_CHANGEUSER:
3223                 if (HIWORD(wParam) == BN_CLICKED ||
3224                     HIWORD(wParam) == BN_DOUBLECLICKED)
3225                         cfg.change_username =
3226                         IsDlgButtonChecked(hwnd, IDC_CHANGEUSER);
3227                 break;
3228               case IDC_CIPHERLIST:
3229               case IDC_CIPHERUP:
3230               case IDC_CIPHERDN:
3231                 handle_prefslist(&cipherlist,
3232                                  cfg.ssh_cipherlist, CIPHER_MAX,
3233                                  0, hwnd, wParam, lParam);
3234                 break;
3235               case IDC_SSHPROT1ONLY:
3236               case IDC_SSHPROT1:
3237               case IDC_SSHPROT2:
3238               case IDC_SSHPROT2ONLY:
3239                 if (HIWORD(wParam) == BN_CLICKED ||
3240                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3241                     if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1ONLY))
3242                         cfg.sshprot = 0;
3243                     if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
3244                         cfg.sshprot = 1;
3245                     else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
3246                         cfg.sshprot = 2;
3247                     else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2ONLY))
3248                         cfg.sshprot = 3;
3249                 }
3250                 break;
3251               case IDC_AUTHTIS:
3252                 if (HIWORD(wParam) == BN_CLICKED ||
3253                     HIWORD(wParam) == BN_DOUBLECLICKED)
3254                         cfg.try_tis_auth =
3255                         IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
3256                 break;
3257               case IDC_AUTHKI:
3258                 if (HIWORD(wParam) == BN_CLICKED ||
3259                     HIWORD(wParam) == BN_DOUBLECLICKED)
3260                         cfg.try_ki_auth =
3261                         IsDlgButtonChecked(hwnd, IDC_AUTHKI);
3262                 break;
3263               case IDC_PKEDIT:
3264                 if (HIWORD(wParam) == EN_CHANGE)
3265                     GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
3266                                    sizeof(cfg.keyfile) - 1);
3267                 break;
3268               case IDC_CMDEDIT:
3269                 if (HIWORD(wParam) == EN_CHANGE)
3270                     GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
3271                                    sizeof(cfg.remote_cmd) - 1);
3272                 break;
3273               case IDC_PKBUTTON:
3274                 memset(&of, 0, sizeof(of));
3275 #ifdef OPENFILENAME_SIZE_VERSION_400
3276                 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
3277 #else
3278                 of.lStructSize = sizeof(of);
3279 #endif
3280                 of.hwndOwner = hwnd;
3281                 of.lpstrFilter = "PuTTY Private Key Files\0*.PPK\0"
3282                     "AllFiles\0*\0\0\0";
3283                 of.lpstrCustomFilter = NULL;
3284                 of.nFilterIndex = 1;
3285                 of.lpstrFile = filename;
3286                 strcpy(filename, cfg.keyfile);
3287                 of.nMaxFile = sizeof(filename);
3288                 of.lpstrFileTitle = NULL;
3289                 of.lpstrInitialDir = NULL;
3290                 of.lpstrTitle = "Select Private Key File";
3291                 of.Flags = 0;
3292                 if (GetOpenFileName(&of)) {
3293                     strcpy(cfg.keyfile, filename);
3294                     SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
3295                 }
3296                 break;
3297               case IDC_RAWCNP:
3298                 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
3299                 break;
3300               case IDC_RTFPASTE:
3301                 cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE);
3302                 break;
3303               case IDC_MBWINDOWS:
3304               case IDC_MBXTERM:
3305                 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
3306                 break;
3307               case IDC_SELTYPELEX:
3308               case IDC_SELTYPERECT:
3309                 cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
3310                 break;
3311               case IDC_MOUSEOVERRIDE:
3312                 cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
3313                 break;
3314               case IDC_CCSET:
3315                 {
3316                     BOOL ok;
3317                     int i;
3318                     int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
3319
3320                     if (!ok)
3321                         MessageBeep(0);
3322                     else {
3323                         for (i = 0; i < 128; i++)
3324                             if (SendDlgItemMessage
3325                                 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
3326                                 char str[100];
3327                                 cfg.wordness[i] = n;
3328                                 SendDlgItemMessage(hwnd, IDC_CCLIST,
3329                                                    LB_DELETESTRING, i, 0);
3330                                 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
3331                                         (i >= 0x21 && i != 0x7F) ? i : ' ',
3332                                         cfg.wordness[i]);
3333                                 SendDlgItemMessage(hwnd, IDC_CCLIST,
3334                                                    LB_INSERTSTRING, i,
3335                                                    (LPARAM) str);
3336                             }
3337                     }
3338                 }
3339                 break;
3340               case IDC_BOLDCOLOUR:
3341                 if (HIWORD(wParam) == BN_CLICKED ||
3342                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3343                     int n, i;
3344                     cfg.bold_colour =
3345                         IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
3346                     SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
3347                                        FALSE, 0);
3348                     n =
3349                         SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3350                                            LB_GETCOUNT, 0, 0);
3351                     if (n != 12 + 10 * cfg.bold_colour) {
3352                         for (i = n; i-- > 0;)
3353                             SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3354                                                LB_DELETESTRING, i, 0);
3355                         for (i = 0; i < 22; i++)
3356                             if (cfg.bold_colour || permcolour[i])
3357                                 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3358                                                    LB_ADDSTRING, 0,
3359                                                    (LPARAM) colours[i]);
3360                     }
3361                     SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
3362                                        TRUE, 0);
3363                     InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
3364                                    TRUE);
3365                 }
3366                 break;
3367               case IDC_PALETTE:
3368                 if (HIWORD(wParam) == BN_CLICKED ||
3369                     HIWORD(wParam) == BN_DOUBLECLICKED)
3370                         cfg.try_palette =
3371                         IsDlgButtonChecked(hwnd, IDC_PALETTE);
3372                 break;
3373               case IDC_COLOURLIST:
3374                 if (HIWORD(wParam) == LBN_DBLCLK ||
3375                     HIWORD(wParam) == LBN_SELCHANGE) {
3376                     int i =
3377                         SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3378                                            LB_GETCURSEL,
3379                                            0, 0);
3380                     if (!cfg.bold_colour)
3381                         i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
3382                     SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
3383                                   FALSE);
3384                     SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
3385                                   FALSE);
3386                     SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
3387                                   FALSE);
3388                 }
3389                 break;
3390               case IDC_CHANGE:
3391                 if (HIWORD(wParam) == BN_CLICKED ||
3392                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3393                     static CHOOSECOLOR cc;
3394                     static DWORD custom[16] = { 0 };    /* zero initialisers */
3395                     int i =
3396                         SendDlgItemMessage(hwnd, IDC_COLOURLIST,
3397                                            LB_GETCURSEL,
3398                                            0, 0);
3399                     if (!cfg.bold_colour)
3400                         i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
3401                     cc.lStructSize = sizeof(cc);
3402                     cc.hwndOwner = hwnd;
3403                     cc.hInstance = (HWND) hinst;
3404                     cc.lpCustColors = custom;
3405                     cc.rgbResult =
3406                         RGB(cfg.colours[i][0], cfg.colours[i][1],
3407                             cfg.colours[i][2]);
3408                     cc.Flags = CC_FULLOPEN | CC_RGBINIT;
3409                     if (ChooseColor(&cc)) {
3410                         cfg.colours[i][0] =
3411                             (unsigned char) (cc.rgbResult & 0xFF);
3412                         cfg.colours[i][1] =
3413                             (unsigned char) (cc.rgbResult >> 8) & 0xFF;
3414                         cfg.colours[i][2] =
3415                             (unsigned char) (cc.rgbResult >> 16) & 0xFF;
3416                         SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
3417                                       FALSE);
3418                         SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
3419                                       FALSE);
3420                         SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
3421                                       FALSE);
3422                     }
3423                 }
3424                 break;
3425               case IDC_CODEPAGE:
3426                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3427                     int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
3428                                                    CB_GETCURSEL, 0, 0);
3429                     SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
3430                                        index, (LPARAM)cfg.line_codepage);
3431                 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
3432                     GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
3433                                    sizeof(cfg.line_codepage) - 1);
3434                 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
3435                     strcpy(cfg.line_codepage,
3436                            cp_name(decode_codepage(cfg.line_codepage)));
3437                     SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
3438                 }
3439                 break;
3440               case IDC_PRINTER:
3441                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3442                     int index = SendDlgItemMessage(hwnd, IDC_PRINTER,
3443                                                    CB_GETCURSEL, 0, 0);
3444                     SendDlgItemMessage(hwnd, IDC_PRINTER, CB_GETLBTEXT,
3445                                        index, (LPARAM)cfg.printer);
3446                 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
3447                     GetDlgItemText(hwnd, IDC_PRINTER, cfg.printer,
3448                                    sizeof(cfg.printer) - 1);
3449                 }
3450                 if (!strcmp(cfg.printer, PRINTER_DISABLED_STRING))
3451                     *cfg.printer = '\0';
3452                 break;
3453               case IDC_CAPSLOCKCYR:
3454                 if (HIWORD(wParam) == BN_CLICKED ||
3455                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3456                     cfg.xlat_capslockcyr =
3457                         IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
3458                 }
3459                 break;
3460               case IDC_VTXWINDOWS:
3461               case IDC_VTOEMANSI:
3462               case IDC_VTOEMONLY:
3463               case IDC_VTPOORMAN:
3464               case IDC_VTUNICODE:
3465                 cfg.vtmode =
3466                     (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
3467                      : IsDlgButtonChecked(hwnd,
3468                                           IDC_VTOEMANSI) ? VT_OEMANSI :
3469                      IsDlgButtonChecked(hwnd,
3470                                         IDC_VTOEMONLY) ? VT_OEMONLY :
3471                      IsDlgButtonChecked(hwnd,
3472                                         IDC_VTUNICODE) ? VT_UNICODE :
3473                      VT_POORMAN);
3474                 break;
3475               case IDC_X11_FORWARD:
3476                 if (HIWORD(wParam) == BN_CLICKED ||
3477                     HIWORD(wParam) == BN_DOUBLECLICKED)
3478                     cfg.x11_forward =
3479                     IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
3480                 break;
3481               case IDC_LPORT_ALL:
3482                 if (HIWORD(wParam) == BN_CLICKED ||
3483                     HIWORD(wParam) == BN_DOUBLECLICKED)
3484                     cfg.lport_acceptall =
3485                     IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
3486                 break;
3487               case IDC_RPORT_ALL:
3488                 if (HIWORD(wParam) == BN_CLICKED ||
3489                     HIWORD(wParam) == BN_DOUBLECLICKED)
3490                     cfg.rport_acceptall =
3491                     IsDlgButtonChecked(hwnd, IDC_RPORT_ALL);
3492                 break;
3493               case IDC_X11_DISPLAY:
3494                 if (HIWORD(wParam) == EN_CHANGE)
3495                     GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
3496                                    sizeof(cfg.x11_display) - 1);
3497                 break;
3498               case IDC_PFWDADD:
3499                 if (HIWORD(wParam) == BN_CLICKED ||
3500                     HIWORD(wParam) == BN_DOUBLECLICKED) {
3501                     char str[sizeof(cfg.portfwd)];
3502                     char *p;
3503                     if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
3504                         str[0] = 'L';
3505                     else
3506                         str[0] = 'R';
3507                     GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
3508                                    sizeof(str) - 2);
3509                     if (!str[1]) {
3510                         MessageBox(hwnd,
3511                                    "You need to specify a source port number",
3512                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3513                         break;
3514                     }
3515                     p = str + strlen(str);
3516                     *p++ = '\t';
3517                     GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
3518                                    sizeof(str) - 1 - (p - str));
3519                     if (!*p || !strchr(p, ':')) {
3520                         MessageBox(hwnd,
3521                                    "You need to specify a destination address\n"
3522                                    "in the form \"host.name:port\"",
3523                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3524                         break;
3525                     }
3526                     p = cfg.portfwd;
3527                     while (*p) {
3528                         while (*p)
3529                             p++;
3530                         p++;
3531                     }
3532                     if ((p - cfg.portfwd) + strlen(str) + 2 <
3533                         sizeof(cfg.portfwd)) {
3534                         strcpy(p, str);
3535                         p[strlen(str) + 1] = '\0';
3536                         SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
3537                                            0, (LPARAM) str);
3538                         SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
3539                         SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
3540                     } else {
3541                         MessageBox(hwnd, "Too many forwardings",
3542                                    "PuTTY Error", MB_OK | MB_ICONERROR);
3543                     }
3544                 }
3545                 break;
3546               case IDC_PFWDREMOVE:
3547                 if (HIWORD(wParam) != BN_CLICKED &&
3548                     HIWORD(wParam) != BN_DOUBLECLICKED) break;
3549                 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
3550                                        LB_GETCURSEL, 0, 0);
3551                 if (i == LB_ERR)
3552                     MessageBeep(0);
3553                 else {
3554                     char *p, *q;
3555
3556                     SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
3557                                        i, 0);
3558                     p = cfg.portfwd;
3559                     while (i > 0) {
3560                         if (!*p)
3561                             goto disaster2;
3562                         while (*p)
3563                             p++;
3564                         p++;
3565                         i--;
3566                     }
3567                     q = p;
3568                     if (!*p)
3569                         goto disaster2;
3570                     while (*p)
3571                         p++;
3572                     p++;
3573                     while (*p) {
3574                         while (*p)
3575                             *q++ = *p++;
3576                         *q++ = *p++;
3577                     }
3578                     *q = '\0';
3579                   disaster2:;
3580                 }
3581                 break;
3582               case IDC_BUGD_IGNORE1:
3583                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3584                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_IGNORE1,
3585                                                    CB_GETCURSEL, 0, 0);
3586                     cfg.sshbug_ignore1 = (index == 0 ? BUG_AUTO :
3587                                           index == 1 ? BUG_OFF : BUG_ON);
3588                 }
3589                 break;
3590               case IDC_BUGD_PLAINPW1:
3591                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3592                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_PLAINPW1,
3593                                                    CB_GETCURSEL, 0, 0);
3594                     cfg.sshbug_plainpw1 = (index == 0 ? BUG_AUTO :
3595                                            index == 1 ? BUG_OFF : BUG_ON);
3596                 }
3597                 break;
3598               case IDC_BUGD_RSA1:
3599                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3600                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSA1,
3601                                                    CB_GETCURSEL, 0, 0);
3602                     cfg.sshbug_rsa1 = (index == 0 ? BUG_AUTO :
3603                                        index == 1 ? BUG_OFF : BUG_ON);
3604                 }
3605                 break;
3606               case IDC_BUGD_HMAC2:
3607                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3608                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_HMAC2,
3609                                                    CB_GETCURSEL, 0, 0);
3610                     cfg.sshbug_hmac2 = (index == 0 ? BUG_AUTO :
3611                                         index == 1 ? BUG_OFF : BUG_ON);
3612                 }
3613                 break;
3614               case IDC_BUGD_DERIVEKEY2:
3615                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3616                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_DERIVEKEY2,
3617                                                    CB_GETCURSEL, 0, 0);
3618                     cfg.sshbug_derivekey2 = (index == 0 ? BUG_AUTO :
3619                                              index == 1 ? BUG_OFF : BUG_ON);
3620                 }
3621                 break;
3622               case IDC_BUGD_RSAPAD2:
3623                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3624                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_RSAPAD2,
3625                                                    CB_GETCURSEL, 0, 0);
3626                     cfg.sshbug_rsapad2 = (index == 0 ? BUG_AUTO :
3627                                           index == 1 ? BUG_OFF : BUG_ON);
3628                 }
3629                 break;
3630               case IDC_BUGD_DHGEX2:
3631                 if (HIWORD(wParam) == CBN_SELCHANGE) {
3632                     int index = SendDlgItemMessage(hwnd, IDC_BUGD_DHGEX2,
3633                                                    CB_GETCURSEL, 0, 0);
3634                     cfg.sshbug_dhgex2 = (index == 0 ? BUG_AUTO :
3635                                          index == 1 ? BUG_OFF : BUG_ON);
3636                 }
3637                 break;
3638             }
3639         return 0;
3640       case WM_HELP:
3641         if (help_path) {
3642             int id = ((LPHELPINFO)lParam)->iCtrlId;
3643             char *cmd = help_context_cmd(id);
3644             if (cmd) {
3645                 WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
3646                 requested_help = TRUE;
3647             } else {
3648                 MessageBeep(0);
3649             }
3650         }
3651         break;
3652       case WM_CLOSE:
3653         if (requested_help) {
3654             WinHelp(hwnd, help_path, HELP_QUIT, 0);
3655             requested_help = FALSE;
3656         }
3657         EndDialog(hwnd, 0);
3658         return 0;
3659
3660         /* Grrr Explorer will maximize Dialogs! */
3661       case WM_SIZE:
3662         if (wParam == SIZE_MAXIMIZED)
3663             force_normal(hwnd);
3664         return 0;
3665
3666       default:
3667         /*
3668          * Handle application-defined messages eg. DragListBox
3669          */
3670         /* First find out what the number is (once). */
3671         if (draglistmsg == WM_NULL)
3672             draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
3673
3674         if (msg == draglistmsg) {
3675             /* Only process once dialog is fully formed. */
3676             if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
3677               case IDC_CIPHERLIST:
3678                 return handle_prefslist(&cipherlist,
3679                                         cfg.ssh_cipherlist, CIPHER_MAX,
3680                                         1, hwnd, wParam, lParam);
3681             }
3682         }
3683         return 0;
3684
3685     }
3686     return 0;
3687 }
3688
3689 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
3690                                 WPARAM wParam, LPARAM lParam)
3691 {
3692     if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
3693     }
3694     if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
3695         EnableWindow(hwnd, 0);
3696         DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3697         EnableWindow(hwnd, 1);
3698         SetActiveWindow(hwnd);
3699     }
3700     return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
3701 }
3702
3703 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
3704                                   WPARAM wParam, LPARAM lParam)
3705 {
3706     return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
3707 }
3708
3709 void defuse_showwindow(void)
3710 {
3711     /*
3712      * Work around the fact that the app's first call to ShowWindow
3713      * will ignore the default in favour of the shell-provided
3714      * setting.
3715      */
3716     {
3717         HWND hwnd;
3718         hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
3719                             NULL, NullDlgProc);
3720         ShowWindow(hwnd, SW_HIDE);
3721         SetActiveWindow(hwnd);
3722         DestroyWindow(hwnd);
3723     }
3724 }
3725
3726 int do_config(void)
3727 {
3728     int ret;
3729
3730     get_sesslist(&sesslist, TRUE);
3731     savedsession[0] = '\0';
3732     ret =
3733         DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
3734     get_sesslist(&sesslist, FALSE);
3735
3736     return ret;
3737 }
3738
3739 int do_reconfig(HWND hwnd)
3740 {
3741     Config backup_cfg;
3742     int ret;
3743
3744     backup_cfg = cfg;                  /* structure copy */
3745     ret =
3746         DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
3747     if (!ret)
3748         cfg = backup_cfg;              /* structure copy */
3749
3750     return ret;
3751 }
3752
3753 void logevent(void *frontend, char *string)
3754 {
3755     char timebuf[40];
3756     time_t t;
3757
3758     log_eventlog(logctx, string);
3759
3760     if (nevents >= negsize) {
3761         negsize += 64;
3762         events = srealloc(events, negsize * sizeof(*events));
3763     }
3764
3765     time(&t);
3766     strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
3767              localtime(&t));
3768
3769     events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
3770     strcpy(events[nevents], timebuf);
3771     strcat(events[nevents], string);
3772     if (logbox) {
3773         int count;
3774         SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
3775                            0, (LPARAM) events[nevents]);
3776         count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
3777         SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
3778     }
3779     nevents++;
3780 }
3781
3782 void showeventlog(HWND hwnd)
3783 {
3784     if (!logbox) {
3785         logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
3786                               hwnd, LogProc);
3787         ShowWindow(logbox, SW_SHOWNORMAL);
3788     }
3789     SetActiveWindow(logbox);
3790 }
3791
3792 void showabout(HWND hwnd)
3793 {
3794     DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3795 }
3796
3797 void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
3798                          char *keystr, char *fingerprint)
3799 {
3800     int ret;
3801
3802     static const char absentmsg[] =
3803         "The server's host key is not cached in the registry. You\n"
3804         "have no guarantee that the server is the computer you\n"
3805         "think it is.\n"
3806         "The server's key fingerprint is:\n"
3807         "%s\n"
3808         "If you trust this host, hit Yes to add the key to\n"
3809         "PuTTY's cache and carry on connecting.\n"
3810         "If you want to carry on connecting just once, without\n"
3811         "adding the key to the cache, hit No.\n"
3812         "If you do not trust this host, hit Cancel to abandon the\n"
3813         "connection.\n";
3814
3815     static const char wrongmsg[] =
3816         "WARNING - POTENTIAL SECURITY BREACH!\n"
3817         "\n"
3818         "The server's host key does not match the one PuTTY has\n"
3819         "cached in the registry. This means that either the\n"
3820         "server administrator has changed the host key, or you\n"
3821         "have actually connected to another computer pretending\n"
3822         "to be the server.\n"
3823         "The new key fingerprint is:\n"
3824         "%s\n"
3825         "If you were expecting this change and trust the new key,\n"
3826         "hit Yes to update PuTTY's cache and continue connecting.\n"
3827         "If you want to carry on connecting but without updating\n"
3828         "the cache, hit No.\n"
3829         "If you want to abandon the connection completely, hit\n"
3830         "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
3831
3832     static const char mbtitle[] = "PuTTY Security Alert";
3833
3834     char message[160 +
3835         /* sensible fingerprint max size */
3836         (sizeof(absentmsg) > sizeof(wrongmsg) ?
3837          sizeof(absentmsg) : sizeof(wrongmsg))];
3838
3839     /*
3840      * Verify the key against the registry.
3841      */
3842     ret = verify_host_key(host, port, keytype, keystr);
3843
3844     if (ret == 0)                      /* success - key matched OK */
3845         return;
3846     if (ret == 2) {                    /* key was different */
3847         int mbret;
3848         sprintf(message, wrongmsg, fingerprint);
3849         mbret = MessageBox(NULL, message, mbtitle,
3850                            MB_ICONWARNING | MB_YESNOCANCEL);
3851         if (mbret == IDYES)
3852             store_host_key(host, port, keytype, keystr);
3853         if (mbret == IDCANCEL)
3854             cleanup_exit(0);
3855     }
3856     if (ret == 1) {                    /* key was absent */
3857         int mbret;
3858         sprintf(message, absentmsg, fingerprint);
3859         mbret = MessageBox(NULL, message, mbtitle,
3860                            MB_ICONWARNING | MB_YESNOCANCEL);
3861         if (mbret == IDYES)
3862             store_host_key(host, port, keytype, keystr);
3863         if (mbret == IDCANCEL)
3864             cleanup_exit(0);
3865     }
3866 }
3867
3868 /*
3869  * Ask whether the selected cipher is acceptable (since it was
3870  * below the configured 'warn' threshold).
3871  * cs: 0 = both ways, 1 = client->server, 2 = server->client
3872  */
3873 void askcipher(void *frontend, char *ciphername, int cs)
3874 {
3875     static const char mbtitle[] = "PuTTY Security Alert";
3876     static const char msg[] =
3877         "The first %.35scipher supported by the server\n"
3878         "is %.64s, which is below the configured\n"
3879         "warning threshold.\n"
3880         "Do you want to continue with this connection?\n";
3881     /* guessed cipher name + type max length */
3882     char message[100 + sizeof(msg)];
3883     int mbret;
3884
3885     sprintf(message, msg,
3886             (cs == 0) ? "" :
3887             (cs == 1) ? "client-to-server " :
3888                         "server-to-client ",
3889             ciphername);
3890     mbret = MessageBox(NULL, message, mbtitle,
3891                        MB_ICONWARNING | MB_YESNO);
3892     if (mbret == IDYES)
3893         return;
3894     else
3895         cleanup_exit(0);
3896 }
3897
3898 /*
3899  * Ask whether to wipe a session log file before writing to it.
3900  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
3901  */
3902 int askappend(void *frontend, char *filename)
3903 {
3904     static const char mbtitle[] = "PuTTY Log to File";
3905     static const char msgtemplate[] =
3906         "The session log file \"%.*s\" already exists.\n"
3907         "You can overwrite it with a new session log,\n"
3908         "append your session log to the end of it,\n"
3909         "or disable session logging for this session.\n"
3910         "Hit Yes to wipe the file, No to append to it,\n"
3911         "or Cancel to disable logging.";
3912     char message[sizeof(msgtemplate) + FILENAME_MAX];
3913     int mbret;
3914     if (cfg.logxfovr != LGXF_ASK) {
3915         return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
3916     }
3917     sprintf(message, msgtemplate, FILENAME_MAX, filename);
3918
3919     mbret = MessageBox(NULL, message, mbtitle,
3920                        MB_ICONQUESTION | MB_YESNOCANCEL);
3921     if (mbret == IDYES)
3922         return 2;
3923     else if (mbret == IDNO)
3924         return 1;
3925     else
3926         return 0;
3927 }
3928
3929 /*
3930  * Warn about the obsolescent key file format.
3931  * 
3932  * Uniquely among these functions, this one does _not_ expect a
3933  * frontend handle. This means that if PuTTY is ported to a
3934  * platform which requires frontend handles, this function will be
3935  * an anomaly. Fortunately, the problem it addresses will not have
3936  * been present on that platform, so it can plausibly be
3937  * implemented as an empty function.
3938  */
3939 void old_keyfile_warning(void)
3940 {
3941     static const char mbtitle[] = "PuTTY Key File Warning";
3942     static const char message[] =
3943         "You are loading an SSH 2 private key which has an\n"
3944         "old version of the file format. This means your key\n"
3945         "file is not fully tamperproof. Future versions of\n"
3946         "PuTTY may stop supporting this private key format,\n"
3947         "so we recommend you convert your key to the new\n"
3948         "format.\n"
3949         "\n"
3950         "You can perform this conversion by loading the key\n"
3951         "into PuTTYgen and then saving it again.";
3952
3953     MessageBox(NULL, message, mbtitle, MB_OK);
3954 }