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