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