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