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