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