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