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