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