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