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