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