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