Jeremy Sawicki's fix for the multiple-conflicting-accelerators
[u/mdw/putty] / windlg.c
1 #include <windows.h>
2 #include <commctrl.h>
3 #include <commdlg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include "ssh.h"
8 #include "putty.h"
9 #include "winstuff.h"
10 #include "win_res.h"
11 #include "storage.h"
12
13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
15
16 static HWND logbox = NULL, abtbox = NULL;
17
18 static int readytogo;
19
20 void force_normal(HWND hwnd)
21 {
22 static int recurse = 0;
23
24 WINDOWPLACEMENT wp;
25
26 if(recurse) return;
27 recurse = 1;
28
29 wp.length = sizeof(wp);
30 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED)
31 {
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
34 }
35 recurse = 0;
36 }
37
38 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
39 BOOL ok;
40 int n;
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
42 if (ok)
43 *result = n;
44 }
45
46 static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
48 int i;
49
50 switch (msg) {
51 case WM_INITDIALOG:
52 for (i=0; i<nevents; i++)
53 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
54 0, (LPARAM)events[i]);
55 return 1;
56 case WM_COMMAND:
57 switch (LOWORD(wParam)) {
58 case IDOK:
59 logbox = NULL;
60 DestroyWindow (hwnd);
61 return 0;
62 case IDN_COPY:
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
65 int selcount;
66 int *selitems;
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
69 selitems = smalloc(selcount * sizeof(int));
70 if (selitems) {
71 int count = SendDlgItemMessage(hwnd, IDN_LIST,
72 LB_GETSELITEMS,
73 selcount, (LPARAM)selitems);
74 int i;
75 int size;
76 char *clipdata;
77 static unsigned char sel_nl[] = SEL_NL;
78
79 if (count == 0) { /* can't copy zero stuff */
80 MessageBeep(0);
81 break;
82 }
83
84 size = 0;
85 for (i = 0; i < count; i++)
86 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
87
88 clipdata = smalloc(size);
89 if (clipdata) {
90 char *p = clipdata;
91 for (i = 0; i < count; i++) {
92 char *q = events[selitems[i]];
93 int qlen = strlen(q);
94 memcpy(p, q, qlen);
95 p += qlen;
96 memcpy(p, sel_nl, sizeof(sel_nl));
97 p += sizeof(sel_nl);
98 }
99 write_clip(clipdata, size, TRUE);
100 sfree(clipdata);
101 }
102 sfree(selitems);
103
104 for (i = 0; i < nevents; i++)
105 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
106 FALSE, i);
107 }
108 }
109 return 0;
110 }
111 return 0;
112 case WM_CLOSE:
113 logbox = NULL;
114 DestroyWindow (hwnd);
115 return 0;
116 }
117 return 0;
118 }
119
120 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
121 WPARAM wParam, LPARAM lParam) {
122 switch (msg) {
123 case WM_INITDIALOG:
124 return 1;
125 case WM_COMMAND:
126 switch (LOWORD(wParam)) {
127 case IDOK:
128 EndDialog(hwnd, 1);
129 return 0;
130 }
131 return 0;
132 case WM_CLOSE:
133 EndDialog(hwnd, 1);
134 return 0;
135 }
136 return 0;
137 }
138
139 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
140 WPARAM wParam, LPARAM lParam) {
141 switch (msg) {
142 case WM_INITDIALOG:
143 SetDlgItemText (hwnd, IDA_VERSION, ver);
144 return 1;
145 case WM_COMMAND:
146 switch (LOWORD(wParam)) {
147 case IDOK:
148 abtbox = NULL;
149 DestroyWindow (hwnd);
150 return 0;
151 case IDA_LICENCE:
152 EnableWindow(hwnd, 0);
153 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
154 NULL, LicenceProc);
155 EnableWindow(hwnd, 1);
156 SetActiveWindow(hwnd);
157 return 0;
158 }
159 return 0;
160 case WM_CLOSE:
161 abtbox = NULL;
162 DestroyWindow (hwnd);
163 return 0;
164 }
165 return 0;
166 }
167
168 /*
169 * Null dialog procedure.
170 */
171 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
172 WPARAM wParam, LPARAM lParam) {
173 return 0;
174 }
175
176 static char savedsession[2048];
177
178 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
179
180 sessionpanelstart,
181 IDC_TITLE_SESSION,
182 IDC_BOX_SESSION1,
183 IDC_BOX_SESSION2,
184 IDC_BOX_SESSION3,
185 IDC_HOSTSTATIC,
186 IDC_HOST,
187 IDC_PORTSTATIC,
188 IDC_PORT,
189 IDC_PROTSTATIC,
190 IDC_PROTRAW,
191 IDC_PROTTELNET,
192 IDC_PROTRLOGIN,
193 IDC_PROTSSH,
194 IDC_SESSSTATIC,
195 IDC_SESSEDIT,
196 IDC_SESSLIST,
197 IDC_SESSLOAD,
198 IDC_SESSSAVE,
199 IDC_SESSDEL,
200 IDC_CLOSEEXIT,
201 sessionpanelend,
202
203 keyboardpanelstart,
204 IDC_TITLE_KEYBOARD,
205 IDC_BOX_KEYBOARD1,
206 IDC_BOX_KEYBOARD2,
207 IDC_BOX_KEYBOARD3,
208 IDC_DELSTATIC,
209 IDC_DEL008,
210 IDC_DEL127,
211 IDC_HOMESTATIC,
212 IDC_HOMETILDE,
213 IDC_HOMERXVT,
214 IDC_FUNCSTATIC,
215 IDC_FUNCTILDE,
216 IDC_FUNCLINUX,
217 IDC_FUNCXTERM,
218 IDC_FUNCVT400,
219 IDC_KPSTATIC,
220 IDC_KPNORMAL,
221 IDC_KPAPPLIC,
222 IDC_KPNH,
223 IDC_NOAPPLICK,
224 IDC_NOAPPLICC,
225 IDC_CURSTATIC,
226 IDC_CURNORMAL,
227 IDC_CURAPPLIC,
228 IDC_COMPOSEKEY,
229 keyboardpanelend,
230
231 terminalpanelstart,
232 IDC_TITLE_TERMINAL,
233 IDC_BOX_TERMINAL1,
234 IDC_BOX_TERMINAL2,
235 IDC_WRAPMODE,
236 IDC_DECOM,
237 IDC_LFHASCR,
238 IDC_BEEP,
239 IDC_BCE,
240 IDC_BLINKTEXT,
241 IDC_LDISCTERM,
242 IDC_LSTATSTATIC,
243 IDC_LSTATOFF,
244 IDC_LSTATASCII,
245 IDC_LSTATRAW,
246 IDC_LGFSTATIC,
247 IDC_LGFEDIT,
248 IDC_LGFBUTTON,
249 terminalpanelend,
250
251 windowpanelstart,
252 IDC_TITLE_WINDOW,
253 IDC_BOX_WINDOW1,
254 IDC_BOX_WINDOW2,
255 IDC_BOX_WINDOW3,
256 IDC_ROWSSTATIC,
257 IDC_ROWSEDIT,
258 IDC_COLSSTATIC,
259 IDC_COLSEDIT,
260 IDC_LOCKSIZE,
261 IDC_SCROLLBAR,
262 IDC_CLOSEWARN,
263 IDC_SAVESTATIC,
264 IDC_SAVEEDIT,
265 IDC_ALTF4,
266 IDC_ALTSPACE,
267 IDC_ALTONLY,
268 IDC_SCROLLKEY,
269 IDC_SCROLLDISP,
270 IDC_ALWAYSONTOP,
271 windowpanelend,
272
273 appearancepanelstart,
274 IDC_TITLE_APPEARANCE,
275 IDC_BOX_APPEARANCE1,
276 IDC_BOX_APPEARANCE2,
277 IDC_BOX_APPEARANCE3,
278 IDC_BOX_APPEARANCE4,
279 IDC_CURSORSTATIC,
280 IDC_CURBLOCK,
281 IDC_CURUNDER,
282 IDC_CURVERT,
283 IDC_BLINKCUR,
284 IDC_FONTSTATIC,
285 IDC_CHOOSEFONT,
286 IDC_WINTITLE,
287 IDC_WINEDIT,
288 IDC_WINNAME,
289 IDC_HIDEMOUSE,
290 appearancepanelend,
291
292 connectionpanelstart,
293 IDC_TITLE_CONNECTION,
294 IDC_BOX_CONNECTION1,
295 IDC_BOX_CONNECTION2,
296 IDC_TTSTATIC,
297 IDC_TTEDIT,
298 IDC_LOGSTATIC,
299 IDC_LOGEDIT,
300 IDC_PINGSTATIC,
301 IDC_PINGEDIT,
302 connectionpanelend,
303
304 telnetpanelstart,
305 IDC_TITLE_TELNET,
306 IDC_BOX_TELNET1,
307 IDC_BOX_TELNET2,
308 IDC_TSSTATIC,
309 IDC_TSEDIT,
310 IDC_ENVSTATIC,
311 IDC_VARSTATIC,
312 IDC_VAREDIT,
313 IDC_VALSTATIC,
314 IDC_VALEDIT,
315 IDC_ENVLIST,
316 IDC_ENVADD,
317 IDC_ENVREMOVE,
318 IDC_EMSTATIC,
319 IDC_EMBSD,
320 IDC_EMRFC,
321 telnetpanelend,
322
323 rloginpanelstart,
324 IDC_TITLE_RLOGIN,
325 IDC_BOX_RLOGIN1,
326 IDC_BOX_RLOGIN2,
327 IDC_R_TSSTATIC,
328 IDC_R_TSEDIT,
329 IDC_RLLUSERSTATIC,
330 IDC_RLLUSEREDIT,
331 rloginpanelend,
332
333 sshpanelstart,
334 IDC_TITLE_SSH,
335 IDC_BOX_SSH1,
336 IDC_BOX_SSH2,
337 IDC_BOX_SSH3,
338 IDC_NOPTY,
339 IDC_CIPHERSTATIC,
340 IDC_CIPHER3DES,
341 IDC_CIPHERBLOWF,
342 IDC_CIPHERDES,
343 IDC_BUGGYMAC,
344 IDC_AUTHTIS,
345 IDC_PKSTATIC,
346 IDC_PKEDIT,
347 IDC_PKBUTTON,
348 IDC_SSHPROTSTATIC,
349 IDC_SSHPROT1,
350 IDC_SSHPROT2,
351 IDC_AGENTFWD,
352 IDC_CMDSTATIC,
353 IDC_CMDEDIT,
354 IDC_COMPRESS,
355 sshpanelend,
356
357 selectionpanelstart,
358 IDC_TITLE_SELECTION,
359 IDC_BOX_SELECTION1,
360 IDC_BOX_SELECTION2,
361 IDC_MBSTATIC,
362 IDC_MBWINDOWS,
363 IDC_MBXTERM,
364 IDC_CCSTATIC,
365 IDC_CCLIST,
366 IDC_CCSET,
367 IDC_CCSTATIC2,
368 IDC_CCEDIT,
369 selectionpanelend,
370
371 colourspanelstart,
372 IDC_TITLE_COLOURS,
373 IDC_BOX_COLOURS1,
374 IDC_BOX_COLOURS2,
375 IDC_BOLDCOLOUR,
376 IDC_PALETTE,
377 IDC_COLOURSTATIC,
378 IDC_COLOURLIST,
379 IDC_RSTATIC,
380 IDC_GSTATIC,
381 IDC_BSTATIC,
382 IDC_RVALUE,
383 IDC_GVALUE,
384 IDC_BVALUE,
385 IDC_CHANGE,
386 colourspanelend,
387
388 translationpanelstart,
389 IDC_TITLE_TRANSLATION,
390 IDC_BOX_TRANSLATION1,
391 IDC_BOX_TRANSLATION2,
392 IDC_BOX_TRANSLATION3,
393 IDC_XLATSTATIC,
394 IDC_NOXLAT,
395 IDC_KOI8WIN1251,
396 IDC_88592WIN1250,
397 IDC_88592CP852,
398 IDC_CAPSLOCKCYR,
399 IDC_VTSTATIC,
400 IDC_VTXWINDOWS,
401 IDC_VTOEMANSI,
402 IDC_VTOEMONLY,
403 IDC_VTPOORMAN,
404 translationpanelend,
405
406 tunnelspanelstart,
407 IDC_TITLE_TUNNELS,
408 IDC_BOX_TUNNELS,
409 IDC_X11_FORWARD,
410 IDC_X11_DISPSTATIC,
411 IDC_X11_DISPLAY,
412 tunnelspanelend,
413
414 controlendvalue
415 };
416
417 static const char *const colours[] = {
418 "Default Foreground", "Default Bold Foreground",
419 "Default Background", "Default Bold Background",
420 "Cursor Text", "Cursor Colour",
421 "ANSI Black", "ANSI Black Bold",
422 "ANSI Red", "ANSI Red Bold",
423 "ANSI Green", "ANSI Green Bold",
424 "ANSI Yellow", "ANSI Yellow Bold",
425 "ANSI Blue", "ANSI Blue Bold",
426 "ANSI Magenta", "ANSI Magenta Bold",
427 "ANSI Cyan", "ANSI Cyan Bold",
428 "ANSI White", "ANSI White Bold"
429 };
430 static const int permcolour[] = {
431 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
432 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
433 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
434 };
435
436 static void fmtfont (char *buf) {
437 sprintf (buf, "Font: %s, ", cfg.font);
438 if (cfg.fontisbold)
439 strcat(buf, "bold, ");
440 if (cfg.fontheight == 0)
441 strcat (buf, "default height");
442 else
443 sprintf (buf+strlen(buf), "%d-%s",
444 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
445 (cfg.fontheight < 0 ? "pixel" : "point"));
446 }
447
448 static void init_dlg_ctrls(HWND hwnd) {
449 int i;
450 char fontstatic[256];
451
452 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
453 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
454 {
455 int i, n;
456 n = SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
457 for (i=n; i-- >0 ;)
458 SendDlgItemMessage (hwnd, IDC_SESSLIST,
459 LB_DELETESTRING, i, 0);
460 for (i = 0; i < nsessions; i++)
461 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
462 0, (LPARAM) (sessions[i]));
463 }
464 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
465 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
466 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
467 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
468 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
469 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
470
471 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
472 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
473 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
474 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
475 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
476 cfg.funky_type == 0 ? IDC_FUNCTILDE :
477 cfg.funky_type == 1 ? IDC_FUNCLINUX :
478 cfg.funky_type == 2 ? IDC_FUNCXTERM :
479 cfg.funky_type == 3 ? IDC_FUNCVT400 :
480 IDC_FUNCTILDE );
481 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
482 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
483 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
484 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
485 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
486 cfg.nethack_keypad ? IDC_KPNH :
487 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
488 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
489 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
490 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
491 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
492 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
493 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
494 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
495 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
496
497 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
498 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
499 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
500 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
501 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
502 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
503 fmtfont (fontstatic);
504 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
505 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
506 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
507 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
508
509 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
510 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
511 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
512 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
513 cfg.cursor_type==0 ? IDC_CURBLOCK :
514 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
515 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
516 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
517 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
518 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
519 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
520
521 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
522 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
523 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
524 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
525 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
526 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
527 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
528 cfg.logtype == 0 ? IDC_LSTATOFF :
529 cfg.logtype == 1 ? IDC_LSTATASCII :
530 IDC_LSTATRAW);
531 {
532 char *p = cfg.environmt;
533 while (*p) {
534 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
535 (LPARAM) p);
536 p += strlen(p)+1;
537 }
538 }
539 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
540 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
541
542 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
543 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
544 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
545 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
546 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
547 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
548 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
549 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
550 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
551 IDC_CIPHER3DES);
552 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
553 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
554 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
555 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
556 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
557
558 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
559 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
560 {
561 static int tabs[4] = {25, 61, 96, 128};
562 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
563 (LPARAM) tabs);
564 }
565 for (i=0; i<256; i++) {
566 char str[100];
567 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
568 (i>=0x21 && i != 0x7F) ? i : ' ',
569 cfg.wordness[i]);
570 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
571 (LPARAM) str);
572 }
573
574 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
575 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
576 {
577 int i, n;
578 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
579 for (i=n; i-- >0 ;)
580 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
581 LB_DELETESTRING, i, 0);
582 for (i=0; i<22; i++)
583 if (cfg.bold_colour || permcolour[i])
584 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
585 (LPARAM) colours[i]);
586 }
587 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
588 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
589 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
590 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
591
592 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
593 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
594 cfg.xlat_88592cp852 ? IDC_88592CP852 :
595 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
596 IDC_NOXLAT);
597 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
598 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
599 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
600 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
601 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
602 IDC_VTPOORMAN);
603
604 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
605 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
606 }
607
608 struct treeview_faff {
609 HWND treeview;
610 HTREEITEM lastat[4];
611 };
612
613 static HTREEITEM treeview_insert(struct treeview_faff *faff,
614 int level, char *text) {
615 TVINSERTSTRUCT ins;
616 int i;
617 HTREEITEM newitem;
618 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
619 ins.hInsertAfter = faff->lastat[level];
620 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
621 #define INSITEM DUMMYUNIONNAME.item
622 #else
623 #define INSITEM item
624 #endif
625 ins.INSITEM.mask = TVIF_TEXT;
626 ins.INSITEM.pszText = text;
627 newitem = TreeView_InsertItem(faff->treeview, &ins);
628 if (level > 0)
629 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
630 faff->lastat[level] = newitem;
631 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
632 return newitem;
633 }
634
635 /*
636 * Create the panelfuls of controls in the configuration box.
637 */
638 static void create_controls(HWND hwnd, int dlgtype, int panel) {
639 if (panel == sessionpanelstart) {
640 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
641 struct ctlpos cp;
642 ctlposinit(&cp, hwnd, 80, 3, 13);
643 bartitle(&cp, "Basic options for your PuTTY session",
644 IDC_TITLE_SESSION);
645 if (dlgtype == 0) {
646 beginbox(&cp, "Specify your connection by host name",
647 IDC_BOX_SESSION1);
648 multiedit(&cp,
649 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
650 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
651 if (backends[3].backend == NULL) {
652 /* this is PuTTYtel, so only three protocols available */
653 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
654 "&Raw", IDC_PROTRAW,
655 "&Telnet", IDC_PROTTELNET,
656 "R&login", IDC_PROTRLOGIN, NULL);
657 } else {
658 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
659 "&Raw", IDC_PROTRAW,
660 "&Telnet", IDC_PROTTELNET,
661 "R&login", IDC_PROTRLOGIN,
662 #ifdef FWHACK
663 "SS&H/hack",
664 #else
665 "SS&H",
666 #endif
667 IDC_PROTSSH, NULL);
668 }
669 endbox(&cp);
670 beginbox(&cp, "Load, save or delete a stored session",
671 IDC_BOX_SESSION2);
672 sesssaver(&cp, "Sav&ed Sessions",
673 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
674 "&Load", IDC_SESSLOAD,
675 "&Save", IDC_SESSSAVE,
676 "&Delete", IDC_SESSDEL, NULL);
677 endbox(&cp);
678 }
679 beginbox(&cp, NULL, IDC_BOX_SESSION3);
680 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
681 endbox(&cp);
682 }
683
684 if (panel == terminalpanelstart) {
685 /* The Terminal panel. Accelerators used: [acgo] &dflbenuw */
686 struct ctlpos cp;
687 ctlposinit(&cp, hwnd, 80, 3, 13);
688 bartitle(&cp, "Options controlling the terminal emulation",
689 IDC_TITLE_TERMINAL);
690 beginbox(&cp, "Set various terminal options",
691 IDC_BOX_TERMINAL1);
692 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
693 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
694 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
695 checkbox(&cp, "&Beep enabled", IDC_BEEP);
696 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
697 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
698 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
699 endbox(&cp);
700
701 beginbox(&cp, "Control session logging",
702 IDC_BOX_TERMINAL2);
703 radiobig(&cp,
704 "Session logging:", IDC_LSTATSTATIC,
705 "Logging turned &off completely", IDC_LSTATOFF,
706 "Log printable output only", IDC_LSTATASCII,
707 "Log all session output", IDC_LSTATRAW, NULL);
708 editbutton(&cp, "Log &file name:",
709 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
710 IDC_LGFBUTTON);
711 endbox(&cp);
712 }
713
714 if (panel == keyboardpanelstart) {
715 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
716 struct ctlpos cp;
717 ctlposinit(&cp, hwnd, 80, 3, 13);
718 bartitle(&cp, "Options controlling the effects of keys",
719 IDC_TITLE_KEYBOARD);
720 beginbox(&cp, "Change the sequences sent by:",
721 IDC_BOX_KEYBOARD1);
722 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
723 "Control-&H", IDC_DEL008,
724 "Control-&? (127)", IDC_DEL127, NULL);
725 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
726 "&Standard", IDC_HOMETILDE,
727 "&rxvt", IDC_HOMERXVT, NULL);
728 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
729 "ESC[n&~", IDC_FUNCTILDE,
730 "&Linux", IDC_FUNCLINUX,
731 "&Xterm R6", IDC_FUNCXTERM,
732 "&VT400", IDC_FUNCVT400, NULL);
733 endbox(&cp);
734 beginbox(&cp, "Application keypad settings:",
735 IDC_BOX_KEYBOARD2);
736 checkbox(&cp,
737 "Application c&ursor keys totally disabled",
738 IDC_NOAPPLICC);
739 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
740 "&Normal", IDC_CURNORMAL,
741 "A&pplication", IDC_CURAPPLIC, NULL);
742 checkbox(&cp,
743 "Application ke&ypad keys totally disabled",
744 IDC_NOAPPLICK);
745 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
746 "Nor&mal", IDC_KPNORMAL,
747 "Appl&ication", IDC_KPAPPLIC,
748 "N&etHack", IDC_KPNH, NULL);
749 endbox(&cp);
750 beginbox(&cp, "Enable extra keyboard features:",
751 IDC_BOX_KEYBOARD3);
752 checkbox(&cp, "Application and AltGr ac&t as Compose key",
753 IDC_COMPOSEKEY);
754 endbox(&cp);
755 }
756
757 if (panel == windowpanelstart) {
758 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
759 struct ctlpos cp;
760 ctlposinit(&cp, hwnd, 80, 3, 13);
761 bartitle(&cp, "Options controlling PuTTY's window",
762 IDC_TITLE_WINDOW);
763 beginbox(&cp, "Set the size of the window",
764 IDC_BOX_WINDOW1);
765 multiedit(&cp,
766 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
767 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
768 NULL);
769 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
770 endbox(&cp);
771 beginbox(&cp, "Control the scrollback in the window",
772 IDC_BOX_WINDOW2);
773 staticedit(&cp, "Lines of &scrollback",
774 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
775 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
776 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
777 checkbox(&cp, "Reset scrollback on dis&play activity",
778 IDC_SCROLLDISP);
779 endbox(&cp);
780 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
781 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
782 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
783 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
784 checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
785 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
786 endbox(&cp);
787 }
788
789 if (panel == appearancepanelstart) {
790 /* The Appearance panel. Accelerators used: [acgo] rmkhtibluv */
791 struct ctlpos cp;
792 ctlposinit(&cp, hwnd, 80, 3, 13);
793 bartitle(&cp, "Options controlling PuTTY's appearance",
794 IDC_TITLE_APPEARANCE);
795 beginbox(&cp, "Adjust the use of the cursor",
796 IDC_BOX_APPEARANCE1);
797 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
798 "B&lock", IDC_CURBLOCK,
799 "&Underline", IDC_CURUNDER,
800 "&Vertical line", IDC_CURVERT,
801 NULL);
802 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
803 endbox(&cp);
804 beginbox(&cp, "Set the font used in the terminal window",
805 IDC_BOX_APPEARANCE2);
806 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
807 endbox(&cp);
808 beginbox(&cp, "Adjust the use of the window title",
809 IDC_BOX_APPEARANCE3);
810 multiedit(&cp,
811 "Window &title:", IDC_WINTITLE,
812 IDC_WINEDIT, 100, NULL);
813 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
814 endbox(&cp);
815 beginbox(&cp, "Adjust the use of the mouse pointer",
816 IDC_BOX_APPEARANCE4);
817 checkbox(&cp, "Hide mouse &pointer when typing in window",
818 IDC_HIDEMOUSE);
819 endbox(&cp);
820 }
821
822 if (panel == translationpanelstart) {
823 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
824 struct ctlpos cp;
825 ctlposinit(&cp, hwnd, 80, 3, 13);
826 bartitle(&cp, "Options controlling character set translation",
827 IDC_TITLE_TRANSLATION);
828 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
829 IDC_BOX_TRANSLATION1);
830 radiobig(&cp,
831 "Handling of line drawing characters:", IDC_VTSTATIC,
832 "Font has &XWindows encoding", IDC_VTXWINDOWS,
833 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
834 "Use font in O&EM mode only", IDC_VTOEMONLY,
835 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
836 IDC_VTPOORMAN, NULL);
837 endbox(&cp);
838 beginbox(&cp, "Enable character set translation on received data",
839 IDC_BOX_TRANSLATION2);
840 radiobig(&cp,
841 "Character set translation:", IDC_XLATSTATIC,
842 "&None", IDC_NOXLAT,
843 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
844 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
845 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
846 endbox(&cp);
847 beginbox(&cp, "Enable character set translation on input data",
848 IDC_BOX_TRANSLATION3);
849 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
850 IDC_CAPSLOCKCYR);
851 endbox(&cp);
852 }
853
854 if (panel == selectionpanelstart) {
855 /* The Selection panel. Accelerators used: [acgo] wxst */
856 struct ctlpos cp;
857 ctlposinit(&cp, hwnd, 80, 3, 13);
858 bartitle(&cp, "Options controlling copy and paste",
859 IDC_TITLE_SELECTION);
860 beginbox(&cp, "Control which mouse button does which thing",
861 IDC_BOX_SELECTION1);
862 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
863 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
864 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
865 NULL);
866 endbox(&cp);
867 beginbox(&cp, "Control the select-one-word-at-a-time mode",
868 IDC_BOX_SELECTION2);
869 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
870 "&Set", IDC_CCSET, IDC_CCEDIT,
871 "&to class", IDC_CCSTATIC2);
872 endbox(&cp);
873 }
874
875 if (panel == colourspanelstart) {
876 /* The Colours panel. Accelerators used: [acgo] blum */
877 struct ctlpos cp;
878 ctlposinit(&cp, hwnd, 80, 3, 13);
879 bartitle(&cp, "Options controlling use of colours",
880 IDC_TITLE_COLOURS);
881 beginbox(&cp, "General options for colour usage",
882 IDC_BOX_COLOURS1);
883 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
884 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
885 endbox(&cp);
886 beginbox(&cp, "Adjust the precise colours PuTTY displays",
887 IDC_BOX_COLOURS2);
888 colouredit(&cp, "Select a colo&ur and then click to modify it:",
889 IDC_COLOURSTATIC, IDC_COLOURLIST,
890 "&Modify...", IDC_CHANGE,
891 "Red:", IDC_RSTATIC, IDC_RVALUE,
892 "Green:", IDC_GSTATIC, IDC_GVALUE,
893 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
894 endbox(&cp);
895 }
896
897 if (panel == connectionpanelstart) {
898 /* The Connection panel. Accelerators used: [acgo] tuk */
899 struct ctlpos cp;
900 ctlposinit(&cp, hwnd, 80, 3, 13);
901 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
902 if (dlgtype == 0) {
903 beginbox(&cp, "Data to send to the server",
904 IDC_BOX_CONNECTION1);
905 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
906 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
907 endbox(&cp);
908 }
909 beginbox(&cp, "Sending of null packets to keep session active",
910 IDC_BOX_CONNECTION2);
911 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
912 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
913 endbox(&cp);
914 }
915
916 if (panel == telnetpanelstart) {
917 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
918 struct ctlpos cp;
919 ctlposinit(&cp, hwnd, 80, 3, 13);
920 if (dlgtype == 0) {
921 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
922 beginbox(&cp, "Data to send to the server",
923 IDC_BOX_TELNET1);
924 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
925 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
926 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
927 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
928 IDC_ENVLIST,
929 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
930 endbox(&cp);
931 beginbox(&cp, "Telnet protocol adjustments",
932 IDC_BOX_TELNET2);
933 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
934 "&BSD (commonplace)", IDC_EMBSD,
935 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
936 endbox(&cp);
937 }
938 }
939
940 if (panel == rloginpanelstart) {
941 /* The Rlogin panel. Accelerators used: [acgo] sl */
942 struct ctlpos cp;
943 ctlposinit(&cp, hwnd, 80, 3, 13);
944 if (dlgtype == 0) {
945 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
946 beginbox(&cp, "Data to send to the server",
947 IDC_BOX_RLOGIN1);
948 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
949 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
950 endbox(&cp);
951 }
952 }
953
954 if (panel == sshpanelstart) {
955 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
956 struct ctlpos cp;
957 ctlposinit(&cp, hwnd, 80, 3, 13);
958 if (dlgtype == 0) {
959 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
960 beginbox(&cp, "Data to send to the server",
961 IDC_BOX_SSH1);
962 multiedit(&cp,
963 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
964 NULL);
965 endbox(&cp);
966 beginbox(&cp, "Authentication options",
967 IDC_BOX_SSH2);
968 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
969 IDC_AUTHTIS);
970 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
971 editbutton(&cp, "Private &key file for authentication:",
972 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
973 endbox(&cp);
974 beginbox(&cp, "Protocol options",
975 IDC_BOX_SSH3);
976 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
977 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
978 radioline(&cp, "Preferred SSH protocol version:",
979 IDC_SSHPROTSTATIC, 2,
980 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
981 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
982 "&3DES", IDC_CIPHER3DES,
983 "&Blowfish", IDC_CIPHERBLOWF,
984 "&DES", IDC_CIPHERDES, NULL);
985 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
986 IDC_BUGGYMAC);
987 endbox(&cp);
988 }
989 }
990
991 if (panel == tunnelspanelstart) {
992 /* The Tunnels panel. Accelerators used: [acgo] ex */
993 struct ctlpos cp;
994 ctlposinit(&cp, hwnd, 80, 3, 13);
995 if (dlgtype == 0) {
996 bartitle(&cp, "Options controlling SSH tunnelling",
997 IDC_TITLE_TUNNELS);
998 beginbox(&cp, "X11 forwarding options",
999 IDC_BOX_TUNNELS);
1000 checkbox(&cp, "&Enable X11 forwarding",
1001 IDC_X11_FORWARD);
1002 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1003 IDC_X11_DISPLAY, 50, NULL);
1004 endbox(&cp);
1005 }
1006 }
1007 }
1008
1009 /*
1010 * This function is the configuration box.
1011 */
1012 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1013 WPARAM wParam, LPARAM lParam,
1014 int dlgtype) {
1015 HWND hw, treeview;
1016 struct treeview_faff tvfaff;
1017 HTREEITEM hsession;
1018 OPENFILENAME of;
1019 char filename[sizeof(cfg.keyfile)];
1020 CHOOSEFONT cf;
1021 LOGFONT lf;
1022 char fontstatic[256];
1023 char portname[32];
1024 struct servent * service;
1025 int i;
1026
1027 switch (msg) {
1028 case WM_INITDIALOG:
1029 readytogo = 0;
1030 SetWindowLong(hwnd, GWL_USERDATA, 0);
1031 /*
1032 * Centre the window.
1033 */
1034 { /* centre the window */
1035 RECT rs, rd;
1036
1037 hw = GetDesktopWindow();
1038 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1039 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1040 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1041 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1042 }
1043
1044 /*
1045 * Create the tree view.
1046 */
1047 {
1048 RECT r;
1049 WPARAM font;
1050 HWND tvstatic;
1051
1052 r.left = 3; r.right = r.left + 75;
1053 r.top = 3; r.bottom = r.top + 10;
1054 MapDialogRect(hwnd, &r);
1055 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1056 WS_CHILD | WS_VISIBLE,
1057 r.left, r.top,
1058 r.right-r.left, r.bottom-r.top,
1059 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
1060 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1061 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1062
1063 r.left = 3; r.right = r.left + 75;
1064 r.top = 13; r.bottom = r.top + 206;
1065 MapDialogRect(hwnd, &r);
1066 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1067 WS_CHILD | WS_VISIBLE |
1068 WS_TABSTOP | TVS_HASLINES |
1069 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
1070 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
1071 r.left, r.top,
1072 r.right-r.left, r.bottom-r.top,
1073 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
1074 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1075 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1076 tvfaff.treeview = treeview;
1077 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1078 }
1079
1080 /*
1081 * Set up the tree view contents.
1082 */
1083 hsession = treeview_insert(&tvfaff, 0, "Session");
1084 treeview_insert(&tvfaff, 0, "Terminal");
1085 treeview_insert(&tvfaff, 1, "Keyboard");
1086 treeview_insert(&tvfaff, 0, "Window");
1087 treeview_insert(&tvfaff, 1, "Appearance");
1088 treeview_insert(&tvfaff, 1, "Translation");
1089 treeview_insert(&tvfaff, 1, "Selection");
1090 treeview_insert(&tvfaff, 1, "Colours");
1091 treeview_insert(&tvfaff, 0, "Connection");
1092 if (dlgtype == 0) {
1093 treeview_insert(&tvfaff, 1, "Telnet");
1094 treeview_insert(&tvfaff, 1, "Rlogin");
1095 if (backends[3].backend != NULL)
1096 treeview_insert(&tvfaff, 1, "SSH");
1097 treeview_insert(&tvfaff, 2, "Tunnels");
1098 }
1099
1100 /*
1101 * Put the treeview selection on to the Session panel. This
1102 * should also cause creation of the relevant controls.
1103 */
1104 TreeView_SelectItem(treeview, hsession);
1105
1106 /*
1107 * Set focus into the first available control.
1108 */
1109 {
1110 HWND ctl;
1111 ctl = GetDlgItem(hwnd, IDC_HOST);
1112 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1113 SetFocus(ctl);
1114 }
1115
1116 SetWindowLong(hwnd, GWL_USERDATA, 1);
1117 return 0;
1118 case WM_LBUTTONUP:
1119 /*
1120 * Button release should trigger WM_OK if there was a
1121 * previous double click on the session list.
1122 */
1123 ReleaseCapture();
1124 if (readytogo)
1125 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1126 break;
1127 case WM_NOTIFY:
1128 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1129 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1130 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1131 TVITEM item;
1132 int j;
1133 char buffer[64];
1134 item.hItem = i;
1135 item.pszText = buffer;
1136 item.cchTextMax = sizeof(buffer);
1137 item.mask = TVIF_TEXT;
1138 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1139 for (j = controlstartvalue; j < controlendvalue; j++) {
1140 HWND item = GetDlgItem(hwnd, j);
1141 if (item)
1142 DestroyWindow(item);
1143 }
1144 if (!strcmp(buffer, "Session"))
1145 create_controls(hwnd, dlgtype, sessionpanelstart);
1146 if (!strcmp(buffer, "Keyboard"))
1147 create_controls(hwnd, dlgtype, keyboardpanelstart);
1148 if (!strcmp(buffer, "Terminal"))
1149 create_controls(hwnd, dlgtype, terminalpanelstart);
1150 if (!strcmp(buffer, "Window"))
1151 create_controls(hwnd, dlgtype, windowpanelstart);
1152 if (!strcmp(buffer, "Appearance"))
1153 create_controls(hwnd, dlgtype, appearancepanelstart);
1154 if (!strcmp(buffer, "Tunnels"))
1155 create_controls(hwnd, dlgtype, tunnelspanelstart);
1156 if (!strcmp(buffer, "Connection"))
1157 create_controls(hwnd, dlgtype, connectionpanelstart);
1158 if (!strcmp(buffer, "Telnet"))
1159 create_controls(hwnd, dlgtype, telnetpanelstart);
1160 if (!strcmp(buffer, "Rlogin"))
1161 create_controls(hwnd, dlgtype, rloginpanelstart);
1162 if (!strcmp(buffer, "SSH"))
1163 create_controls(hwnd, dlgtype, sshpanelstart);
1164 if (!strcmp(buffer, "Selection"))
1165 create_controls(hwnd, dlgtype, selectionpanelstart);
1166 if (!strcmp(buffer, "Colours"))
1167 create_controls(hwnd, dlgtype, colourspanelstart);
1168 if (!strcmp(buffer, "Translation"))
1169 create_controls(hwnd, dlgtype, translationpanelstart);
1170
1171 init_dlg_ctrls(hwnd);
1172
1173 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1174 return 0;
1175 }
1176 break;
1177 case WM_COMMAND:
1178 /*
1179 * Only process WM_COMMAND once the dialog is fully formed.
1180 */
1181 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1182 case IDOK:
1183 if (*cfg.host)
1184 EndDialog (hwnd, 1);
1185 else
1186 MessageBeep (0);
1187 return 0;
1188 case IDCANCEL:
1189 EndDialog (hwnd, 0);
1190 return 0;
1191 case IDC_PROTTELNET:
1192 case IDC_PROTRLOGIN:
1193 case IDC_PROTSSH:
1194 case IDC_PROTRAW:
1195 if (HIWORD(wParam) == BN_CLICKED ||
1196 HIWORD(wParam) == BN_DOUBLECLICKED) {
1197 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1198 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1199 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1200 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1201 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1202 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1203 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1204 cfg.port = i ? 22 : j ? 23 : 513;
1205 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1206 }
1207 }
1208 break;
1209 case IDC_HOST:
1210 if (HIWORD(wParam) == EN_CHANGE)
1211 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1212 sizeof(cfg.host)-1);
1213 break;
1214 case IDC_PORT:
1215 if (HIWORD(wParam) == EN_CHANGE) {
1216 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1217 if (isdigit(portname[0]))
1218 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1219 else {
1220 service = getservbyname(portname, NULL);
1221 if (service) cfg.port = ntohs(service->s_port);
1222 else cfg.port = 0;
1223 }
1224 }
1225 break;
1226 case IDC_SESSEDIT:
1227 if (HIWORD(wParam) == EN_CHANGE) {
1228 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1229 (WPARAM) -1, 0);
1230 GetDlgItemText (hwnd, IDC_SESSEDIT,
1231 savedsession, sizeof(savedsession)-1);
1232 savedsession[sizeof(savedsession)-1] = '\0';
1233 }
1234 break;
1235 case IDC_SESSSAVE:
1236 if (HIWORD(wParam) == BN_CLICKED ||
1237 HIWORD(wParam) == BN_DOUBLECLICKED) {
1238 /*
1239 * Save a session
1240 */
1241 char str[2048];
1242 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1243 if (!*str) {
1244 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1245 LB_GETCURSEL, 0, 0);
1246 if (n == LB_ERR) {
1247 MessageBeep(0);
1248 break;
1249 }
1250 strcpy (str, sessions[n]);
1251 }
1252 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1253 get_sesslist (FALSE);
1254 get_sesslist (TRUE);
1255 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1256 0, 0);
1257 for (i = 0; i < nsessions; i++)
1258 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1259 0, (LPARAM) (sessions[i]));
1260 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1261 (WPARAM) -1, 0);
1262 }
1263 break;
1264 case IDC_SESSLIST:
1265 case IDC_SESSLOAD:
1266 if (LOWORD(wParam) == IDC_SESSLOAD &&
1267 HIWORD(wParam) != BN_CLICKED &&
1268 HIWORD(wParam) != BN_DOUBLECLICKED)
1269 break;
1270 if (LOWORD(wParam) == IDC_SESSLIST &&
1271 HIWORD(wParam) != LBN_DBLCLK)
1272 break;
1273 {
1274 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1275 LB_GETCURSEL, 0, 0);
1276 int isdef;
1277 if (n == LB_ERR) {
1278 MessageBeep(0);
1279 break;
1280 }
1281 isdef = !strcmp(sessions[n], "Default Settings");
1282 load_settings (sessions[n], !isdef, &cfg);
1283 init_dlg_ctrls(hwnd);
1284 if (!isdef)
1285 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1286 else
1287 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1288 }
1289 if (LOWORD(wParam) == IDC_SESSLIST) {
1290 /*
1291 * A double-click on a saved session should
1292 * actually start the session, not just load it.
1293 * Unless it's Default Settings or some other
1294 * host-less set of saved settings.
1295 */
1296 if (*cfg.host) {
1297 readytogo = TRUE;
1298 SetCapture(hwnd);
1299 }
1300 }
1301 break;
1302 case IDC_SESSDEL:
1303 if (HIWORD(wParam) == BN_CLICKED ||
1304 HIWORD(wParam) == BN_DOUBLECLICKED) {
1305 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1306 LB_GETCURSEL, 0, 0);
1307 if (n == LB_ERR || n == 0) {
1308 MessageBeep(0);
1309 break;
1310 }
1311 del_settings(sessions[n]);
1312 get_sesslist (FALSE);
1313 get_sesslist (TRUE);
1314 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1315 0, 0);
1316 for (i = 0; i < nsessions; i++)
1317 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1318 0, (LPARAM) (sessions[i]));
1319 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1320 (WPARAM) -1, 0);
1321 }
1322 case IDC_PINGEDIT:
1323 if (HIWORD(wParam) == EN_CHANGE)
1324 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1325 break;
1326 case IDC_DEL008:
1327 case IDC_DEL127:
1328 if (HIWORD(wParam) == BN_CLICKED ||
1329 HIWORD(wParam) == BN_DOUBLECLICKED)
1330 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1331 break;
1332 case IDC_HOMETILDE:
1333 case IDC_HOMERXVT:
1334 if (HIWORD(wParam) == BN_CLICKED ||
1335 HIWORD(wParam) == BN_DOUBLECLICKED)
1336 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1337 break;
1338 case IDC_FUNCXTERM:
1339 if (HIWORD(wParam) == BN_CLICKED ||
1340 HIWORD(wParam) == BN_DOUBLECLICKED)
1341 cfg.funky_type = 2;
1342 break;
1343 case IDC_FUNCVT400:
1344 if (HIWORD(wParam) == BN_CLICKED ||
1345 HIWORD(wParam) == BN_DOUBLECLICKED)
1346 cfg.funky_type = 3;
1347 break;
1348 case IDC_FUNCTILDE:
1349 case IDC_FUNCLINUX:
1350 if (HIWORD(wParam) == BN_CLICKED ||
1351 HIWORD(wParam) == BN_DOUBLECLICKED)
1352 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1353 break;
1354 case IDC_KPNORMAL:
1355 case IDC_KPAPPLIC:
1356 if (HIWORD(wParam) == BN_CLICKED ||
1357 HIWORD(wParam) == BN_DOUBLECLICKED) {
1358 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1359 cfg.nethack_keypad = FALSE;
1360 }
1361 break;
1362 case IDC_KPNH:
1363 if (HIWORD(wParam) == BN_CLICKED ||
1364 HIWORD(wParam) == BN_DOUBLECLICKED) {
1365 cfg.app_keypad = FALSE;
1366 cfg.nethack_keypad = TRUE;
1367 }
1368 break;
1369 case IDC_CURNORMAL:
1370 case IDC_CURAPPLIC:
1371 if (HIWORD(wParam) == BN_CLICKED ||
1372 HIWORD(wParam) == BN_DOUBLECLICKED)
1373 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1374 break;
1375 case IDC_NOAPPLICC:
1376 if (HIWORD(wParam) == BN_CLICKED ||
1377 HIWORD(wParam) == BN_DOUBLECLICKED)
1378 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1379 break;
1380 case IDC_NOAPPLICK:
1381 if (HIWORD(wParam) == BN_CLICKED ||
1382 HIWORD(wParam) == BN_DOUBLECLICKED)
1383 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1384 break;
1385 case IDC_ALTF4:
1386 if (HIWORD(wParam) == BN_CLICKED ||
1387 HIWORD(wParam) == BN_DOUBLECLICKED)
1388 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1389 break;
1390 case IDC_ALTSPACE:
1391 if (HIWORD(wParam) == BN_CLICKED ||
1392 HIWORD(wParam) == BN_DOUBLECLICKED)
1393 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1394 break;
1395 case IDC_ALTONLY:
1396 if (HIWORD(wParam) == BN_CLICKED ||
1397 HIWORD(wParam) == BN_DOUBLECLICKED)
1398 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1399 break;
1400 case IDC_LDISCTERM:
1401 if (HIWORD(wParam) == BN_CLICKED ||
1402 HIWORD(wParam) == BN_DOUBLECLICKED)
1403 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1404 break;
1405 case IDC_ALWAYSONTOP:
1406 if (HIWORD(wParam) == BN_CLICKED ||
1407 HIWORD(wParam) == BN_DOUBLECLICKED)
1408 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1409 break;
1410 case IDC_SCROLLKEY:
1411 if (HIWORD(wParam) == BN_CLICKED ||
1412 HIWORD(wParam) == BN_DOUBLECLICKED)
1413 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1414 break;
1415 case IDC_SCROLLDISP:
1416 if (HIWORD(wParam) == BN_CLICKED ||
1417 HIWORD(wParam) == BN_DOUBLECLICKED)
1418 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1419 break;
1420 case IDC_COMPOSEKEY:
1421 if (HIWORD(wParam) == BN_CLICKED ||
1422 HIWORD(wParam) == BN_DOUBLECLICKED)
1423 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1424 break;
1425 case IDC_WRAPMODE:
1426 if (HIWORD(wParam) == BN_CLICKED ||
1427 HIWORD(wParam) == BN_DOUBLECLICKED)
1428 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1429 break;
1430 case IDC_DECOM:
1431 if (HIWORD(wParam) == BN_CLICKED ||
1432 HIWORD(wParam) == BN_DOUBLECLICKED)
1433 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1434 break;
1435 case IDC_LFHASCR:
1436 if (HIWORD(wParam) == BN_CLICKED ||
1437 HIWORD(wParam) == BN_DOUBLECLICKED)
1438 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1439 break;
1440 case IDC_ROWSEDIT:
1441 if (HIWORD(wParam) == EN_CHANGE)
1442 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1443 break;
1444 case IDC_COLSEDIT:
1445 if (HIWORD(wParam) == EN_CHANGE)
1446 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1447 break;
1448 case IDC_SAVEEDIT:
1449 if (HIWORD(wParam) == EN_CHANGE)
1450 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1451 break;
1452 case IDC_CHOOSEFONT:
1453 lf.lfHeight = cfg.fontheight;
1454 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1455 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1456 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1457 lf.lfCharSet = cfg.fontcharset;
1458 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1459 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1460 lf.lfQuality = DEFAULT_QUALITY;
1461 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1462 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1463 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1464
1465 cf.lStructSize = sizeof(cf);
1466 cf.hwndOwner = hwnd;
1467 cf.lpLogFont = &lf;
1468 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1469 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1470
1471 if (ChooseFont (&cf)) {
1472 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1473 cfg.font[sizeof(cfg.font)-1] = '\0';
1474 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1475 cfg.fontcharset = lf.lfCharSet;
1476 cfg.fontheight = lf.lfHeight;
1477 fmtfont (fontstatic);
1478 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1479 }
1480 break;
1481 case IDC_BEEP:
1482 if (HIWORD(wParam) == BN_CLICKED ||
1483 HIWORD(wParam) == BN_DOUBLECLICKED)
1484 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1485 break;
1486 case IDC_BLINKTEXT:
1487 if (HIWORD(wParam) == BN_CLICKED ||
1488 HIWORD(wParam) == BN_DOUBLECLICKED)
1489 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1490 break;
1491 case IDC_BCE:
1492 if (HIWORD(wParam) == BN_CLICKED ||
1493 HIWORD(wParam) == BN_DOUBLECLICKED)
1494 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1495 break;
1496 case IDC_WINNAME:
1497 if (HIWORD(wParam) == BN_CLICKED ||
1498 HIWORD(wParam) == BN_DOUBLECLICKED)
1499 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1500 break;
1501 case IDC_HIDEMOUSE:
1502 if (HIWORD(wParam) == BN_CLICKED ||
1503 HIWORD(wParam) == BN_DOUBLECLICKED)
1504 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1505 break;
1506 case IDC_CURBLOCK:
1507 if (HIWORD(wParam) == BN_CLICKED ||
1508 HIWORD(wParam) == BN_DOUBLECLICKED)
1509 cfg.cursor_type = 0;
1510 break;
1511 case IDC_CURUNDER:
1512 if (HIWORD(wParam) == BN_CLICKED ||
1513 HIWORD(wParam) == BN_DOUBLECLICKED)
1514 cfg.cursor_type = 1;
1515 break;
1516 case IDC_CURVERT:
1517 if (HIWORD(wParam) == BN_CLICKED ||
1518 HIWORD(wParam) == BN_DOUBLECLICKED)
1519 cfg.cursor_type = 2;
1520 break;
1521 case IDC_BLINKCUR:
1522 if (HIWORD(wParam) == BN_CLICKED ||
1523 HIWORD(wParam) == BN_DOUBLECLICKED)
1524 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1525 break;
1526 case IDC_SCROLLBAR:
1527 if (HIWORD(wParam) == BN_CLICKED ||
1528 HIWORD(wParam) == BN_DOUBLECLICKED)
1529 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1530 break;
1531 case IDC_LOCKSIZE:
1532 if (HIWORD(wParam) == BN_CLICKED ||
1533 HIWORD(wParam) == BN_DOUBLECLICKED)
1534 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1535 break;
1536 case IDC_WINEDIT:
1537 if (HIWORD(wParam) == EN_CHANGE)
1538 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1539 sizeof(cfg.wintitle)-1);
1540 break;
1541 case IDC_CLOSEEXIT:
1542 if (HIWORD(wParam) == BN_CLICKED ||
1543 HIWORD(wParam) == BN_DOUBLECLICKED)
1544 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1545 break;
1546 case IDC_CLOSEWARN:
1547 if (HIWORD(wParam) == BN_CLICKED ||
1548 HIWORD(wParam) == BN_DOUBLECLICKED)
1549 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1550 break;
1551 case IDC_TTEDIT:
1552 if (HIWORD(wParam) == EN_CHANGE)
1553 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1554 sizeof(cfg.termtype)-1);
1555 break;
1556 case IDC_LGFEDIT:
1557 if (HIWORD(wParam) == EN_CHANGE)
1558 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1559 sizeof(cfg.logfilename)-1);
1560 break;
1561 case IDC_LGFBUTTON:
1562 memset(&of, 0, sizeof(of));
1563 #ifdef OPENFILENAME_SIZE_VERSION_400
1564 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1565 #else
1566 of.lStructSize = sizeof(of);
1567 #endif
1568 of.hwndOwner = hwnd;
1569 of.lpstrFilter = "All Files\0*\0\0\0";
1570 of.lpstrCustomFilter = NULL;
1571 of.nFilterIndex = 1;
1572 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1573 of.nMaxFile = sizeof(filename);
1574 of.lpstrFileTitle = NULL;
1575 of.lpstrInitialDir = NULL;
1576 of.lpstrTitle = "Select session log file";
1577 of.Flags = 0;
1578 if (GetSaveFileName(&of)) {
1579 strcpy(cfg.keyfile, filename);
1580 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.keyfile);
1581 }
1582 break;
1583 case IDC_LSTATOFF:
1584 case IDC_LSTATASCII:
1585 case IDC_LSTATRAW:
1586 if (HIWORD(wParam) == BN_CLICKED ||
1587 HIWORD(wParam) == BN_DOUBLECLICKED) {
1588 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1589 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1590 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1591 }
1592 break;
1593 case IDC_TSEDIT:
1594 case IDC_R_TSEDIT:
1595 if (HIWORD(wParam) == EN_CHANGE)
1596 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1597 sizeof(cfg.termspeed)-1);
1598 break;
1599 case IDC_LOGEDIT:
1600 if (HIWORD(wParam) == EN_CHANGE)
1601 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1602 sizeof(cfg.username)-1);
1603 break;
1604 case IDC_RLLUSEREDIT:
1605 if (HIWORD(wParam) == EN_CHANGE)
1606 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1607 sizeof(cfg.localusername)-1);
1608 break;
1609 case IDC_EMBSD:
1610 case IDC_EMRFC:
1611 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1612 break;
1613 case IDC_ENVADD:
1614 if (HIWORD(wParam) == BN_CLICKED ||
1615 HIWORD(wParam) == BN_DOUBLECLICKED) {
1616 char str[sizeof(cfg.environmt)];
1617 char *p;
1618 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1619 if (!*str) {
1620 MessageBeep(0);
1621 break;
1622 }
1623 p = str + strlen(str);
1624 *p++ = '\t';
1625 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1626 if (!*p) {
1627 MessageBeep(0);
1628 break;
1629 }
1630 p = cfg.environmt;
1631 while (*p) {
1632 while (*p) p++;
1633 p++;
1634 }
1635 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1636 strcpy (p, str);
1637 p[strlen(str)+1] = '\0';
1638 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1639 0, (LPARAM)str);
1640 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1641 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1642 } else {
1643 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1644 MB_OK | MB_ICONERROR);
1645 }
1646 }
1647 break;
1648 case IDC_ENVREMOVE:
1649 if (HIWORD(wParam) != BN_CLICKED &&
1650 HIWORD(wParam) != BN_DOUBLECLICKED)
1651 break;
1652 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1653 if (i == LB_ERR)
1654 MessageBeep (0);
1655 else {
1656 char *p, *q;
1657
1658 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1659 i, 0);
1660 p = cfg.environmt;
1661 while (i > 0) {
1662 if (!*p)
1663 goto disaster;
1664 while (*p) p++;
1665 p++;
1666 i--;
1667 }
1668 q = p;
1669 if (!*p)
1670 goto disaster;
1671 while (*p) p++;
1672 p++;
1673 while (*p) {
1674 while (*p)
1675 *q++ = *p++;
1676 *q++ = *p++;
1677 }
1678 *q = '\0';
1679 disaster:;
1680 }
1681 break;
1682 case IDC_NOPTY:
1683 if (HIWORD(wParam) == BN_CLICKED ||
1684 HIWORD(wParam) == BN_DOUBLECLICKED)
1685 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1686 break;
1687 case IDC_COMPRESS:
1688 if (HIWORD(wParam) == BN_CLICKED ||
1689 HIWORD(wParam) == BN_DOUBLECLICKED)
1690 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1691 break;
1692 case IDC_BUGGYMAC:
1693 if (HIWORD(wParam) == BN_CLICKED ||
1694 HIWORD(wParam) == BN_DOUBLECLICKED)
1695 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1696 break;
1697 case IDC_AGENTFWD:
1698 if (HIWORD(wParam) == BN_CLICKED ||
1699 HIWORD(wParam) == BN_DOUBLECLICKED)
1700 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1701 break;
1702 case IDC_CIPHER3DES:
1703 case IDC_CIPHERBLOWF:
1704 case IDC_CIPHERDES:
1705 if (HIWORD(wParam) == BN_CLICKED ||
1706 HIWORD(wParam) == BN_DOUBLECLICKED) {
1707 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1708 cfg.cipher = CIPHER_3DES;
1709 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1710 cfg.cipher = CIPHER_BLOWFISH;
1711 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1712 cfg.cipher = CIPHER_DES;
1713 }
1714 break;
1715 case IDC_SSHPROT1:
1716 case IDC_SSHPROT2:
1717 if (HIWORD(wParam) == BN_CLICKED ||
1718 HIWORD(wParam) == BN_DOUBLECLICKED) {
1719 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1720 cfg.sshprot = 1;
1721 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1722 cfg.sshprot = 2;
1723 }
1724 break;
1725 case IDC_AUTHTIS:
1726 if (HIWORD(wParam) == BN_CLICKED ||
1727 HIWORD(wParam) == BN_DOUBLECLICKED)
1728 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1729 break;
1730 case IDC_PKEDIT:
1731 if (HIWORD(wParam) == EN_CHANGE)
1732 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1733 sizeof(cfg.keyfile)-1);
1734 break;
1735 case IDC_CMDEDIT:
1736 if (HIWORD(wParam) == EN_CHANGE)
1737 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1738 sizeof(cfg.remote_cmd)-1);
1739 break;
1740 case IDC_PKBUTTON:
1741 memset(&of, 0, sizeof(of));
1742 #ifdef OPENFILENAME_SIZE_VERSION_400
1743 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1744 #else
1745 of.lStructSize = sizeof(of);
1746 #endif
1747 of.hwndOwner = hwnd;
1748 of.lpstrFilter = "All Files\0*\0\0\0";
1749 of.lpstrCustomFilter = NULL;
1750 of.nFilterIndex = 1;
1751 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1752 of.nMaxFile = sizeof(filename);
1753 of.lpstrFileTitle = NULL;
1754 of.lpstrInitialDir = NULL;
1755 of.lpstrTitle = "Select Public Key File";
1756 of.Flags = 0;
1757 if (GetOpenFileName(&of)) {
1758 strcpy(cfg.keyfile, filename);
1759 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1760 }
1761 break;
1762 case IDC_MBWINDOWS:
1763 case IDC_MBXTERM:
1764 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1765 break;
1766 case IDC_CCSET:
1767 {
1768 BOOL ok;
1769 int i;
1770 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1771
1772 if (!ok)
1773 MessageBeep (0);
1774 else {
1775 for (i=0; i<256; i++)
1776 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1777 i, 0)) {
1778 char str[100];
1779 cfg.wordness[i] = n;
1780 SendDlgItemMessage (hwnd, IDC_CCLIST,
1781 LB_DELETESTRING, i, 0);
1782 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1783 (i>=0x21 && i != 0x7F) ? i : ' ',
1784 cfg.wordness[i]);
1785 SendDlgItemMessage (hwnd, IDC_CCLIST,
1786 LB_INSERTSTRING, i,
1787 (LPARAM)str);
1788 }
1789 }
1790 }
1791 break;
1792 case IDC_BOLDCOLOUR:
1793 if (HIWORD(wParam) == BN_CLICKED ||
1794 HIWORD(wParam) == BN_DOUBLECLICKED) {
1795 int n, i;
1796 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1797 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1798 if (n != 12+10*cfg.bold_colour) {
1799 for (i=n; i-- >0 ;)
1800 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1801 LB_DELETESTRING, i, 0);
1802 for (i=0; i<22; i++)
1803 if (cfg.bold_colour || permcolour[i])
1804 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1805 LB_ADDSTRING, 0,
1806 (LPARAM) colours[i]);
1807 }
1808 }
1809 break;
1810 case IDC_PALETTE:
1811 if (HIWORD(wParam) == BN_CLICKED ||
1812 HIWORD(wParam) == BN_DOUBLECLICKED)
1813 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1814 break;
1815 case IDC_COLOURLIST:
1816 if (HIWORD(wParam) == LBN_DBLCLK ||
1817 HIWORD(wParam) == LBN_SELCHANGE) {
1818 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1819 0, 0);
1820 if (!cfg.bold_colour)
1821 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1822 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1823 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1824 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1825 }
1826 break;
1827 case IDC_CHANGE:
1828 if (HIWORD(wParam) == BN_CLICKED ||
1829 HIWORD(wParam) == BN_DOUBLECLICKED) {
1830 static CHOOSECOLOR cc;
1831 static DWORD custom[16] = {0}; /* zero initialisers */
1832 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1833 0, 0);
1834 if (!cfg.bold_colour)
1835 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1836 cc.lStructSize = sizeof(cc);
1837 cc.hwndOwner = hwnd;
1838 cc.hInstance = (HWND)hinst;
1839 cc.lpCustColors = custom;
1840 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1841 cfg.colours[i][2]);
1842 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1843 if (ChooseColor(&cc)) {
1844 cfg.colours[i][0] =
1845 (unsigned char) (cc.rgbResult & 0xFF);
1846 cfg.colours[i][1] =
1847 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1848 cfg.colours[i][2] =
1849 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1850 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1851 FALSE);
1852 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1853 FALSE);
1854 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1855 FALSE);
1856 }
1857 }
1858 break;
1859 case IDC_NOXLAT:
1860 case IDC_KOI8WIN1251:
1861 case IDC_88592WIN1250:
1862 case IDC_88592CP852:
1863 cfg.xlat_enablekoiwin =
1864 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1865 cfg.xlat_88592w1250 =
1866 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1867 cfg.xlat_88592cp852 =
1868 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1869 break;
1870 case IDC_CAPSLOCKCYR:
1871 if (HIWORD(wParam) == BN_CLICKED ||
1872 HIWORD(wParam) == BN_DOUBLECLICKED) {
1873 cfg.xlat_capslockcyr =
1874 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1875 }
1876 break;
1877 case IDC_VTXWINDOWS:
1878 case IDC_VTOEMANSI:
1879 case IDC_VTOEMONLY:
1880 case IDC_VTPOORMAN:
1881 cfg.vtmode =
1882 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1883 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1884 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1885 VT_POORMAN);
1886 break;
1887 case IDC_X11_FORWARD:
1888 if (HIWORD(wParam) == BN_CLICKED ||
1889 HIWORD(wParam) == BN_DOUBLECLICKED)
1890 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1891 break;
1892 case IDC_X11_DISPLAY:
1893 if (HIWORD(wParam) == EN_CHANGE)
1894 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1895 sizeof(cfg.x11_display)-1);
1896 break;
1897 }
1898 return 0;
1899 case WM_CLOSE:
1900 EndDialog (hwnd, 0);
1901 return 0;
1902
1903 /* Grrr Explorer will maximize Dialogs! */
1904 case WM_SIZE:
1905 if (wParam == SIZE_MAXIMIZED)
1906 force_normal(hwnd);
1907 return 0;
1908 }
1909 return 0;
1910 }
1911
1912 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1913 WPARAM wParam, LPARAM lParam) {
1914 static HWND page = NULL;
1915
1916 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1917 }
1918 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1919 EnableWindow(hwnd, 0);
1920 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1921 GetParent(hwnd), AboutProc);
1922 EnableWindow(hwnd, 1);
1923 SetActiveWindow(hwnd);
1924 }
1925 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1926 }
1927
1928 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1929 WPARAM wParam, LPARAM lParam) {
1930 static HWND page;
1931 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1932 }
1933
1934 void defuse_showwindow(void) {
1935 /*
1936 * Work around the fact that the app's first call to ShowWindow
1937 * will ignore the default in favour of the shell-provided
1938 * setting.
1939 */
1940 {
1941 HWND hwnd;
1942 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1943 NULL, NullDlgProc);
1944 ShowWindow(hwnd, SW_HIDE);
1945 DestroyWindow(hwnd);
1946 }
1947 }
1948
1949 int do_config (void) {
1950 int ret;
1951
1952 get_sesslist(TRUE);
1953 savedsession[0] = '\0';
1954 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1955 get_sesslist(FALSE);
1956
1957 return ret;
1958 }
1959
1960 int do_reconfig (HWND hwnd) {
1961 Config backup_cfg;
1962 int ret;
1963
1964 backup_cfg = cfg; /* structure copy */
1965 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1966 if (!ret)
1967 cfg = backup_cfg; /* structure copy */
1968
1969 return ret;
1970 }
1971
1972 void logevent (char *string) {
1973 if (nevents >= negsize) {
1974 negsize += 64;
1975 events = srealloc (events, negsize * sizeof(*events));
1976 }
1977 events[nevents] = smalloc(1+strlen(string));
1978 strcpy (events[nevents], string);
1979 nevents++;
1980 if (logbox) {
1981 int count;
1982 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1983 0, (LPARAM)string);
1984 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1985 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1986 }
1987 }
1988
1989 void showeventlog (HWND hwnd) {
1990 if (!logbox) {
1991 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1992 hwnd, LogProc);
1993 ShowWindow (logbox, SW_SHOWNORMAL);
1994 }
1995 }
1996
1997 void showabout (HWND hwnd) {
1998 if (!abtbox) {
1999 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2000 hwnd, AboutProc);
2001 ShowWindow (abtbox, SW_SHOWNORMAL);
2002 }
2003 }
2004
2005 void verify_ssh_host_key(char *host, int port, char *keytype,
2006 char *keystr, char *fingerprint) {
2007 int ret;
2008
2009 static const char absentmsg[] =
2010 "The server's host key is not cached in the registry. You\n"
2011 "have no guarantee that the server is the computer you\n"
2012 "think it is.\n"
2013 "The server's key fingerprint is:\n"
2014 "%s\n"
2015 "If you trust this host, hit Yes to add the key to\n"
2016 "PuTTY's cache and carry on connecting.\n"
2017 "If you do not trust this host, hit No to abandon the\n"
2018 "connection.\n";
2019
2020 static const char wrongmsg[] =
2021 "WARNING - POTENTIAL SECURITY BREACH!\n"
2022 "\n"
2023 "The server's host key does not match the one PuTTY has\n"
2024 "cached in the registry. This means that either the\n"
2025 "server administrator has changed the host key, or you\n"
2026 "have actually connected to another computer pretending\n"
2027 "to be the server.\n"
2028 "The new key fingerprint is:\n"
2029 "%s\n"
2030 "If you were expecting this change and trust the new key,\n"
2031 "hit Yes to update PuTTY's cache and continue connecting.\n"
2032 "If you want to carry on connecting but without updating\n"
2033 "the cache, hit No.\n"
2034 "If you want to abandon the connection completely, hit\n"
2035 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2036 "choice.\n";
2037
2038 static const char mbtitle[] = "PuTTY Security Alert";
2039
2040
2041 char message[160+ /* sensible fingerprint max size */
2042 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2043 sizeof(absentmsg) : sizeof(wrongmsg))];
2044
2045 /*
2046 * Verify the key against the registry.
2047 */
2048 ret = verify_host_key(host, port, keytype, keystr);
2049
2050 if (ret == 0) /* success - key matched OK */
2051 return;
2052 if (ret == 2) { /* key was different */
2053 int mbret;
2054 sprintf(message, wrongmsg, fingerprint);
2055 mbret = MessageBox(NULL, message, mbtitle,
2056 MB_ICONWARNING | MB_YESNOCANCEL);
2057 if (mbret == IDYES)
2058 store_host_key(host, port, keytype, keystr);
2059 if (mbret == IDCANCEL)
2060 exit(0);
2061 }
2062 if (ret == 1) { /* key was absent */
2063 int mbret;
2064 sprintf(message, absentmsg, fingerprint);
2065 mbret = MessageBox(NULL, message, mbtitle,
2066 MB_ICONWARNING | MB_YESNO);
2067 if (mbret == IDNO)
2068 exit(0);
2069 store_host_key(host, port, keytype, keystr);
2070 }
2071 }
2072
2073 /*
2074 * Ask whether to wipe a session log file before writing to it.
2075 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2076 */
2077 int askappend(char *filename) {
2078 static const char mbtitle[] = "PuTTY Log to File";
2079 static const char msgtemplate[] =
2080 "The session log file \"%.*s\" already exists.\n"
2081 "You can overwrite it with a new session log,\n"
2082 "append your session log to the end of it,\n"
2083 "or disable session logging for this session.\n"
2084 "Hit Yes to wipe the file, No to append to it,\n"
2085 "or Cancel to disable logging.";
2086 char message[sizeof(msgtemplate) + FILENAME_MAX];
2087 int mbret;
2088 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2089
2090 mbret = MessageBox(NULL, message, mbtitle,
2091 MB_ICONQUESTION | MB_YESNOCANCEL);
2092 if (mbret == IDYES)
2093 return 2;
2094 else if (mbret == IDNO)
2095 return 1;
2096 else
2097 return 0;
2098 }