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