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