13 static char **events
= NULL
;
14 static int nevents
= 0, negsize
= 0;
16 static HWND logbox
= NULL
, abtbox
= NULL
;
20 static void force_normal(HWND hwnd
)
22 static int recurse
= 0;
29 wp
.length
= sizeof(wp
);
30 if (GetWindowPlacement(hwnd
, &wp
))
32 wp
.showCmd
= SW_SHOWNORMAL
;
33 SetWindowPlacement(hwnd
, &wp
);
38 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
41 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
46 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
47 WPARAM wParam
, LPARAM lParam
) {
52 for (i
=0; i
<nevents
; i
++)
53 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
54 0, (LPARAM
)events
[i
]);
57 switch (LOWORD(wParam
)) {
63 if (HIWORD(wParam
) == BN_CLICKED
||
64 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
67 selcount
= SendDlgItemMessage(hwnd
, IDN_LIST
,
68 LB_GETSELCOUNT
, 0, 0);
69 selitems
= smalloc(selcount
* sizeof(int));
71 int count
= SendDlgItemMessage(hwnd
, IDN_LIST
,
73 selcount
, (LPARAM
)selitems
);
77 static unsigned char sel_nl
[] = SEL_NL
;
79 if (count
== 0) { /* can't copy zero stuff */
85 for (i
= 0; i
< count
; i
++)
86 size
+= strlen(events
[selitems
[i
]]) + sizeof(sel_nl
);
88 clipdata
= smalloc(size
);
91 for (i
= 0; i
< count
; i
++) {
92 char *q
= events
[selitems
[i
]];
96 memcpy(p
, sel_nl
, sizeof(sel_nl
));
99 write_clip(clipdata
, size
, TRUE
);
104 for (i
= 0; i
< nevents
; i
++)
105 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_SETSEL
,
114 DestroyWindow (hwnd
);
120 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
121 WPARAM wParam
, LPARAM lParam
) {
126 switch (LOWORD(wParam
)) {
139 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
140 WPARAM wParam
, LPARAM lParam
) {
143 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
146 switch (LOWORD(wParam
)) {
149 DestroyWindow (hwnd
);
152 EnableWindow(hwnd
, 0);
153 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
155 EnableWindow(hwnd
, 1);
156 SetActiveWindow(hwnd
);
162 DestroyWindow (hwnd
);
169 * Null dialog procedure.
171 static int CALLBACK
NullDlgProc (HWND hwnd
, UINT msg
,
172 WPARAM wParam
, LPARAM lParam
) {
176 static char savedsession
[2048];
178 enum { IDCX_ABOUT
= IDC_ABOUT
, IDCX_TVSTATIC
, IDCX_TREEVIEW
, controlstartvalue
,
182 IDC_BOX_SESSION1
, IDC_BOXT_SESSION1
,
183 IDC_BOX_SESSION2
, IDC_BOXT_SESSION2
,
204 IDC_BOX_KEYBOARD1
, IDC_BOXT_KEYBOARD1
,
205 IDC_BOX_KEYBOARD2
, IDC_BOXT_KEYBOARD2
,
206 IDC_BOX_KEYBOARD3
, IDC_BOXT_KEYBOARD3
,
232 IDC_BOX_TERMINAL1
, IDC_BOXT_TERMINAL1
,
244 IDC_BOX_WINDOW1
, IDC_BOXT_WINDOW1
,
245 IDC_BOX_WINDOW2
, IDC_BOXT_WINDOW2
,
264 appearancepanelstart
,
265 IDC_TITLE_APPEARANCE
,
266 IDC_BOX_APPEARANCE1
, IDC_BOXT_APPEARANCE1
,
267 IDC_BOX_APPEARANCE2
, IDC_BOXT_APPEARANCE2
,
268 IDC_BOX_APPEARANCE3
, IDC_BOXT_APPEARANCE3
,
277 connectionpanelstart
,
278 IDC_TITLE_CONNECTION
,
279 IDC_BOX_CONNECTION1
, IDC_BOXT_CONNECTION1
,
280 IDC_BOX_CONNECTION2
, IDC_BOXT_CONNECTION2
,
291 IDC_BOX_TELNET1
, IDC_BOXT_TELNET1
,
292 IDC_BOX_TELNET2
, IDC_BOXT_TELNET2
,
310 IDC_BOX_SSH1
, IDC_BOXT_SSH1
,
311 IDC_BOX_SSH2
, IDC_BOXT_SSH2
,
312 IDC_BOX_SSH3
, IDC_BOXT_SSH3
,
334 IDC_BOX_SELECTION1
, IDC_BOXT_SELECTION1
,
335 IDC_BOX_SELECTION2
, IDC_BOXT_SELECTION2
,
348 IDC_BOX_COLOURS1
, IDC_BOXT_COLOURS1
,
349 IDC_BOX_COLOURS2
, IDC_BOXT_COLOURS2
,
363 translationpanelstart
,
364 IDC_TITLE_TRANSLATION
,
365 IDC_BOX_TRANSLATION1
, IDC_BOXT_TRANSLATION1
,
366 IDC_BOX_TRANSLATION2
, IDC_BOXT_TRANSLATION2
,
367 IDC_BOX_TRANSLATION3
, IDC_BOXT_TRANSLATION3
,
384 static const char *const colours
[] = {
385 "Default Foreground", "Default Bold Foreground",
386 "Default Background", "Default Bold Background",
387 "Cursor Text", "Cursor Colour",
388 "ANSI Black", "ANSI Black Bold",
389 "ANSI Red", "ANSI Red Bold",
390 "ANSI Green", "ANSI Green Bold",
391 "ANSI Yellow", "ANSI Yellow Bold",
392 "ANSI Blue", "ANSI Blue Bold",
393 "ANSI Magenta", "ANSI Magenta Bold",
394 "ANSI Cyan", "ANSI Cyan Bold",
395 "ANSI White", "ANSI White Bold"
397 static const int permcolour
[] = {
398 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
399 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
400 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
403 static void fmtfont (char *buf
) {
404 sprintf (buf
, "Font: %s, ", cfg
.font
);
406 strcat(buf
, "bold, ");
407 if (cfg
.fontheight
== 0)
408 strcat (buf
, "default height");
410 sprintf (buf
+strlen(buf
), "%d-%s",
411 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
412 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
415 static void init_dlg_ctrls(HWND hwnd
) {
417 char fontstatic
[256];
419 SetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
);
420 SetDlgItemText (hwnd
, IDC_SESSEDIT
, savedsession
);
421 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
422 CheckRadioButton (hwnd
, IDC_PROTRAW
, IDC_PROTSSH
,
423 cfg
.protocol
==PROT_SSH ? IDC_PROTSSH
:
424 cfg
.protocol
==PROT_TELNET ? IDC_PROTTELNET
: IDC_PROTRAW
);
425 SetDlgItemInt (hwnd
, IDC_PINGEDIT
, cfg
.ping_interval
, FALSE
);
427 CheckRadioButton (hwnd
, IDC_DEL008
, IDC_DEL127
,
428 cfg
.bksp_is_delete ? IDC_DEL127
: IDC_DEL008
);
429 CheckRadioButton (hwnd
, IDC_HOMETILDE
, IDC_HOMERXVT
,
430 cfg
.rxvt_homeend ? IDC_HOMERXVT
: IDC_HOMETILDE
);
431 CheckRadioButton (hwnd
, IDC_FUNCTILDE
, IDC_FUNCVT400
,
432 cfg
.funky_type
== 0 ? IDC_FUNCTILDE
:
433 cfg
.funky_type
== 1 ? IDC_FUNCLINUX
:
434 cfg
.funky_type
== 2 ? IDC_FUNCXTERM
:
435 cfg
.funky_type
== 3 ? IDC_FUNCVT400
:
437 CheckDlgButton (hwnd
, IDC_NOAPPLICC
, cfg
.no_applic_c
);
438 CheckDlgButton (hwnd
, IDC_NOAPPLICK
, cfg
.no_applic_k
);
439 CheckRadioButton (hwnd
, IDC_CURNORMAL
, IDC_CURAPPLIC
,
440 cfg
.app_cursor ? IDC_CURAPPLIC
: IDC_CURNORMAL
);
441 CheckRadioButton (hwnd
, IDC_KPNORMAL
, IDC_KPNH
,
442 cfg
.nethack_keypad ? IDC_KPNH
:
443 cfg
.app_keypad ? IDC_KPAPPLIC
: IDC_KPNORMAL
);
444 CheckDlgButton (hwnd
, IDC_ALTF4
, cfg
.alt_f4
);
445 CheckDlgButton (hwnd
, IDC_ALTSPACE
, cfg
.alt_space
);
446 CheckDlgButton (hwnd
, IDC_ALTONLY
, cfg
.alt_only
);
447 CheckDlgButton (hwnd
, IDC_COMPOSEKEY
, cfg
.compose_key
);
448 CheckDlgButton (hwnd
, IDC_LDISCTERM
, cfg
.ldisc_term
);
449 CheckDlgButton (hwnd
, IDC_ALWAYSONTOP
, cfg
.alwaysontop
);
450 CheckDlgButton (hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
451 CheckDlgButton (hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
453 CheckDlgButton (hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
454 CheckDlgButton (hwnd
, IDC_DECOM
, cfg
.dec_om
);
455 CheckDlgButton (hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
456 SetDlgItemInt (hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
457 SetDlgItemInt (hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
458 SetDlgItemInt (hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
459 fmtfont (fontstatic
);
460 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
461 CheckDlgButton (hwnd
, IDC_BEEP
, cfg
.beep
);
462 CheckDlgButton (hwnd
, IDC_BCE
, cfg
.bce
);
463 CheckDlgButton (hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
465 SetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
466 CheckDlgButton (hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
467 CheckDlgButton (hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
468 CheckDlgButton (hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
469 CheckDlgButton (hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
470 CheckDlgButton (hwnd
, IDC_CLOSEEXIT
, cfg
.close_on_exit
);
471 CheckDlgButton (hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
473 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
474 SetDlgItemText (hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
475 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
477 char *p
= cfg
.environmt
;
479 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
484 CheckRadioButton (hwnd
, IDC_EMBSD
, IDC_EMRFC
,
485 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
487 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
488 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
489 CheckDlgButton (hwnd
, IDC_NOPTY
, cfg
.nopty
);
490 CheckDlgButton (hwnd
, IDC_COMPRESS
, cfg
.compression
);
491 CheckDlgButton (hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
492 CheckDlgButton (hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
493 CheckRadioButton (hwnd
, IDC_CIPHER3DES
, IDC_CIPHERDES
,
494 cfg
.cipher
== CIPHER_BLOWFISH ? IDC_CIPHERBLOWF
:
495 cfg
.cipher
== CIPHER_DES ? IDC_CIPHERDES
:
497 CheckRadioButton (hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
498 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
499 CheckDlgButton (hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
500 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
501 SetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
503 CheckRadioButton (hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
504 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
506 static int tabs
[4] = {25, 61, 96, 128};
507 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
510 for (i
=0; i
<256; i
++) {
512 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
513 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
515 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
519 CheckDlgButton (hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
520 CheckDlgButton (hwnd
, IDC_PALETTE
, cfg
.try_palette
);
523 n
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
525 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
526 LB_DELETESTRING
, i
, 0);
528 if (cfg
.bold_colour
|| permcolour
[i
])
529 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
530 (LPARAM
) colours
[i
]);
532 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
533 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
534 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
535 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
537 CheckRadioButton (hwnd
, IDC_NOXLAT
, IDC_88592CP852
,
538 cfg
.xlat_88592w1250 ? IDC_88592WIN1250
:
539 cfg
.xlat_88592cp852 ? IDC_88592CP852
:
540 cfg
.xlat_enablekoiwin ? IDC_KOI8WIN1251
:
542 CheckDlgButton (hwnd
, IDC_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
543 CheckRadioButton (hwnd
, IDC_VTXWINDOWS
, IDC_VTPOORMAN
,
544 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
545 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
546 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
550 static void hide(HWND hwnd
, int hide
, int minid
, int maxid
) {
552 for (i
= minid
; i
< maxid
; i
++) {
553 HWND ctl
= GetDlgItem(hwnd
, i
);
555 ShowWindow(ctl
, hide ? SW_HIDE
: SW_SHOW
);
560 struct treeview_faff
{
565 static HTREEITEM
treeview_insert(struct treeview_faff
*faff
,
566 int level
, char *text
) {
570 ins
.hParent
= (level
> 0 ? faff
->lastat
[level
-1] : TVI_ROOT
);
571 ins
.hInsertAfter
= faff
->lastat
[level
];
572 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
573 #define INSITEM DUMMYUNIONNAME.item
577 ins
.INSITEM
.mask
= TVIF_TEXT
;
578 ins
.INSITEM
.pszText
= text
;
579 newitem
= TreeView_InsertItem(faff
->treeview
, &ins
);
581 TreeView_Expand(faff
->treeview
, faff
->lastat
[level
-1], TVE_EXPAND
);
582 faff
->lastat
[level
] = newitem
;
583 for (i
= level
+1; i
< 4; i
++) faff
->lastat
[i
] = NULL
;
588 * This _huge_ function is the configuration box.
590 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
591 WPARAM wParam
, LPARAM lParam
,
594 struct treeview_faff tvfaff
;
597 char filename
[sizeof(cfg
.keyfile
)];
600 char fontstatic
[256];
606 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
610 { /* centre the window */
613 hw
= GetDesktopWindow();
614 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
615 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
616 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
617 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
621 * Create the tree view.
628 r
.left
= 3; r
.right
= r
.left
+ 75;
629 r
.top
= 3; r
.bottom
= r
.top
+ 10;
630 MapDialogRect(hwnd
, &r
);
631 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
632 WS_CHILD
| WS_VISIBLE
,
634 r
.right
-r
.left
, r
.bottom
-r
.top
,
635 hwnd
, (HMENU
)IDCX_TVSTATIC
, hinst
, NULL
);
636 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
637 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
639 r
.left
= 3; r
.right
= r
.left
+ 75;
640 r
.top
= 13; r
.bottom
= r
.top
+ 206;
641 MapDialogRect(hwnd
, &r
);
642 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
643 WS_CHILD
| WS_VISIBLE
|
644 WS_TABSTOP
| TVS_HASLINES
|
645 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
|
646 TVS_LINESATROOT
| TVS_SHOWSELALWAYS
,
648 r
.right
-r
.left
, r
.bottom
-r
.top
,
649 hwnd
, (HMENU
)IDCX_TREEVIEW
, hinst
, NULL
);
650 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
651 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
652 tvfaff
.treeview
= treeview
;
653 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
657 * Create the various panelfuls of controls.
660 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
663 ctlposinit(&cp
, hwnd
, 80, 3, 13);
664 bartitle(&cp
, "Basic options for your PuTTY session",
667 beginbox(&cp
, "Specify your connection by host name",
668 IDC_BOX_SESSION1
, IDC_BOXT_SESSION1
);
670 "Host &Name", IDC_HOSTSTATIC
, IDC_HOST
, 75,
671 "&Port", IDC_PORTSTATIC
, IDC_PORT
, 25, NULL
);
672 if (backends
[2].backend
== NULL
) {
673 /* this is PuTTYtel, so only two protocols available */
674 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
676 "&Telnet", IDC_PROTTELNET
, NULL
);
678 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
680 "&Telnet", IDC_PROTTELNET
,
689 beginbox(&cp
, "Load, save or delete a stored session",
690 IDC_BOX_SESSION2
, IDC_BOXT_SESSION2
);
691 sesssaver(&cp
, "Sav&ed Sessions",
692 IDC_SESSSTATIC
, IDC_SESSEDIT
, IDC_SESSLIST
,
693 "&Load", IDC_SESSLOAD
,
694 "&Save", IDC_SESSSAVE
,
695 "&Delete", IDC_SESSDEL
, NULL
);
698 beginbox(&cp
, NULL
, IDC_BOX_SESSION3
, 0);
699 checkbox(&cp
, "Close Window on E&xit", IDC_CLOSEEXIT
);
702 hsession
= treeview_insert(&tvfaff
, 0, "Session");
705 /* The Terminal panel. Accelerators used: [acgo] &dlbenu */
708 ctlposinit(&cp
, hwnd
, 80, 3, 13);
709 bartitle(&cp
, "Options controlling the terminal emulation",
711 beginbox(&cp
, "Set various terminal options",
712 IDC_BOX_TERMINAL1
, IDC_BOXT_TERMINAL1
);
713 checkbox(&cp
, "Auto &wrap mode initially on", IDC_WRAPMODE
);
714 checkbox(&cp
, "&DEC Origin Mode initially on", IDC_DECOM
);
715 checkbox(&cp
, "Implicit CR in every &LF", IDC_LFHASCR
);
716 checkbox(&cp
, "&Beep enabled", IDC_BEEP
);
717 checkbox(&cp
, "Use background colour to &erase screen", IDC_BCE
);
718 checkbox(&cp
, "Enable bli&nking text", IDC_BLINKTEXT
);
719 checkbox(&cp
, "&Use local terminal line discipline", IDC_LDISCTERM
);
722 treeview_insert(&tvfaff
, 0, "Terminal");
725 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
728 ctlposinit(&cp
, hwnd
, 80, 3, 13);
729 bartitle(&cp
, "Options controlling the effects of keys",
731 beginbox(&cp
, "Change the sequences sent by:",
732 IDC_BOX_KEYBOARD1
, IDC_BOXT_KEYBOARD1
);
733 radioline(&cp
, "The Backspace key", IDC_DELSTATIC
, 2,
734 "Control-&H", IDC_DEL008
,
735 "Control-&? (127)", IDC_DEL127
, NULL
);
736 radioline(&cp
, "The Home and End keys", IDC_HOMESTATIC
, 2,
737 "&Standard", IDC_HOMETILDE
,
738 "&rxvt", IDC_HOMERXVT
, NULL
);
739 radioline(&cp
, "The Function keys and keypad", IDC_FUNCSTATIC
, 4,
740 "ESC[n&~", IDC_FUNCTILDE
,
741 "&Linux", IDC_FUNCLINUX
,
742 "&Xterm R6", IDC_FUNCXTERM
,
743 "&VT400", IDC_FUNCVT400
, NULL
);
745 beginbox(&cp
, "Application keypad settings:",
746 IDC_BOX_KEYBOARD2
, IDC_BOXT_KEYBOARD2
);
748 "Application c&ursor keys totally disabled",
750 radioline(&cp
, "Initial state of cursor keys:", IDC_CURSTATIC
, 2,
751 "&Normal", IDC_CURNORMAL
,
752 "A&pplication", IDC_CURAPPLIC
, NULL
);
754 "Application ke&ypad keys totally disabled",
756 radioline(&cp
, "Initial state of numeric keypad:", IDC_KPSTATIC
, 3,
757 "Nor&mal", IDC_KPNORMAL
,
758 "Appl&ication", IDC_KPAPPLIC
,
759 "N&etHack", IDC_KPNH
, NULL
);
761 beginbox(&cp
, "Enable extra keyboard features:",
762 IDC_BOX_KEYBOARD3
, IDC_BOXT_KEYBOARD3
);
763 checkbox(&cp
, "Application and AltGr ac&t as Compose key",
767 treeview_insert(&tvfaff
, 1, "Keyboard");
770 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
773 ctlposinit(&cp
, hwnd
, 80, 3, 13);
774 bartitle(&cp
, "Options controlling PuTTY's window",
776 beginbox(&cp
, "Set the size of the window",
777 IDC_BOX_WINDOW1
, IDC_BOXT_WINDOW1
);
779 "&Rows", IDC_ROWSSTATIC
, IDC_ROWSEDIT
, 50,
780 "Colu&mns", IDC_COLSSTATIC
, IDC_COLSEDIT
, 50,
782 checkbox(&cp
, "Loc&k window size against resizing", IDC_LOCKSIZE
);
784 beginbox(&cp
, "Control the scrollback in the window",
785 IDC_BOX_WINDOW2
, IDC_BOXT_WINDOW2
);
786 staticedit(&cp
, "Lines of &scrollback",
787 IDC_SAVESTATIC
, IDC_SAVEEDIT
, 50);
788 checkbox(&cp
, "&Display scrollbar", IDC_SCROLLBAR
);
789 checkbox(&cp
, "Reset scrollback on &keypress", IDC_SCROLLKEY
);
790 checkbox(&cp
, "Reset scrollback on dis&play activity",
793 beginbox(&cp
, NULL
, IDC_BOX_WINDOW3
, 0);
794 checkbox(&cp
, "&Warn before closing window", IDC_CLOSEWARN
);
795 checkbox(&cp
, "Window closes on ALT-F&4", IDC_ALTF4
);
796 checkbox(&cp
, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE
);
797 checkbox(&cp
, "System menu appears on A< alone", IDC_ALTONLY
);
798 checkbox(&cp
, "Ensure window is always on &top", IDC_ALWAYSONTOP
);
801 treeview_insert(&tvfaff
, 0, "Window");
804 /* The Appearance panel. Accelerators used: [acgo] rmkhti */
807 ctlposinit(&cp
, hwnd
, 80, 3, 13);
808 bartitle(&cp
, "Options controlling PuTTY's appearance",
809 IDC_TITLE_APPEARANCE
);
810 beginbox(&cp
, "Adjust the use of the cursor",
811 IDC_BOX_APPEARANCE1
, IDC_BOXT_APPEARANCE1
);
812 checkbox(&cp
, "Cursor &blinks", IDC_BLINKCUR
);
814 beginbox(&cp
, "Set the font used in the terminal window",
815 IDC_BOX_APPEARANCE2
, IDC_BOXT_APPEARANCE2
);
816 staticbtn(&cp
, "", IDC_FONTSTATIC
, "C&hange...", IDC_CHOOSEFONT
);
818 beginbox(&cp
, "Adjust the use of the window title",
819 IDC_BOX_APPEARANCE3
, IDC_BOXT_APPEARANCE3
);
822 "Initial window &title:", IDC_WINTITLE
,
823 IDC_WINEDIT
, 100, NULL
);
824 checkbox(&cp
, "Avoid ever using &icon title", IDC_WINNAME
);
827 treeview_insert(&tvfaff
, 1, "Appearance");
830 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
833 ctlposinit(&cp
, hwnd
, 80, 3, 13);
834 bartitle(&cp
, "Options controlling character set translation",
835 IDC_TITLE_TRANSLATION
);
836 beginbox(&cp
, "Adjust how PuTTY displays line drawing characters",
837 IDC_BOX_TRANSLATION1
, IDC_BOXT_TRANSLATION1
);
839 "Handling of line drawing characters:", IDC_VTSTATIC
,
840 "Font has &XWindows encoding", IDC_VTXWINDOWS
,
841 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI
,
842 "Use font in O&EM mode only", IDC_VTOEMONLY
,
843 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
844 IDC_VTPOORMAN
, NULL
);
846 beginbox(&cp
, "Enable character set translation on received data",
847 IDC_BOX_TRANSLATION2
, IDC_BOXT_TRANSLATION2
);
849 "Character set translation:", IDC_XLATSTATIC
,
851 "&KOI8 / Win-1251", IDC_KOI8WIN1251
,
852 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250
,
853 "&ISO-8859-2 / CP852", IDC_88592CP852
, NULL
);
855 beginbox(&cp
, "Enable character set translation on input data",
856 IDC_BOX_TRANSLATION3
, IDC_BOXT_TRANSLATION3
);
857 checkbox(&cp
, "CAP&S LOCK acts as cyrillic switch",
861 treeview_insert(&tvfaff
, 1, "Translation");
864 /* The Selection panel. Accelerators used: [acgo] wxst */
867 ctlposinit(&cp
, hwnd
, 80, 3, 13);
868 bartitle(&cp
, "Options controlling copy and paste",
869 IDC_TITLE_SELECTION
);
870 beginbox(&cp
, "Control which mouse button does which thing",
871 IDC_BOX_SELECTION1
, IDC_BOXT_SELECTION1
);
872 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
873 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
874 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
877 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
878 IDC_BOX_SELECTION2
, IDC_BOXT_SELECTION2
);
879 charclass(&cp
, "Character classes:", IDC_CCSTATIC
, IDC_CCLIST
,
880 "&Set", IDC_CCSET
, IDC_CCEDIT
,
881 "&to class", IDC_CCSTATIC2
);
884 treeview_insert(&tvfaff
, 1, "Selection");
887 /* The Colours panel. Accelerators used: [acgo] blum */
890 ctlposinit(&cp
, hwnd
, 80, 3, 13);
891 bartitle(&cp
, "Options controlling use of colours",
893 beginbox(&cp
, "General options for colour usage",
894 IDC_BOX_COLOURS1
, IDC_BOXT_COLOURS1
);
895 checkbox(&cp
, "&Bolded text is a different colour", IDC_BOLDCOLOUR
);
896 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
898 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
899 IDC_BOX_COLOURS2
, IDC_BOXT_COLOURS2
);
900 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
901 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
902 "&Modify...", IDC_CHANGE
,
903 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
904 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
905 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
908 treeview_insert(&tvfaff
, 1, "Colours");
911 /* The Connection panel. Accelerators used: [acgo] tuk */
914 ctlposinit(&cp
, hwnd
, 80, 3, 13);
915 bartitle(&cp
, "Options controlling the connection", IDC_TITLE_CONNECTION
);
917 beginbox(&cp
, "Data to send to the server",
918 IDC_BOX_CONNECTION1
, IDC_BOXT_CONNECTION1
);
919 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
, IDC_TTEDIT
, 50);
920 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
, IDC_LOGEDIT
, 50);
923 beginbox(&cp
, "Sending of null packets to keep session active",
924 IDC_BOX_CONNECTION2
, IDC_BOXT_CONNECTION2
);
925 staticedit(&cp
, "Minutes between &keepalives (0 to turn off)",
926 IDC_PINGSTATIC
, IDC_PINGEDIT
, 25);
929 treeview_insert(&tvfaff
, 0, "Connection");
932 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
935 ctlposinit(&cp
, hwnd
, 80, 3, 13);
937 bartitle(&cp
, "Options controlling Telnet connections", IDC_TITLE_TELNET
);
938 beginbox(&cp
, "Data to send to the server",
939 IDC_BOX_TELNET1
, IDC_BOXT_TELNET1
);
940 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
, IDC_TSEDIT
, 50);
941 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
942 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
,
943 "Va&lue", IDC_VALSTATIC
, IDC_VALEDIT
,
945 "A&dd", IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
947 beginbox(&cp
, "Telnet protocol adjustments",
948 IDC_BOX_TELNET2
, IDC_BOXT_TELNET2
);
949 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC
, 2,
950 "&BSD (commonplace)", IDC_EMBSD
,
951 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
954 treeview_insert(&tvfaff
, 1, "Telnet");
958 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
959 if (backends
[2].backend
!= NULL
) {
961 ctlposinit(&cp
, hwnd
, 80, 3, 13);
963 bartitle(&cp
, "Options controlling SSH connections", IDC_TITLE_SSH
);
964 beginbox(&cp
, "Data to send to the server",
965 IDC_BOX_SSH1
, IDC_BOXT_SSH1
);
967 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
970 beginbox(&cp
, "Authentication options",
971 IDC_BOX_SSH2
, IDC_BOXT_SSH2
);
972 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
974 checkbox(&cp
, "Allow &agent forwarding", IDC_AGENTFWD
);
975 editbutton(&cp
, "Private &key file for authentication:",
976 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...", IDC_PKBUTTON
);
978 beginbox(&cp
, "Protocol options",
979 IDC_BOX_SSH3
, IDC_BOXT_SSH3
);
980 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
981 checkbox(&cp
, "Enable compr&ession", IDC_COMPRESS
);
982 radioline(&cp
, "Preferred SSH protocol version:",
983 IDC_SSHPROTSTATIC
, 2,
984 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
985 radioline(&cp
, "Preferred encryption algorithm:", IDC_CIPHERSTATIC
, 3,
986 "&3DES", IDC_CIPHER3DES
,
987 "&Blowfish", IDC_CIPHERBLOWF
,
988 "&DES", IDC_CIPHERDES
, NULL
);
989 checkbox(&cp
, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
993 treeview_insert(&tvfaff
, 1, "SSH");
997 init_dlg_ctrls(hwnd
);
998 for (i
= 0; i
< nsessions
; i
++)
999 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1000 0, (LPARAM
) (sessions
[i
]));
1003 * Hide all the controls to start with.
1005 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
1008 * Put the treeview selection on to the Session panel. This
1009 * should also cause unhiding of the relevant controls.
1011 TreeView_SelectItem(treeview
, hsession
);
1014 * Set focus into the first available control.
1018 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
1019 if (!ctl
) ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
1023 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1027 * Button release should trigger WM_OK if there was a
1028 * previous double click on the session list.
1032 SendMessage (hwnd
, WM_COMMAND
, IDOK
, 0);
1035 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1036 ((LPNMHDR
)lParam
)->code
== TVN_SELCHANGED
) {
1037 HTREEITEM i
= TreeView_GetSelection(((LPNMHDR
)lParam
)->hwndFrom
);
1041 item
.pszText
= buffer
;
1042 item
.cchTextMax
= sizeof(buffer
);
1043 item
.mask
= TVIF_TEXT
;
1044 TreeView_GetItem(((LPNMHDR
)lParam
)->hwndFrom
, &item
);
1045 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
1046 if (!strcmp(buffer
, "Session"))
1047 hide(hwnd
, FALSE
, sessionpanelstart
, sessionpanelend
);
1048 if (!strcmp(buffer
, "Keyboard"))
1049 hide(hwnd
, FALSE
, keyboardpanelstart
, keyboardpanelend
);
1050 if (!strcmp(buffer
, "Terminal"))
1051 hide(hwnd
, FALSE
, terminalpanelstart
, terminalpanelend
);
1052 if (!strcmp(buffer
, "Window"))
1053 hide(hwnd
, FALSE
, windowpanelstart
, windowpanelend
);
1054 if (!strcmp(buffer
, "Appearance"))
1055 hide(hwnd
, FALSE
, appearancepanelstart
, appearancepanelend
);
1056 if (!strcmp(buffer
, "Connection"))
1057 hide(hwnd
, FALSE
, connectionpanelstart
, connectionpanelend
);
1058 if (!strcmp(buffer
, "Telnet"))
1059 hide(hwnd
, FALSE
, telnetpanelstart
, telnetpanelend
);
1060 if (!strcmp(buffer
, "SSH"))
1061 hide(hwnd
, FALSE
, sshpanelstart
, sshpanelend
);
1062 if (!strcmp(buffer
, "Selection"))
1063 hide(hwnd
, FALSE
, selectionpanelstart
, selectionpanelend
);
1064 if (!strcmp(buffer
, "Colours"))
1065 hide(hwnd
, FALSE
, colourspanelstart
, colourspanelend
);
1066 if (!strcmp(buffer
, "Translation"))
1067 hide(hwnd
, FALSE
, translationpanelstart
, translationpanelend
);
1069 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1075 * Only process WM_COMMAND once the dialog is fully formed.
1077 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1) switch (LOWORD(wParam
)) {
1080 EndDialog (hwnd
, 1);
1085 EndDialog (hwnd
, 0);
1087 case IDC_PROTTELNET
:
1090 if (HIWORD(wParam
) == BN_CLICKED
||
1091 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1092 int i
= IsDlgButtonChecked (hwnd
, IDC_PROTSSH
);
1093 int j
= IsDlgButtonChecked (hwnd
, IDC_PROTTELNET
);
1094 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
1095 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
1096 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
1097 cfg
.port
= i ?
22 : 23;
1098 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1103 if (HIWORD(wParam
) == EN_CHANGE
)
1104 GetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
,
1105 sizeof(cfg
.host
)-1);
1108 if (HIWORD(wParam
) == EN_CHANGE
)
1109 MyGetDlgItemInt (hwnd
, IDC_PORT
, &cfg
.port
);
1112 if (HIWORD(wParam
) == EN_CHANGE
) {
1113 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1115 GetDlgItemText (hwnd
, IDC_SESSEDIT
,
1116 savedsession
, sizeof(savedsession
)-1);
1117 savedsession
[sizeof(savedsession
)-1] = '\0';
1121 if (HIWORD(wParam
) == BN_CLICKED
||
1122 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1127 GetDlgItemText (hwnd
, IDC_SESSEDIT
, str
, sizeof(str
)-1);
1129 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1130 LB_GETCURSEL
, 0, 0);
1135 strcpy (str
, sessions
[n
]);
1137 save_settings (str
, !!strcmp(str
, "Default Settings"), &cfg
);
1138 get_sesslist (FALSE
);
1139 get_sesslist (TRUE
);
1140 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1142 for (i
= 0; i
< nsessions
; i
++)
1143 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1144 0, (LPARAM
) (sessions
[i
]));
1145 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1151 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1152 HIWORD(wParam
) != BN_CLICKED
&&
1153 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1155 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1156 HIWORD(wParam
) != LBN_DBLCLK
)
1159 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1160 LB_GETCURSEL
, 0, 0);
1166 isdef
= !strcmp(sessions
[n
], "Default Settings");
1167 load_settings (sessions
[n
], !isdef
, &cfg
);
1168 init_dlg_ctrls(hwnd
);
1170 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1172 SetDlgItemText(hwnd
, IDC_SESSEDIT
, "");
1174 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1176 * A double-click on a saved session should
1177 * actually start the session, not just load it.
1178 * Unless it's Default Settings or some other
1179 * host-less set of saved settings.
1188 if (HIWORD(wParam
) == BN_CLICKED
||
1189 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1190 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1191 LB_GETCURSEL
, 0, 0);
1192 if (n
== LB_ERR
|| n
== 0) {
1196 del_settings(sessions
[n
]);
1197 get_sesslist (FALSE
);
1198 get_sesslist (TRUE
);
1199 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1201 for (i
= 0; i
< nsessions
; i
++)
1202 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1203 0, (LPARAM
) (sessions
[i
]));
1204 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1208 if (HIWORD(wParam
) == EN_CHANGE
)
1209 MyGetDlgItemInt (hwnd
, IDC_PINGEDIT
, &cfg
.ping_interval
);
1213 if (HIWORD(wParam
) == BN_CLICKED
||
1214 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1215 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC_DEL127
);
1219 if (HIWORD(wParam
) == BN_CLICKED
||
1220 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1221 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC_HOMERXVT
);
1224 if (HIWORD(wParam
) == BN_CLICKED
||
1225 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1229 if (HIWORD(wParam
) == BN_CLICKED
||
1230 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1235 if (HIWORD(wParam
) == BN_CLICKED
||
1236 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1237 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC_FUNCLINUX
);
1241 if (HIWORD(wParam
) == BN_CLICKED
||
1242 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1243 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC_KPAPPLIC
);
1244 cfg
.nethack_keypad
= FALSE
;
1248 if (HIWORD(wParam
) == BN_CLICKED
||
1249 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1250 cfg
.app_keypad
= FALSE
;
1251 cfg
.nethack_keypad
= TRUE
;
1256 if (HIWORD(wParam
) == BN_CLICKED
||
1257 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1258 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC_CURAPPLIC
);
1261 if (HIWORD(wParam
) == BN_CLICKED
||
1262 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1263 cfg
.no_applic_c
= IsDlgButtonChecked (hwnd
, IDC_NOAPPLICC
);
1266 if (HIWORD(wParam
) == BN_CLICKED
||
1267 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1268 cfg
.no_applic_k
= IsDlgButtonChecked (hwnd
, IDC_NOAPPLICK
);
1271 if (HIWORD(wParam
) == BN_CLICKED
||
1272 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1273 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC_ALTF4
);
1276 if (HIWORD(wParam
) == BN_CLICKED
||
1277 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1278 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC_ALTSPACE
);
1281 if (HIWORD(wParam
) == BN_CLICKED
||
1282 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1283 cfg
.alt_only
= IsDlgButtonChecked (hwnd
, IDC_ALTONLY
);
1286 if (HIWORD(wParam
) == BN_CLICKED
||
1287 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1288 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC_LDISCTERM
);
1290 case IDC_ALWAYSONTOP
:
1291 if (HIWORD(wParam
) == BN_CLICKED
||
1292 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1293 cfg
.alwaysontop
= IsDlgButtonChecked (hwnd
, IDC_ALWAYSONTOP
);
1296 if (HIWORD(wParam
) == BN_CLICKED
||
1297 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1298 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC_SCROLLKEY
);
1300 case IDC_SCROLLDISP
:
1301 if (HIWORD(wParam
) == BN_CLICKED
||
1302 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1303 cfg
.scroll_on_disp
= IsDlgButtonChecked (hwnd
, IDC_SCROLLDISP
);
1305 case IDC_COMPOSEKEY
:
1306 if (HIWORD(wParam
) == BN_CLICKED
||
1307 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1308 cfg
.compose_key
= IsDlgButtonChecked (hwnd
, IDC_COMPOSEKEY
);
1311 if (HIWORD(wParam
) == BN_CLICKED
||
1312 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1313 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC_WRAPMODE
);
1316 if (HIWORD(wParam
) == BN_CLICKED
||
1317 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1318 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC_DECOM
);
1321 if (HIWORD(wParam
) == BN_CLICKED
||
1322 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1323 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC_LFHASCR
);
1326 if (HIWORD(wParam
) == EN_CHANGE
)
1327 MyGetDlgItemInt (hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1330 if (HIWORD(wParam
) == EN_CHANGE
)
1331 MyGetDlgItemInt (hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1334 if (HIWORD(wParam
) == EN_CHANGE
)
1335 MyGetDlgItemInt (hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1337 case IDC_CHOOSEFONT
:
1338 lf
.lfHeight
= cfg
.fontheight
;
1339 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1340 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1341 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1342 lf
.lfCharSet
= cfg
.fontcharset
;
1343 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1344 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1345 lf
.lfQuality
= DEFAULT_QUALITY
;
1346 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1347 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
1348 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
1350 cf
.lStructSize
= sizeof(cf
);
1351 cf
.hwndOwner
= hwnd
;
1353 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1354 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1356 if (ChooseFont (&cf
)) {
1357 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
1358 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
1359 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1360 cfg
.fontcharset
= lf
.lfCharSet
;
1361 cfg
.fontheight
= lf
.lfHeight
;
1362 fmtfont (fontstatic
);
1363 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
1367 if (HIWORD(wParam
) == BN_CLICKED
||
1368 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1369 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC_BEEP
);
1372 if (HIWORD(wParam
) == BN_CLICKED
||
1373 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1374 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC_BLINKTEXT
);
1377 if (HIWORD(wParam
) == BN_CLICKED
||
1378 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1379 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC_BCE
);
1382 if (HIWORD(wParam
) == BN_CLICKED
||
1383 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1384 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC_WINNAME
);
1387 if (HIWORD(wParam
) == BN_CLICKED
||
1388 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1389 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC_BLINKCUR
);
1392 if (HIWORD(wParam
) == BN_CLICKED
||
1393 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1394 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC_SCROLLBAR
);
1397 if (HIWORD(wParam
) == BN_CLICKED
||
1398 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1399 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC_LOCKSIZE
);
1402 if (HIWORD(wParam
) == EN_CHANGE
)
1403 GetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
1404 sizeof(cfg
.wintitle
)-1);
1407 if (HIWORD(wParam
) == BN_CLICKED
||
1408 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1409 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC_CLOSEEXIT
);
1412 if (HIWORD(wParam
) == BN_CLICKED
||
1413 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1414 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC_CLOSEWARN
);
1417 if (HIWORD(wParam
) == EN_CHANGE
)
1418 GetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
,
1419 sizeof(cfg
.termtype
)-1);
1422 if (HIWORD(wParam
) == EN_CHANGE
)
1423 GetDlgItemText (hwnd
, IDC_TSEDIT
, cfg
.termspeed
,
1424 sizeof(cfg
.termspeed
)-1);
1427 if (HIWORD(wParam
) == EN_CHANGE
)
1428 GetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
,
1429 sizeof(cfg
.username
)-1);
1433 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC_EMRFC
);
1436 if (HIWORD(wParam
) == BN_CLICKED
||
1437 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1438 char str
[sizeof(cfg
.environmt
)];
1440 GetDlgItemText (hwnd
, IDC_VAREDIT
, str
, sizeof(str
)-1);
1445 p
= str
+ strlen(str
);
1447 GetDlgItemText (hwnd
, IDC_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
1457 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
1459 p
[strlen(str
)+1] = '\0';
1460 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
1462 SetDlgItemText (hwnd
, IDC_VAREDIT
, "");
1463 SetDlgItemText (hwnd
, IDC_VALEDIT
, "");
1465 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
1466 MB_OK
| MB_ICONERROR
);
1471 if (HIWORD(wParam
) != BN_CLICKED
&&
1472 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1474 i
= SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0, 0);
1480 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
1505 if (HIWORD(wParam
) == BN_CLICKED
||
1506 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1507 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC_NOPTY
);
1510 if (HIWORD(wParam
) == BN_CLICKED
||
1511 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1512 cfg
.compression
= IsDlgButtonChecked (hwnd
, IDC_COMPRESS
);
1515 if (HIWORD(wParam
) == BN_CLICKED
||
1516 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1517 cfg
.buggymac
= IsDlgButtonChecked (hwnd
, IDC_BUGGYMAC
);
1520 if (HIWORD(wParam
) == BN_CLICKED
||
1521 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1522 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC_AGENTFWD
);
1524 case IDC_CIPHER3DES
:
1525 case IDC_CIPHERBLOWF
:
1527 if (HIWORD(wParam
) == BN_CLICKED
||
1528 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1529 if (IsDlgButtonChecked (hwnd
, IDC_CIPHER3DES
))
1530 cfg
.cipher
= CIPHER_3DES
;
1531 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERBLOWF
))
1532 cfg
.cipher
= CIPHER_BLOWFISH
;
1533 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERDES
))
1534 cfg
.cipher
= CIPHER_DES
;
1539 if (HIWORD(wParam
) == BN_CLICKED
||
1540 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1541 if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT1
))
1543 else if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT2
))
1548 if (HIWORD(wParam
) == BN_CLICKED
||
1549 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1550 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC_AUTHTIS
);
1553 if (HIWORD(wParam
) == EN_CHANGE
)
1554 GetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
1555 sizeof(cfg
.keyfile
)-1);
1558 if (HIWORD(wParam
) == EN_CHANGE
)
1559 GetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
1560 sizeof(cfg
.remote_cmd
)-1);
1563 memset(&of
, 0, sizeof(of
));
1564 #ifdef OPENFILENAME_SIZE_VERSION_400
1565 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1567 of
.lStructSize
= sizeof(of
);
1569 of
.hwndOwner
= hwnd
;
1570 of
.lpstrFilter
= "All Files\0*\0\0\0";
1571 of
.lpstrCustomFilter
= NULL
;
1572 of
.nFilterIndex
= 1;
1573 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1574 of
.nMaxFile
= sizeof(filename
);
1575 of
.lpstrFileTitle
= NULL
;
1576 of
.lpstrInitialDir
= NULL
;
1577 of
.lpstrTitle
= "Select Public Key File";
1579 if (GetOpenFileName(&of
)) {
1580 strcpy(cfg
.keyfile
, filename
);
1581 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
1586 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC_MBXTERM
);
1592 int n
= GetDlgItemInt (hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
1597 for (i
=0; i
<256; i
++)
1598 if (SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_GETSEL
,
1601 cfg
.wordness
[i
] = n
;
1602 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
1603 LB_DELETESTRING
, i
, 0);
1604 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1605 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1607 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
1614 case IDC_BOLDCOLOUR
:
1615 if (HIWORD(wParam
) == BN_CLICKED
||
1616 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1618 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC_BOLDCOLOUR
);
1619 n
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
1620 if (n
!= 12+10*cfg
.bold_colour
) {
1622 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
1623 LB_DELETESTRING
, i
, 0);
1624 for (i
=0; i
<22; i
++)
1625 if (cfg
.bold_colour
|| permcolour
[i
])
1626 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
1628 (LPARAM
) colours
[i
]);
1633 if (HIWORD(wParam
) == BN_CLICKED
||
1634 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1635 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC_PALETTE
);
1637 case IDC_COLOURLIST
:
1638 if (HIWORD(wParam
) == LBN_DBLCLK
||
1639 HIWORD(wParam
) == LBN_SELCHANGE
) {
1640 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
1642 if (!cfg
.bold_colour
)
1643 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1644 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1645 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1646 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1650 if (HIWORD(wParam
) == BN_CLICKED
||
1651 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1652 static CHOOSECOLOR cc
;
1653 static DWORD custom
[16] = {0}; /* zero initialisers */
1654 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
1656 if (!cfg
.bold_colour
)
1657 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1658 cc
.lStructSize
= sizeof(cc
);
1659 cc
.hwndOwner
= hwnd
;
1660 cc
.hInstance
= (HWND
)hinst
;
1661 cc
.lpCustColors
= custom
;
1662 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1664 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1665 if (ChooseColor(&cc
)) {
1667 (unsigned char) (cc
.rgbResult
& 0xFF);
1669 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1671 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1672 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
1674 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
1676 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
1682 case IDC_KOI8WIN1251
:
1683 case IDC_88592WIN1250
:
1684 case IDC_88592CP852
:
1685 cfg
.xlat_enablekoiwin
=
1686 IsDlgButtonChecked (hwnd
, IDC_KOI8WIN1251
);
1687 cfg
.xlat_88592w1250
=
1688 IsDlgButtonChecked (hwnd
, IDC_88592WIN1250
);
1689 cfg
.xlat_88592cp852
=
1690 IsDlgButtonChecked (hwnd
, IDC_88592CP852
);
1692 case IDC_CAPSLOCKCYR
:
1693 if (HIWORD(wParam
) == BN_CLICKED
||
1694 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1695 cfg
.xlat_capslockcyr
=
1696 IsDlgButtonChecked (hwnd
, IDC_CAPSLOCKCYR
);
1699 case IDC_VTXWINDOWS
:
1704 (IsDlgButtonChecked (hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
:
1705 IsDlgButtonChecked (hwnd
, IDC_VTOEMANSI
) ? VT_OEMANSI
:
1706 IsDlgButtonChecked (hwnd
, IDC_VTOEMONLY
) ? VT_OEMONLY
:
1712 EndDialog (hwnd
, 0);
1715 /* Grrr Explorer will maximize Dialogs! */
1717 if (wParam
== SIZE_MAXIMIZED
)
1724 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1725 WPARAM wParam
, LPARAM lParam
) {
1726 static HWND page
= NULL
;
1728 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1730 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
1731 EnableWindow(hwnd
, 0);
1732 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1733 GetParent(hwnd
), AboutProc
);
1734 EnableWindow(hwnd
, 1);
1735 SetActiveWindow(hwnd
);
1737 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 0);
1740 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1741 WPARAM wParam
, LPARAM lParam
) {
1743 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 1);
1746 void defuse_showwindow(void) {
1748 * Work around the fact that the app's first call to ShowWindow
1749 * will ignore the default in favour of the shell-provided
1754 hwnd
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1756 ShowWindow(hwnd
, SW_HIDE
);
1757 DestroyWindow(hwnd
);
1761 int do_config (void) {
1765 savedsession
[0] = '\0';
1766 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1767 get_sesslist(FALSE
);
1772 int do_reconfig (HWND hwnd
) {
1776 backup_cfg
= cfg
; /* structure copy */
1777 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1779 cfg
= backup_cfg
; /* structure copy */
1786 void logevent (char *string
) {
1787 if (nevents
>= negsize
) {
1789 events
= srealloc (events
, negsize
* sizeof(*events
));
1791 events
[nevents
] = smalloc(1+strlen(string
));
1792 strcpy (events
[nevents
], string
);
1796 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1798 count
= SendDlgItemMessage (logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
1799 SendDlgItemMessage (logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
-1, 0);
1803 void showeventlog (HWND hwnd
) {
1805 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1807 ShowWindow (logbox
, SW_SHOWNORMAL
);
1811 void showabout (HWND hwnd
) {
1813 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1815 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1819 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
1820 char *keystr
, char *fingerprint
) {
1823 static const char absentmsg
[] =
1824 "The server's host key is not cached in the registry. You\n"
1825 "have no guarantee that the server is the computer you\n"
1827 "The server's key fingerprint is:\n"
1829 "If you trust this host, hit Yes to add the key to\n"
1830 "PuTTY's cache and carry on connecting.\n"
1831 "If you do not trust this host, hit No to abandon the\n"
1834 static const char wrongmsg
[] =
1835 "WARNING - POTENTIAL SECURITY BREACH!\n"
1837 "The server's host key does not match the one PuTTY has\n"
1838 "cached in the registry. This means that either the\n"
1839 "server administrator has changed the host key, or you\n"
1840 "have actually connected to another computer pretending\n"
1841 "to be the server.\n"
1842 "The new key fingerprint is:\n"
1844 "If you were expecting this change and trust the new key,\n"
1845 "hit Yes to update PuTTY's cache and continue connecting.\n"
1846 "If you want to carry on connecting but without updating\n"
1847 "the cache, hit No.\n"
1848 "If you want to abandon the connection completely, hit\n"
1849 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1852 static const char mbtitle
[] = "PuTTY Security Alert";
1855 char message
[160+ /* sensible fingerprint max size */
1856 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
1857 sizeof(absentmsg
) : sizeof(wrongmsg
))];
1860 * Verify the key against the registry.
1862 ret
= verify_host_key(host
, port
, keytype
, keystr
);
1864 if (ret
== 0) /* success - key matched OK */
1866 if (ret
== 2) { /* key was different */
1868 sprintf(message
, wrongmsg
, fingerprint
);
1869 mbret
= MessageBox(NULL
, message
, mbtitle
,
1870 MB_ICONWARNING
| MB_YESNOCANCEL
);
1872 store_host_key(host
, port
, keytype
, keystr
);
1873 if (mbret
== IDCANCEL
)
1876 if (ret
== 1) { /* key was absent */
1878 sprintf(message
, absentmsg
, fingerprint
);
1879 mbret
= MessageBox(NULL
, message
, mbtitle
,
1880 MB_ICONWARNING
| MB_YESNO
);
1883 store_host_key(host
, port
, keytype
, keystr
);