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