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