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