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