15 static char **events
= NULL
;
16 static int nevents
= 0, negsize
= 0;
20 void force_normal(HWND hwnd
)
22 static int recurse
= 0;
30 wp
.length
= sizeof(wp
);
31 if (GetWindowPlacement(hwnd
, &wp
) && wp
.showCmd
== SW_SHOWMAXIMIZED
) {
32 wp
.showCmd
= SW_SHOWNORMAL
;
33 SetWindowPlacement(hwnd
, &wp
);
38 static void MyGetDlgItemInt(HWND hwnd
, int id
, int *result
)
42 n
= GetDlgItemInt(hwnd
, id
, &ok
, FALSE
);
47 static void MyGetDlgItemFlt(HWND hwnd
, int id
, int *result
, int scale
)
51 ok
= GetDlgItemText(hwnd
, id
, text
, sizeof(text
) - 1);
53 *result
= (int) (scale
* atof(text
));
56 static void MySetDlgItemFlt(HWND hwnd
, int id
, double value
)
59 sprintf(text
, "%g", value
);
60 SetDlgItemText(hwnd
, id
, text
);
63 static int CALLBACK
LogProc(HWND hwnd
, UINT msg
,
64 WPARAM wParam
, LPARAM lParam
)
71 static int tabs
[4] = { 78, 108 };
72 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_SETTABSTOPS
, 2,
75 for (i
= 0; i
< nevents
; i
++)
76 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_ADDSTRING
,
77 0, (LPARAM
) events
[i
]);
80 switch (LOWORD(wParam
)) {
84 SetActiveWindow(GetParent(hwnd
));
88 if (HIWORD(wParam
) == BN_CLICKED
||
89 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
92 selcount
= SendDlgItemMessage(hwnd
, IDN_LIST
,
93 LB_GETSELCOUNT
, 0, 0);
94 if (selcount
== 0) { /* don't even try to copy zero items */
99 selitems
= smalloc(selcount
* sizeof(int));
101 int count
= SendDlgItemMessage(hwnd
, IDN_LIST
,
108 static unsigned char sel_nl
[] = SEL_NL
;
110 if (count
== 0) { /* can't copy zero stuff */
116 for (i
= 0; i
< count
; i
++)
118 strlen(events
[selitems
[i
]]) + sizeof(sel_nl
);
120 clipdata
= smalloc(size
);
123 for (i
= 0; i
< count
; i
++) {
124 char *q
= events
[selitems
[i
]];
125 int qlen
= strlen(q
);
128 memcpy(p
, sel_nl
, sizeof(sel_nl
));
131 write_aclip(clipdata
, size
, TRUE
);
136 for (i
= 0; i
< nevents
; i
++)
137 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_SETSEL
,
146 SetActiveWindow(GetParent(hwnd
));
153 static int CALLBACK
LicenceProc(HWND hwnd
, UINT msg
,
154 WPARAM wParam
, LPARAM lParam
)
160 switch (LOWORD(wParam
)) {
173 static int CALLBACK
AboutProc(HWND hwnd
, UINT msg
,
174 WPARAM wParam
, LPARAM lParam
)
178 SetDlgItemText(hwnd
, IDA_VERSION
, ver
);
181 switch (LOWORD(wParam
)) {
184 EndDialog(hwnd
, TRUE
);
187 EnableWindow(hwnd
, 0);
188 DialogBox(hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
190 EnableWindow(hwnd
, 1);
191 SetActiveWindow(hwnd
);
195 /* Load web browser */
196 ShellExecute(hwnd
, "open",
197 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
198 0, 0, SW_SHOWDEFAULT
);
203 EndDialog(hwnd
, TRUE
);
210 * Null dialog procedure.
212 static int CALLBACK
NullDlgProc(HWND hwnd
, UINT msg
,
213 WPARAM wParam
, LPARAM lParam
)
218 static char savedsession
[2048];
221 IDC_ABOUT
, IDCX_TVSTATIC
, IDCX_TREEVIEW
, controlstartvalue
,
362 appearancepanelstart
,
363 IDC_TITLE_APPEARANCE
,
383 connectionpanelstart
,
384 IDC_TITLE_CONNECTION
,
485 translationpanelstart
,
486 IDC_TITLE_TRANSLATION
,
487 IDC_BOX_TRANSLATION1
,
488 IDC_BOX_TRANSLATION2
,
510 static const char *const colours
[] = {
511 "Default Foreground", "Default Bold Foreground",
512 "Default Background", "Default Bold Background",
513 "Cursor Text", "Cursor Colour",
514 "ANSI Black", "ANSI Black Bold",
515 "ANSI Red", "ANSI Red Bold",
516 "ANSI Green", "ANSI Green Bold",
517 "ANSI Yellow", "ANSI Yellow Bold",
518 "ANSI Blue", "ANSI Blue Bold",
519 "ANSI Magenta", "ANSI Magenta Bold",
520 "ANSI Cyan", "ANSI Cyan Bold",
521 "ANSI White", "ANSI White Bold"
523 static const int permcolour
[] = {
524 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
525 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
526 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
529 static void fmtfont(char *buf
)
531 sprintf(buf
, "Font: %s, ", cfg
.font
);
533 strcat(buf
, "bold, ");
534 if (cfg
.fontheight
== 0)
535 strcat(buf
, "default height");
537 sprintf(buf
+ strlen(buf
), "%d-point",
538 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
));
541 static void init_dlg_ctrls(HWND hwnd
)
544 char fontstatic
[256];
546 SetDlgItemText(hwnd
, IDC_HOST
, cfg
.host
);
547 SetDlgItemText(hwnd
, IDC_SESSEDIT
, savedsession
);
550 n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_GETCOUNT
, 0, 0);
551 for (i
= n
; i
-- > 0;)
552 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_DELETESTRING
, i
, 0);
553 for (i
= 0; i
< nsessions
; i
++)
554 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
555 0, (LPARAM
) (sessions
[i
]));
557 SetDlgItemInt(hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
558 CheckRadioButton(hwnd
, IDC_PROTRAW
, IDC_PROTSSH
,
559 cfg
.protocol
== PROT_SSH ? IDC_PROTSSH
:
560 cfg
.protocol
== PROT_TELNET ? IDC_PROTTELNET
:
562 PROT_RLOGIN ? IDC_PROTRLOGIN
: IDC_PROTRAW
);
563 SetDlgItemInt(hwnd
, IDC_PINGEDIT
, cfg
.ping_interval
, FALSE
);
565 CheckRadioButton(hwnd
, IDC_DEL008
, IDC_DEL127
,
566 cfg
.bksp_is_delete ? IDC_DEL127
: IDC_DEL008
);
567 CheckRadioButton(hwnd
, IDC_HOMETILDE
, IDC_HOMERXVT
,
568 cfg
.rxvt_homeend ? IDC_HOMERXVT
: IDC_HOMETILDE
);
569 CheckRadioButton(hwnd
, IDC_FUNCTILDE
, IDC_FUNCSCO
,
570 cfg
.funky_type
== 0 ? IDC_FUNCTILDE
:
571 cfg
.funky_type
== 1 ? IDC_FUNCLINUX
:
572 cfg
.funky_type
== 2 ? IDC_FUNCXTERM
:
573 cfg
.funky_type
== 3 ? IDC_FUNCVT400
:
574 cfg
.funky_type
== 4 ? IDC_FUNCVT100P
:
575 cfg
.funky_type
== 5 ? IDC_FUNCSCO
: IDC_FUNCTILDE
);
576 CheckDlgButton(hwnd
, IDC_NOAPPLICC
, cfg
.no_applic_c
);
577 CheckDlgButton(hwnd
, IDC_NOAPPLICK
, cfg
.no_applic_k
);
578 CheckRadioButton(hwnd
, IDC_CURNORMAL
, IDC_CURAPPLIC
,
579 cfg
.app_cursor ? IDC_CURAPPLIC
: IDC_CURNORMAL
);
580 CheckRadioButton(hwnd
, IDC_KPNORMAL
, IDC_KPNH
,
581 cfg
.nethack_keypad ? IDC_KPNH
:
582 cfg
.app_keypad ? IDC_KPAPPLIC
: IDC_KPNORMAL
);
583 CheckDlgButton(hwnd
, IDC_ALTF4
, cfg
.alt_f4
);
584 CheckDlgButton(hwnd
, IDC_ALTSPACE
, cfg
.alt_space
);
585 CheckDlgButton(hwnd
, IDC_ALTONLY
, cfg
.alt_only
);
586 CheckDlgButton(hwnd
, IDC_COMPOSEKEY
, cfg
.compose_key
);
587 CheckDlgButton(hwnd
, IDC_CTRLALTKEYS
, cfg
.ctrlaltkeys
);
588 CheckDlgButton(hwnd
, IDC_TELNETKEY
, cfg
.telnet_keyboard
);
589 CheckRadioButton(hwnd
, IDC_ECHOBACKEND
, IDC_ECHONO
,
590 cfg
.localecho
== LD_BACKEND ? IDC_ECHOBACKEND
:
591 cfg
.localecho
== LD_YES ? IDC_ECHOYES
: IDC_ECHONO
);
592 CheckRadioButton(hwnd
, IDC_EDITBACKEND
, IDC_EDITNO
,
593 cfg
.localedit
== LD_BACKEND ? IDC_EDITBACKEND
:
594 cfg
.localedit
== LD_YES ? IDC_EDITYES
: IDC_EDITNO
);
595 SetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
);
596 CheckDlgButton(hwnd
, IDC_ALWAYSONTOP
, cfg
.alwaysontop
);
597 CheckDlgButton(hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
598 CheckDlgButton(hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
600 CheckDlgButton(hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
601 CheckDlgButton(hwnd
, IDC_DECOM
, cfg
.dec_om
);
602 CheckDlgButton(hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
603 SetDlgItemInt(hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
604 SetDlgItemInt(hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
605 SetDlgItemInt(hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
607 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
608 CheckRadioButton(hwnd
, IDC_BELL_DISABLED
, IDC_BELL_VISUAL
,
609 cfg
.beep
== BELL_DISABLED ? IDC_BELL_DISABLED
:
610 cfg
.beep
== BELL_DEFAULT ? IDC_BELL_DEFAULT
:
611 cfg
.beep
== BELL_WAVEFILE ? IDC_BELL_WAVEFILE
:
613 BELL_VISUAL ? IDC_BELL_VISUAL
: IDC_BELL_DEFAULT
);
614 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
, cfg
.bell_wavefile
);
615 CheckDlgButton(hwnd
, IDC_BELLOVL
, cfg
.bellovl
);
616 SetDlgItemInt(hwnd
, IDC_BELLOVLN
, cfg
.bellovl_n
, FALSE
);
617 MySetDlgItemFlt(hwnd
, IDC_BELLOVLT
, cfg
.bellovl_t
/ 1000.0);
618 MySetDlgItemFlt(hwnd
, IDC_BELLOVLS
, cfg
.bellovl_s
/ 1000.0);
620 CheckDlgButton(hwnd
, IDC_BCE
, cfg
.bce
);
621 CheckDlgButton(hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
623 SetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
624 CheckDlgButton(hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
625 CheckDlgButton(hwnd
, IDC_HIDEMOUSE
, cfg
.hide_mouseptr
);
626 CheckDlgButton(hwnd
, IDC_SUNKENEDGE
, cfg
.sunken_edge
);
627 CheckRadioButton(hwnd
, IDC_CURBLOCK
, IDC_CURVERT
,
628 cfg
.cursor_type
== 0 ? IDC_CURBLOCK
:
629 cfg
.cursor_type
== 1 ? IDC_CURUNDER
: IDC_CURVERT
);
630 CheckDlgButton(hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
631 CheckDlgButton(hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
632 CheckDlgButton(hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
633 CheckRadioButton(hwnd
, IDC_COEALWAYS
, IDC_COENORMAL
,
634 cfg
.close_on_exit
== COE_NORMAL ? IDC_COENORMAL
:
636 COE_NEVER ? IDC_COENEVER
: IDC_COEALWAYS
);
637 CheckDlgButton(hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
639 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
640 SetDlgItemText(hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
641 SetDlgItemText(hwnd
, IDC_R_TSEDIT
, cfg
.termspeed
);
642 SetDlgItemText(hwnd
, IDC_RLLUSEREDIT
, cfg
.localusername
);
643 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
644 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
645 CheckRadioButton(hwnd
, IDC_LSTATOFF
, IDC_LSTATRAW
,
646 cfg
.logtype
== 0 ? IDC_LSTATOFF
:
647 cfg
.logtype
== 1 ? IDC_LSTATASCII
: IDC_LSTATRAW
);
648 CheckRadioButton(hwnd
, IDC_LSTATXOVR
, IDC_LSTATXASK
,
649 cfg
.logxfovr
== LGXF_OVR ? IDC_LSTATXOVR
:
650 cfg
.logxfovr
== LGXF_ASK ? IDC_LSTATXASK
:
653 char *p
= cfg
.environmt
;
655 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
660 CheckRadioButton(hwnd
, IDC_EMBSD
, IDC_EMRFC
,
661 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
662 CheckRadioButton(hwnd
, IDC_TPASSIVE
, IDC_TACTIVE
,
663 cfg
.passive_telnet ? IDC_TPASSIVE
: IDC_TACTIVE
);
665 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
666 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
667 CheckDlgButton(hwnd
, IDC_NOPTY
, cfg
.nopty
);
668 CheckDlgButton(hwnd
, IDC_COMPRESS
, cfg
.compression
);
669 CheckDlgButton(hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
670 CheckDlgButton(hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
671 CheckRadioButton(hwnd
, IDC_CIPHER3DES
, IDC_CIPHERAES
,
672 cfg
.cipher
== CIPHER_BLOWFISH ? IDC_CIPHERBLOWF
:
673 cfg
.cipher
== CIPHER_DES ? IDC_CIPHERDES
:
674 cfg
.cipher
== CIPHER_AES ? IDC_CIPHERAES
:
676 CheckRadioButton(hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
677 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
678 CheckDlgButton(hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
679 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
680 SetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
682 CheckRadioButton(hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
683 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
684 CheckDlgButton(hwnd
, IDC_RAWCNP
, cfg
.rawcnp
);
686 static int tabs
[4] = { 25, 61, 96, 128 };
687 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
690 for (i
= 0; i
< 128; i
++) {
692 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
693 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ', cfg
.wordness
[i
]);
694 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
698 CheckDlgButton(hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
699 CheckDlgButton(hwnd
, IDC_PALETTE
, cfg
.try_palette
);
702 n
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
703 for (i
= n
; i
-- > 0;)
704 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
705 LB_DELETESTRING
, i
, 0);
706 for (i
= 0; i
< 22; i
++)
707 if (cfg
.bold_colour
|| permcolour
[i
])
708 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
709 (LPARAM
) colours
[i
]);
711 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
712 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
713 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
714 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
716 SetDlgItemText(hwnd
, IDC_CODEPAGE
, cfg
.line_codepage
);
717 CheckRadioButton(hwnd
, IDC_VTXWINDOWS
, IDC_VTUNICODE
,
718 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
719 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
720 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
721 cfg
.vtmode
== VT_UNICODE ? IDC_VTUNICODE
:
724 CheckDlgButton(hwnd
, IDC_X11_FORWARD
, cfg
.x11_forward
);
725 SetDlgItemText(hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
);
728 struct treeview_faff
{
733 static HTREEITEM
treeview_insert(struct treeview_faff
*faff
,
734 int level
, char *text
)
739 ins
.hParent
= (level
> 0 ? faff
->lastat
[level
- 1] : TVI_ROOT
);
740 ins
.hInsertAfter
= faff
->lastat
[level
];
741 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
742 #define INSITEM DUMMYUNIONNAME.item
746 ins
.INSITEM
.mask
= TVIF_TEXT
;
747 ins
.INSITEM
.pszText
= text
;
748 newitem
= TreeView_InsertItem(faff
->treeview
, &ins
);
750 TreeView_Expand(faff
->treeview
, faff
->lastat
[level
- 1],
752 faff
->lastat
[level
] = newitem
;
753 for (i
= level
+ 1; i
< 4; i
++)
754 faff
->lastat
[i
] = NULL
;
759 * Create the panelfuls of controls in the configuration box.
761 static void create_controls(HWND hwnd
, int dlgtype
, int panel
)
763 if (panel
== sessionpanelstart
) {
764 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
766 ctlposinit(&cp
, hwnd
, 80, 3, 13);
767 bartitle(&cp
, "Basic options for your PuTTY session",
770 beginbox(&cp
, "Specify your connection by host name",
773 "Host &Name", IDC_HOSTSTATIC
, IDC_HOST
, 75,
774 "&Port", IDC_PORTSTATIC
, IDC_PORT
, 25, NULL
);
775 if (backends
[3].backend
== NULL
) {
776 /* this is PuTTYtel, so only three protocols available */
777 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
779 "&Telnet", IDC_PROTTELNET
,
780 "Rlog&in", IDC_PROTRLOGIN
, NULL
);
782 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 4,
784 "&Telnet", IDC_PROTTELNET
,
785 "Rlog&in", IDC_PROTRLOGIN
,
794 beginbox(&cp
, "Load, save or delete a stored session",
796 sesssaver(&cp
, "Sav&ed Sessions",
797 IDC_SESSSTATIC
, IDC_SESSEDIT
, IDC_SESSLIST
,
798 "&Load", IDC_SESSLOAD
,
799 "&Save", IDC_SESSSAVE
, "&Delete", IDC_SESSDEL
, NULL
);
802 beginbox(&cp
, NULL
, IDC_BOX_SESSION3
);
803 radioline(&cp
, "Close &window on exit:", IDC_CLOSEEXIT
, 4,
804 "Always", IDC_COEALWAYS
,
805 "Never", IDC_COENEVER
,
806 "Only on clean exit", IDC_COENORMAL
, NULL
);
810 if (panel
== loggingpanelstart
) {
811 /* The Logging panel. Accelerators used: [acgo] tplfwe */
813 ctlposinit(&cp
, hwnd
, 80, 3, 13);
814 bartitle(&cp
, "Options controlling session logging",
816 beginbox(&cp
, NULL
, IDC_BOX_LOGGING1
);
818 "Session logging:", IDC_LSTATSTATIC
,
819 "Logging &turned off completely", IDC_LSTATOFF
,
820 "Log &printable output only", IDC_LSTATASCII
,
821 "&Log all session output", IDC_LSTATRAW
, NULL
);
822 editbutton(&cp
, "Log &file name:",
823 IDC_LGFSTATIC
, IDC_LGFEDIT
, "Bro&wse...",
826 "What to do if the log file already &exists:",
827 IDC_LSTATXIST
, "Always overwrite it", IDC_LSTATXOVR
,
828 "Always append to the end of it", IDC_LSTATXAPN
,
829 "Ask the user every time", IDC_LSTATXASK
, NULL
);
833 if (panel
== terminalpanelstart
) {
834 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
836 ctlposinit(&cp
, hwnd
, 80, 3, 13);
837 bartitle(&cp
, "Options controlling the terminal emulation",
839 beginbox(&cp
, "Set various terminal options", IDC_BOX_TERMINAL1
);
840 checkbox(&cp
, "Auto &wrap mode initially on", IDC_WRAPMODE
);
841 checkbox(&cp
, "&DEC Origin Mode initially on", IDC_DECOM
);
842 checkbox(&cp
, "Implicit CR in every &LF", IDC_LFHASCR
);
843 checkbox(&cp
, "Use background colour to &erase screen", IDC_BCE
);
844 checkbox(&cp
, "Enable bli&nking text", IDC_BLINKTEXT
);
846 "An&swerback to ^E:", IDC_ANSWERBACK
,
847 IDC_ANSWEREDIT
, 100, NULL
);
850 beginbox(&cp
, "Line discipline options", IDC_BOX_TERMINAL2
);
851 radioline(&cp
, "Local ec&ho:", IDC_ECHOSTATIC
, 3,
852 "Auto", IDC_ECHOBACKEND
,
853 "Force on", IDC_ECHOYES
, "Force off", IDC_ECHONO
, NULL
);
854 radioline(&cp
, "Local line edi&ting:", IDC_EDITSTATIC
, 3,
855 "Auto", IDC_EDITBACKEND
,
856 "Force on", IDC_EDITYES
, "Force off", IDC_EDITNO
, NULL
);
860 if (panel
== bellpanelstart
) {
861 /* The Bell panel. Accelerators used: [acgo] bdsm wt */
863 ctlposinit(&cp
, hwnd
, 80, 3, 13);
864 bartitle(&cp
, "Options controlling the terminal bell",
866 beginbox(&cp
, "Set the style of bell", IDC_BOX_BELL1
);
868 "Action to happen when a &bell occurs:", IDC_BELLSTATIC
,
869 "None (bell disabled)", IDC_BELL_DISABLED
,
870 "Play Windows Default Sound", IDC_BELL_DEFAULT
,
871 "Play a custom sound file", IDC_BELL_WAVEFILE
,
872 "Visual bell (flash window)", IDC_BELL_VISUAL
, NULL
);
873 editbutton(&cp
, "Custom sound file to play as a bell:",
874 IDC_BELL_WAVESTATIC
, IDC_BELL_WAVEEDIT
,
875 "Bro&wse...", IDC_BELL_WAVEBROWSE
);
877 beginbox(&cp
, "Control the bell overload behaviour",
879 checkbox(&cp
, "Bell is temporarily &disabled when over-used",
881 staticedit(&cp
, "Over-use means this &many bells...",
882 IDC_BELLOVLNSTATIC
, IDC_BELLOVLN
, 20);
883 staticedit(&cp
, "... in &this many seconds",
884 IDC_BELLOVLTSTATIC
, IDC_BELLOVLT
, 20);
886 "The bell is re-enabled after a few seconds of silence.",
888 staticedit(&cp
, "Seconds of &silence required", IDC_BELLOVLSSTATIC
,
893 if (panel
== keyboardpanelstart
) {
894 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
896 ctlposinit(&cp
, hwnd
, 80, 3, 13);
898 bartitle(&cp, "Options controlling the effects of keys",
901 beginbox(&cp
, "Change the sequences sent by:", IDC_BOX_KEYBOARD1
);
902 radioline(&cp
, "The &Backspace key", IDC_DELSTATIC
, 2,
903 "Control-H", IDC_DEL008
,
904 "Control-? (127)", IDC_DEL127
, NULL
);
905 radioline(&cp
, "The &Home and End keys", IDC_HOMESTATIC
, 2,
906 "Standard", IDC_HOMETILDE
, "rxvt", IDC_HOMERXVT
, NULL
);
907 radioline(&cp
, "The &Function keys and keypad", IDC_FUNCSTATIC
, 3,
908 "ESC[n~", IDC_FUNCTILDE
,
909 "Linux", IDC_FUNCLINUX
,
910 "Xterm R6", IDC_FUNCXTERM
,
911 "VT400", IDC_FUNCVT400
,
912 "VT100+", IDC_FUNCVT100P
, "SCO", IDC_FUNCSCO
, NULL
);
914 beginbox(&cp
, "Application keypad settings:", IDC_BOX_KEYBOARD2
);
916 "Application c&ursor keys totally disabled",
918 radioline(&cp
, "Initial state of cu&rsor keys:", IDC_CURSTATIC
, 2,
919 "Normal", IDC_CURNORMAL
,
920 "Application", IDC_CURAPPLIC
, NULL
);
922 "Application ke&ypad keys totally disabled",
924 radioline(&cp
, "Initial state of &numeric keypad:", IDC_KPSTATIC
,
925 3, "Normal", IDC_KPNORMAL
, "Application", IDC_KPAPPLIC
,
926 "NetHack", IDC_KPNH
, NULL
);
928 beginbox(&cp
, "Enable extra keyboard features:",
930 checkbox(&cp
, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY
);
931 checkbox(&cp
, "Control-Alt is &different from AltGr",
936 if (panel
== windowpanelstart
) {
937 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
939 ctlposinit(&cp
, hwnd
, 80, 3, 13);
940 bartitle(&cp
, "Options controlling PuTTY's window",
942 beginbox(&cp
, "Set the size of the window", IDC_BOX_WINDOW1
);
944 "&Rows", IDC_ROWSSTATIC
, IDC_ROWSEDIT
, 50,
945 "Colu&mns", IDC_COLSSTATIC
, IDC_COLSEDIT
, 50, NULL
);
946 checkbox(&cp
, "Lock window size against resi&zing", IDC_LOCKSIZE
);
948 beginbox(&cp
, "Control the scrollback in the window",
950 staticedit(&cp
, "Lines of &scrollback",
951 IDC_SAVESTATIC
, IDC_SAVEEDIT
, 50);
952 checkbox(&cp
, "&Display scrollbar", IDC_SCROLLBAR
);
953 checkbox(&cp
, "Reset scrollback on &keypress", IDC_SCROLLKEY
);
954 checkbox(&cp
, "Reset scrollback on dis&play activity",
957 beginbox(&cp
, NULL
, IDC_BOX_WINDOW3
);
958 checkbox(&cp
, "&Warn before closing window", IDC_CLOSEWARN
);
959 checkbox(&cp
, "Window closes on ALT-F&4", IDC_ALTF4
);
960 checkbox(&cp
, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE
);
961 checkbox(&cp
, "System menu appears on A< alone", IDC_ALTONLY
);
962 checkbox(&cp
, "Ensure window is always on &top", IDC_ALWAYSONTOP
);
966 if (panel
== appearancepanelstart
) {
967 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
969 ctlposinit(&cp
, hwnd
, 80, 3, 13);
970 bartitle(&cp
, "Options controlling PuTTY's appearance",
971 IDC_TITLE_APPEARANCE
);
972 beginbox(&cp
, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1
);
973 radioline(&cp
, "Cursor appearance:", IDC_CURSORSTATIC
, 3,
974 "B&lock", IDC_CURBLOCK
,
975 "&Underline", IDC_CURUNDER
,
976 "&Vertical line", IDC_CURVERT
, NULL
);
977 checkbox(&cp
, "Cursor &blinks", IDC_BLINKCUR
);
979 beginbox(&cp
, "Set the font used in the terminal window",
980 IDC_BOX_APPEARANCE2
);
981 staticbtn(&cp
, "", IDC_FONTSTATIC
, "C&hange...", IDC_CHOOSEFONT
);
983 beginbox(&cp
, "Adjust the use of the window title",
984 IDC_BOX_APPEARANCE3
);
986 "Window &title:", IDC_WINTITLE
, IDC_WINEDIT
, 100, NULL
);
987 checkbox(&cp
, "Avoid ever using &icon title", IDC_WINNAME
);
989 beginbox(&cp
, "Adjust the use of the mouse pointer",
990 IDC_BOX_APPEARANCE4
);
991 checkbox(&cp
, "Hide mouse &pointer when typing in window",
994 beginbox(&cp
, "Adjust the window border", IDC_BOX_APPEARANCE5
);
995 checkbox(&cp
, "&Sunken-edge border (slightly thicker)",
1000 if (panel
== translationpanelstart
) {
1001 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1003 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1004 bartitle(&cp
, "Options controlling character set translation",
1005 IDC_TITLE_TRANSLATION
);
1006 beginbox(&cp
, "Adjust how PuTTY displays line drawing characters",
1007 IDC_BOX_TRANSLATION1
);
1009 "Handling of line drawing characters:", IDC_VTSTATIC
,
1010 "Font has &XWindows encoding", IDC_VTXWINDOWS
,
1011 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI
,
1012 "Use font in O&EM mode only", IDC_VTOEMONLY
,
1013 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1014 IDC_VTPOORMAN
, "&Unicode mode", IDC_VTUNICODE
, NULL
);
1016 beginbox(&cp
, "Enable character set translation on received data",
1017 IDC_BOX_TRANSLATION2
);
1018 multiedit(&cp
, "Line codepage:", IDC_CODEPAGESTATIC
,
1019 IDC_CODEPAGE
, 100, NULL
);
1023 if (panel
== selectionpanelstart
) {
1024 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1026 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1027 bartitle(&cp
, "Options controlling copy and paste",
1028 IDC_TITLE_SELECTION
);
1029 beginbox(&cp
, "Translation of pasted characters",
1030 IDC_BOX_SELECTION1
);
1032 "&Don't translate line drawing chars into +, - and |",
1035 beginbox(&cp
, "Control which mouse button does which thing",
1036 IDC_BOX_SELECTION2
);
1037 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
1038 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
1039 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
1042 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
1043 IDC_BOX_SELECTION3
);
1044 charclass(&cp
, "C&haracter classes:", IDC_CCSTATIC
, IDC_CCLIST
,
1045 "&Set", IDC_CCSET
, IDC_CCEDIT
,
1046 "&to class", IDC_CCSTATIC2
);
1050 if (panel
== colourspanelstart
) {
1051 /* The Colours panel. Accelerators used: [acgo] blum */
1053 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1054 bartitle(&cp
, "Options controlling use of colours",
1056 beginbox(&cp
, "General options for colour usage",
1058 checkbox(&cp
, "&Bolded text is a different colour",
1060 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
1062 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
1064 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
1065 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
1066 "&Modify...", IDC_CHANGE
,
1067 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
1068 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
1069 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
1073 if (panel
== connectionpanelstart
) {
1074 /* The Connection panel. Accelerators used: [acgo] tuk */
1076 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1077 bartitle(&cp
, "Options controlling the connection",
1078 IDC_TITLE_CONNECTION
);
1080 beginbox(&cp
, "Data to send to the server",
1081 IDC_BOX_CONNECTION1
);
1082 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
,
1084 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
,
1088 beginbox(&cp
, "Adjust telnet session.", IDC_BOX_CONNECTION1
);
1089 checkbox(&cp
, "Keyboard sends telnet Backspace and Interrupt",
1093 beginbox(&cp
, "Sending of null packets to keep session active",
1094 IDC_BOX_CONNECTION2
);
1095 staticedit(&cp
, "Seconds between &keepalives (0 to turn off)",
1096 IDC_PINGSTATIC
, IDC_PINGEDIT
, 20);
1100 if (panel
== telnetpanelstart
) {
1101 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1103 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1105 bartitle(&cp
, "Options controlling Telnet connections",
1107 beginbox(&cp
, "Data to send to the server", IDC_BOX_TELNET1
);
1108 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
,
1110 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
1111 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
, "Va&lue",
1112 IDC_VALSTATIC
, IDC_VALEDIT
, IDC_ENVLIST
, "A&dd",
1113 IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
1115 beginbox(&cp
, "Telnet protocol adjustments", IDC_BOX_TELNET2
);
1116 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:",
1117 IDC_EMSTATIC
, 2, "&BSD (commonplace)", IDC_EMBSD
,
1118 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
1119 radioline(&cp
, "&Telnet negotiation mode:", IDC_ACTSTATIC
, 2,
1120 "Passive", IDC_TPASSIVE
, "Active",
1122 checkbox(&cp
, "&Keyboard sends telnet Backspace and Interrupt",
1128 if (panel
== rloginpanelstart
) {
1129 /* The Rlogin panel. Accelerators used: [acgo] sl */
1131 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1133 bartitle(&cp
, "Options controlling Rlogin connections",
1135 beginbox(&cp
, "Data to send to the server", IDC_BOX_RLOGIN1
);
1136 staticedit(&cp
, "Terminal-&speed string", IDC_R_TSSTATIC
,
1138 staticedit(&cp
, "&Local username:", IDC_RLLUSERSTATIC
,
1139 IDC_RLLUSEREDIT
, 50);
1144 if (panel
== sshpanelstart
) {
1145 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1147 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1149 bartitle(&cp
, "Options controlling SSH connections",
1151 beginbox(&cp
, "Data to send to the server", IDC_BOX_SSH1
);
1153 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
1156 beginbox(&cp
, "Authentication options", IDC_BOX_SSH2
);
1157 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
1159 checkbox(&cp
, "Allow agent &forwarding", IDC_AGENTFWD
);
1160 editbutton(&cp
, "Private &key file for authentication:",
1161 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...",
1164 beginbox(&cp
, "Protocol options", IDC_BOX_SSH3
);
1165 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
1166 checkbox(&cp
, "Enable compr&ession", IDC_COMPRESS
);
1167 radioline(&cp
, "Preferred SSH protocol version:",
1168 IDC_SSHPROTSTATIC
, 2,
1169 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
1170 radioline(&cp
, "Preferred encryption algorithm:",
1171 IDC_CIPHERSTATIC
, 4, "&3DES", IDC_CIPHER3DES
,
1172 "&Blowfish", IDC_CIPHERBLOWF
, "&DES", IDC_CIPHERDES
,
1173 "AE&S", IDC_CIPHERAES
, NULL
);
1174 checkbox(&cp
, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1180 if (panel
== tunnelspanelstart
) {
1181 /* The Tunnels panel. Accelerators used: [acgo] ex */
1183 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1185 bartitle(&cp
, "Options controlling SSH tunnelling",
1187 beginbox(&cp
, "X11 forwarding options", IDC_BOX_TUNNELS
);
1188 checkbox(&cp
, "&Enable X11 forwarding", IDC_X11_FORWARD
);
1189 multiedit(&cp
, "&X display location", IDC_X11_DISPSTATIC
,
1190 IDC_X11_DISPLAY
, 50, NULL
);
1197 * This function is the configuration box.
1199 static int GenericMainDlgProc(HWND hwnd
, UINT msg
,
1200 WPARAM wParam
, LPARAM lParam
, int dlgtype
)
1203 struct treeview_faff tvfaff
;
1206 char filename
[sizeof(cfg
.keyfile
)];
1209 char fontstatic
[256];
1211 struct servent
*service
;
1217 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1219 * Centre the window.
1221 { /* centre the window */
1224 hw
= GetDesktopWindow();
1225 if (GetWindowRect(hw
, &rs
) && GetWindowRect(hwnd
, &rd
))
1227 (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
) / 2,
1228 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
) / 2,
1229 rd
.right
- rd
.left
, rd
.bottom
- rd
.top
, TRUE
);
1233 * Create the tree view.
1241 r
.right
= r
.left
+ 75;
1243 r
.bottom
= r
.top
+ 10;
1244 MapDialogRect(hwnd
, &r
);
1245 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
1246 WS_CHILD
| WS_VISIBLE
,
1248 r
.right
- r
.left
, r
.bottom
- r
.top
,
1249 hwnd
, (HMENU
) IDCX_TVSTATIC
, hinst
,
1251 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1252 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1255 r
.right
= r
.left
+ 75;
1257 r
.bottom
= r
.top
+ 206;
1258 MapDialogRect(hwnd
, &r
);
1259 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
1260 WS_CHILD
| WS_VISIBLE
|
1261 WS_TABSTOP
| TVS_HASLINES
|
1262 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
1264 TVS_SHOWSELALWAYS
, r
.left
, r
.top
,
1265 r
.right
- r
.left
, r
.bottom
- r
.top
,
1266 hwnd
, (HMENU
) IDCX_TREEVIEW
, hinst
,
1268 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1269 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1270 tvfaff
.treeview
= treeview
;
1271 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
1275 * Set up the tree view contents.
1277 hsession
= treeview_insert(&tvfaff
, 0, "Session");
1278 treeview_insert(&tvfaff
, 1, "Logging");
1279 treeview_insert(&tvfaff
, 0, "Terminal");
1280 treeview_insert(&tvfaff
, 1, "Keyboard");
1281 treeview_insert(&tvfaff
, 1, "Bell");
1282 treeview_insert(&tvfaff
, 0, "Window");
1283 treeview_insert(&tvfaff
, 1, "Appearance");
1284 treeview_insert(&tvfaff
, 1, "Translation");
1285 treeview_insert(&tvfaff
, 1, "Selection");
1286 treeview_insert(&tvfaff
, 1, "Colours");
1287 treeview_insert(&tvfaff
, 0, "Connection");
1289 treeview_insert(&tvfaff
, 1, "Telnet");
1290 treeview_insert(&tvfaff
, 1, "Rlogin");
1291 if (backends
[3].backend
!= NULL
) {
1292 treeview_insert(&tvfaff
, 1, "SSH");
1293 treeview_insert(&tvfaff
, 2, "Tunnels");
1298 * Put the treeview selection on to the Session panel. This
1299 * should also cause creation of the relevant controls.
1301 TreeView_SelectItem(treeview
, hsession
);
1304 * Set focus into the first available control.
1308 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
1310 ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
1314 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1318 * Button release should trigger WM_OK if there was a
1319 * previous double click on the session list.
1323 SendMessage(hwnd
, WM_COMMAND
, IDOK
, 0);
1326 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1327 ((LPNMHDR
) lParam
)->code
== TVN_SELCHANGED
) {
1329 TreeView_GetSelection(((LPNMHDR
) lParam
)->hwndFrom
);
1334 item
.pszText
= buffer
;
1335 item
.cchTextMax
= sizeof(buffer
);
1336 item
.mask
= TVIF_TEXT
;
1337 TreeView_GetItem(((LPNMHDR
) lParam
)->hwndFrom
, &item
);
1338 for (j
= controlstartvalue
; j
< controlendvalue
; j
++) {
1339 HWND item
= GetDlgItem(hwnd
, j
);
1341 DestroyWindow(item
);
1343 if (!strcmp(buffer
, "Session"))
1344 create_controls(hwnd
, dlgtype
, sessionpanelstart
);
1345 if (!strcmp(buffer
, "Logging"))
1346 create_controls(hwnd
, dlgtype
, loggingpanelstart
);
1347 if (!strcmp(buffer
, "Keyboard"))
1348 create_controls(hwnd
, dlgtype
, keyboardpanelstart
);
1349 if (!strcmp(buffer
, "Terminal"))
1350 create_controls(hwnd
, dlgtype
, terminalpanelstart
);
1351 if (!strcmp(buffer
, "Bell"))
1352 create_controls(hwnd
, dlgtype
, bellpanelstart
);
1353 if (!strcmp(buffer
, "Window"))
1354 create_controls(hwnd
, dlgtype
, windowpanelstart
);
1355 if (!strcmp(buffer
, "Appearance"))
1356 create_controls(hwnd
, dlgtype
, appearancepanelstart
);
1357 if (!strcmp(buffer
, "Tunnels"))
1358 create_controls(hwnd
, dlgtype
, tunnelspanelstart
);
1359 if (!strcmp(buffer
, "Connection"))
1360 create_controls(hwnd
, dlgtype
, connectionpanelstart
);
1361 if (!strcmp(buffer
, "Telnet"))
1362 create_controls(hwnd
, dlgtype
, telnetpanelstart
);
1363 if (!strcmp(buffer
, "Rlogin"))
1364 create_controls(hwnd
, dlgtype
, rloginpanelstart
);
1365 if (!strcmp(buffer
, "SSH"))
1366 create_controls(hwnd
, dlgtype
, sshpanelstart
);
1367 if (!strcmp(buffer
, "Selection"))
1368 create_controls(hwnd
, dlgtype
, selectionpanelstart
);
1369 if (!strcmp(buffer
, "Colours"))
1370 create_controls(hwnd
, dlgtype
, colourspanelstart
);
1371 if (!strcmp(buffer
, "Translation"))
1372 create_controls(hwnd
, dlgtype
, translationpanelstart
);
1374 init_dlg_ctrls(hwnd
);
1376 SetFocus(((LPNMHDR
) lParam
)->hwndFrom
); /* ensure focus stays */
1382 * Only process WM_COMMAND once the dialog is fully formed.
1384 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1)
1385 switch (LOWORD(wParam
)) {
1395 case IDC_PROTTELNET
:
1396 case IDC_PROTRLOGIN
:
1399 if (HIWORD(wParam
) == BN_CLICKED
||
1400 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1401 int i
= IsDlgButtonChecked(hwnd
, IDC_PROTSSH
);
1402 int j
= IsDlgButtonChecked(hwnd
, IDC_PROTTELNET
);
1403 int k
= IsDlgButtonChecked(hwnd
, IDC_PROTRLOGIN
);
1405 i ? PROT_SSH
: j ? PROT_TELNET
: k ? PROT_RLOGIN
:
1407 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
!= 22)
1408 || (cfg
.protocol
== PROT_TELNET
&& cfg
.port
!= 23)
1409 || (cfg
.protocol
== PROT_RLOGIN
1410 && cfg
.port
!= 513)) {
1411 cfg
.port
= i ?
22 : j ?
23 : 513;
1412 SetDlgItemInt(hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1417 if (HIWORD(wParam
) == EN_CHANGE
)
1418 GetDlgItemText(hwnd
, IDC_HOST
, cfg
.host
,
1419 sizeof(cfg
.host
) - 1);
1422 if (HIWORD(wParam
) == EN_CHANGE
) {
1423 GetDlgItemText(hwnd
, IDC_PORT
, portname
, 31);
1424 if (isdigit(portname
[0]))
1425 MyGetDlgItemInt(hwnd
, IDC_PORT
, &cfg
.port
);
1427 service
= getservbyname(portname
, NULL
);
1429 cfg
.port
= ntohs(service
->s_port
);
1436 if (HIWORD(wParam
) == EN_CHANGE
) {
1437 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1439 GetDlgItemText(hwnd
, IDC_SESSEDIT
,
1440 savedsession
, sizeof(savedsession
) - 1);
1441 savedsession
[sizeof(savedsession
) - 1] = '\0';
1445 if (HIWORD(wParam
) == BN_CLICKED
||
1446 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1451 GetDlgItemText(hwnd
, IDC_SESSEDIT
, str
,
1454 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1455 LB_GETCURSEL
, 0, 0);
1460 strcpy(str
, sessions
[n
]);
1462 save_settings(str
, !!strcmp(str
, "Default Settings"),
1464 get_sesslist(FALSE
);
1466 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1468 for (i
= 0; i
< nsessions
; i
++)
1469 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1471 (LPARAM
) (sessions
[i
]));
1472 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1478 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1479 HIWORD(wParam
) != BN_CLICKED
&&
1480 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
1481 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1482 HIWORD(wParam
) != LBN_DBLCLK
) break;
1484 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1485 LB_GETCURSEL
, 0, 0);
1491 isdef
= !strcmp(sessions
[n
], "Default Settings");
1492 load_settings(sessions
[n
], !isdef
, &cfg
);
1493 init_dlg_ctrls(hwnd
);
1495 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1497 SetDlgItemText(hwnd
, IDC_SESSEDIT
, "");
1499 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1501 * A double-click on a saved session should
1502 * actually start the session, not just load it.
1503 * Unless it's Default Settings or some other
1504 * host-less set of saved settings.
1513 if (HIWORD(wParam
) == BN_CLICKED
||
1514 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1515 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1516 LB_GETCURSEL
, 0, 0);
1517 if (n
== LB_ERR
|| n
== 0) {
1521 del_settings(sessions
[n
]);
1522 get_sesslist(FALSE
);
1524 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1526 for (i
= 0; i
< nsessions
; i
++)
1527 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1529 (LPARAM
) (sessions
[i
]));
1530 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1534 if (HIWORD(wParam
) == EN_CHANGE
)
1535 MyGetDlgItemInt(hwnd
, IDC_PINGEDIT
,
1536 &cfg
.ping_interval
);
1540 if (HIWORD(wParam
) == BN_CLICKED
||
1541 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1542 cfg
.bksp_is_delete
=
1543 IsDlgButtonChecked(hwnd
, IDC_DEL127
);
1547 if (HIWORD(wParam
) == BN_CLICKED
||
1548 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1550 IsDlgButtonChecked(hwnd
, IDC_HOMERXVT
);
1556 case IDC_FUNCVT100P
:
1558 if (HIWORD(wParam
) == BN_CLICKED
||
1559 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1560 switch (LOWORD(wParam
)) {
1573 case IDC_FUNCVT100P
:
1583 if (HIWORD(wParam
) == BN_CLICKED
||
1584 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1586 IsDlgButtonChecked(hwnd
, IDC_KPAPPLIC
);
1587 cfg
.nethack_keypad
= FALSE
;
1591 if (HIWORD(wParam
) == BN_CLICKED
||
1592 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1593 cfg
.app_keypad
= FALSE
;
1594 cfg
.nethack_keypad
= TRUE
;
1599 if (HIWORD(wParam
) == BN_CLICKED
||
1600 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1602 IsDlgButtonChecked(hwnd
, IDC_CURAPPLIC
);
1605 if (HIWORD(wParam
) == BN_CLICKED
||
1606 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1608 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICC
);
1611 if (HIWORD(wParam
) == BN_CLICKED
||
1612 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1614 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICK
);
1617 if (HIWORD(wParam
) == BN_CLICKED
||
1618 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1619 cfg
.alt_f4
= IsDlgButtonChecked(hwnd
, IDC_ALTF4
);
1622 if (HIWORD(wParam
) == BN_CLICKED
||
1623 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1625 IsDlgButtonChecked(hwnd
, IDC_ALTSPACE
);
1628 if (HIWORD(wParam
) == BN_CLICKED
||
1629 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1631 IsDlgButtonChecked(hwnd
, IDC_ALTONLY
);
1633 case IDC_ECHOBACKEND
:
1636 if (HIWORD(wParam
) == BN_CLICKED
||
1637 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1638 if (LOWORD(wParam
) == IDC_ECHOBACKEND
)
1639 cfg
.localecho
= LD_BACKEND
;
1640 if (LOWORD(wParam
) == IDC_ECHOYES
)
1641 cfg
.localecho
= LD_YES
;
1642 if (LOWORD(wParam
) == IDC_ECHONO
)
1643 cfg
.localecho
= LD_NO
;
1646 case IDC_EDITBACKEND
:
1649 if (HIWORD(wParam
) == BN_CLICKED
||
1650 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1651 if (LOWORD(wParam
) == IDC_EDITBACKEND
)
1652 cfg
.localedit
= LD_BACKEND
;
1653 if (LOWORD(wParam
) == IDC_EDITYES
)
1654 cfg
.localedit
= LD_YES
;
1655 if (LOWORD(wParam
) == IDC_EDITNO
)
1656 cfg
.localedit
= LD_NO
;
1659 case IDC_ANSWEREDIT
:
1660 if (HIWORD(wParam
) == EN_CHANGE
)
1661 GetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
,
1662 sizeof(cfg
.answerback
) - 1);
1664 case IDC_ALWAYSONTOP
:
1665 if (HIWORD(wParam
) == BN_CLICKED
||
1666 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1668 IsDlgButtonChecked(hwnd
, IDC_ALWAYSONTOP
);
1671 if (HIWORD(wParam
) == BN_CLICKED
||
1672 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1674 IsDlgButtonChecked(hwnd
, IDC_SCROLLKEY
);
1676 case IDC_SCROLLDISP
:
1677 if (HIWORD(wParam
) == BN_CLICKED
||
1678 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1679 cfg
.scroll_on_disp
=
1680 IsDlgButtonChecked(hwnd
, IDC_SCROLLDISP
);
1682 case IDC_COMPOSEKEY
:
1683 if (HIWORD(wParam
) == BN_CLICKED
||
1684 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1686 IsDlgButtonChecked(hwnd
, IDC_COMPOSEKEY
);
1688 case IDC_CTRLALTKEYS
:
1689 if (HIWORD(wParam
) == BN_CLICKED
||
1690 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1692 IsDlgButtonChecked(hwnd
, IDC_CTRLALTKEYS
);
1695 if (HIWORD(wParam
) == BN_CLICKED
||
1696 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1697 cfg
.telnet_keyboard
=
1698 IsDlgButtonChecked(hwnd
, IDC_TELNETKEY
);
1701 if (HIWORD(wParam
) == BN_CLICKED
||
1702 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1704 IsDlgButtonChecked(hwnd
, IDC_WRAPMODE
);
1707 if (HIWORD(wParam
) == BN_CLICKED
||
1708 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1709 cfg
.dec_om
= IsDlgButtonChecked(hwnd
, IDC_DECOM
);
1712 if (HIWORD(wParam
) == BN_CLICKED
||
1713 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1715 IsDlgButtonChecked(hwnd
, IDC_LFHASCR
);
1718 if (HIWORD(wParam
) == EN_CHANGE
)
1719 MyGetDlgItemInt(hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1722 if (HIWORD(wParam
) == EN_CHANGE
)
1723 MyGetDlgItemInt(hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1726 if (HIWORD(wParam
) == EN_CHANGE
)
1727 MyGetDlgItemInt(hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1729 case IDC_CHOOSEFONT
:
1732 lf
.lfHeight
= -MulDiv(cfg
.fontheight
,
1733 GetDeviceCaps(hdc
, LOGPIXELSY
),
1737 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1738 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1739 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1740 lf
.lfCharSet
= cfg
.fontcharset
;
1741 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1742 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1743 lf
.lfQuality
= DEFAULT_QUALITY
;
1744 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1745 strncpy(lf
.lfFaceName
, cfg
.font
,
1746 sizeof(lf
.lfFaceName
) - 1);
1747 lf
.lfFaceName
[sizeof(lf
.lfFaceName
) - 1] = '\0';
1749 cf
.lStructSize
= sizeof(cf
);
1750 cf
.hwndOwner
= hwnd
;
1752 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1753 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1755 if (ChooseFont(&cf
)) {
1756 strncpy(cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
) - 1);
1757 cfg
.font
[sizeof(cfg
.font
) - 1] = '\0';
1758 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1759 cfg
.fontcharset
= lf
.lfCharSet
;
1760 cfg
.fontheight
= cf
.iPointSize
/ 10;
1761 fmtfont(fontstatic
);
1762 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
1765 case IDC_BELL_DISABLED
:
1766 case IDC_BELL_DEFAULT
:
1767 case IDC_BELL_WAVEFILE
:
1768 case IDC_BELL_VISUAL
:
1769 if (HIWORD(wParam
) == BN_CLICKED
||
1770 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1771 if (LOWORD(wParam
) == IDC_BELL_DISABLED
)
1772 cfg
.beep
= BELL_DISABLED
;
1773 if (LOWORD(wParam
) == IDC_BELL_DEFAULT
)
1774 cfg
.beep
= BELL_DEFAULT
;
1775 if (LOWORD(wParam
) == IDC_BELL_WAVEFILE
)
1776 cfg
.beep
= BELL_WAVEFILE
;
1777 if (LOWORD(wParam
) == IDC_BELL_VISUAL
)
1778 cfg
.beep
= BELL_VISUAL
;
1781 case IDC_BELL_WAVEBROWSE
:
1782 memset(&of
, 0, sizeof(of
));
1783 #ifdef OPENFILENAME_SIZE_VERSION_400
1784 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1786 of
.lStructSize
= sizeof(of
);
1788 of
.hwndOwner
= hwnd
;
1789 of
.lpstrFilter
= "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1790 of
.lpstrCustomFilter
= NULL
;
1791 of
.nFilterIndex
= 1;
1792 of
.lpstrFile
= filename
;
1793 strcpy(filename
, cfg
.bell_wavefile
);
1794 of
.nMaxFile
= sizeof(filename
);
1795 of
.lpstrFileTitle
= NULL
;
1796 of
.lpstrInitialDir
= NULL
;
1797 of
.lpstrTitle
= "Select Bell Sound File";
1799 if (GetOpenFileName(&of
)) {
1800 strcpy(cfg
.bell_wavefile
, filename
);
1801 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
1805 case IDC_BELL_WAVEEDIT
:
1806 if (HIWORD(wParam
) == EN_CHANGE
)
1807 GetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
1809 sizeof(cfg
.bell_wavefile
) - 1);
1812 if (HIWORD(wParam
) == BN_CLICKED
||
1813 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1815 IsDlgButtonChecked(hwnd
, IDC_BELLOVL
);
1818 if (HIWORD(wParam
) == EN_CHANGE
)
1819 MyGetDlgItemInt(hwnd
, IDC_BELLOVLN
, &cfg
.bellovl_n
);
1822 if (HIWORD(wParam
) == EN_CHANGE
)
1823 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLT
, &cfg
.bellovl_t
,
1827 if (HIWORD(wParam
) == EN_CHANGE
)
1828 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLS
, &cfg
.bellovl_s
,
1832 if (HIWORD(wParam
) == BN_CLICKED
||
1833 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1835 IsDlgButtonChecked(hwnd
, IDC_BLINKTEXT
);
1838 if (HIWORD(wParam
) == BN_CLICKED
||
1839 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1840 cfg
.bce
= IsDlgButtonChecked(hwnd
, IDC_BCE
);
1843 if (HIWORD(wParam
) == BN_CLICKED
||
1844 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1845 cfg
.win_name_always
=
1846 IsDlgButtonChecked(hwnd
, IDC_WINNAME
);
1849 if (HIWORD(wParam
) == BN_CLICKED
||
1850 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1852 IsDlgButtonChecked(hwnd
, IDC_HIDEMOUSE
);
1854 case IDC_SUNKENEDGE
:
1855 if (HIWORD(wParam
) == BN_CLICKED
||
1856 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1858 IsDlgButtonChecked(hwnd
, IDC_SUNKENEDGE
);
1861 if (HIWORD(wParam
) == BN_CLICKED
||
1862 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1863 cfg
.cursor_type
= 0;
1866 if (HIWORD(wParam
) == BN_CLICKED
||
1867 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1868 cfg
.cursor_type
= 1;
1871 if (HIWORD(wParam
) == BN_CLICKED
||
1872 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1873 cfg
.cursor_type
= 2;
1876 if (HIWORD(wParam
) == BN_CLICKED
||
1877 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1879 IsDlgButtonChecked(hwnd
, IDC_BLINKCUR
);
1882 if (HIWORD(wParam
) == BN_CLICKED
||
1883 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1885 IsDlgButtonChecked(hwnd
, IDC_SCROLLBAR
);
1888 if (HIWORD(wParam
) == BN_CLICKED
||
1889 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1891 IsDlgButtonChecked(hwnd
, IDC_LOCKSIZE
);
1894 if (HIWORD(wParam
) == EN_CHANGE
)
1895 GetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
1896 sizeof(cfg
.wintitle
) - 1);
1901 if (HIWORD(wParam
) == BN_CLICKED
||
1902 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1904 IsDlgButtonChecked(hwnd
,
1905 IDC_COEALWAYS
) ? COE_ALWAYS
:
1906 IsDlgButtonChecked(hwnd
,
1907 IDC_COENEVER
) ? COE_NEVER
:
1912 if (HIWORD(wParam
) == BN_CLICKED
||
1913 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1915 IsDlgButtonChecked(hwnd
, IDC_CLOSEWARN
);
1918 if (HIWORD(wParam
) == EN_CHANGE
)
1919 GetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
,
1920 sizeof(cfg
.termtype
) - 1);
1923 if (HIWORD(wParam
) == EN_CHANGE
)
1924 GetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
,
1925 sizeof(cfg
.logfilename
) - 1);
1928 memset(&of
, 0, sizeof(of
));
1929 #ifdef OPENFILENAME_SIZE_VERSION_400
1930 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1932 of
.lStructSize
= sizeof(of
);
1934 of
.hwndOwner
= hwnd
;
1935 of
.lpstrFilter
= "All Files\0*\0\0\0";
1936 of
.lpstrCustomFilter
= NULL
;
1937 of
.nFilterIndex
= 1;
1938 of
.lpstrFile
= filename
;
1939 strcpy(filename
, cfg
.logfilename
);
1940 of
.nMaxFile
= sizeof(filename
);
1941 of
.lpstrFileTitle
= NULL
;
1942 of
.lpstrInitialDir
= NULL
;
1943 of
.lpstrTitle
= "Select session log file";
1945 if (GetSaveFileName(&of
)) {
1946 strcpy(cfg
.logfilename
, filename
);
1947 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
1951 case IDC_LSTATASCII
:
1953 if (HIWORD(wParam
) == BN_CLICKED
||
1954 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1955 if (IsDlgButtonChecked(hwnd
, IDC_LSTATOFF
))
1957 if (IsDlgButtonChecked(hwnd
, IDC_LSTATASCII
))
1959 if (IsDlgButtonChecked(hwnd
, IDC_LSTATRAW
))
1966 if (HIWORD(wParam
) == BN_CLICKED
||
1967 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1968 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXASK
))
1969 cfg
.logxfovr
= LGXF_ASK
;
1970 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXAPN
))
1971 cfg
.logxfovr
= LGXF_APN
;
1972 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXOVR
))
1973 cfg
.logxfovr
= LGXF_OVR
;
1978 if (HIWORD(wParam
) == EN_CHANGE
)
1979 GetDlgItemText(hwnd
, LOWORD(wParam
), cfg
.termspeed
,
1980 sizeof(cfg
.termspeed
) - 1);
1983 if (HIWORD(wParam
) == EN_CHANGE
)
1984 GetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
,
1985 sizeof(cfg
.username
) - 1);
1987 case IDC_RLLUSEREDIT
:
1988 if (HIWORD(wParam
) == EN_CHANGE
)
1989 GetDlgItemText(hwnd
, IDC_RLLUSEREDIT
,
1991 sizeof(cfg
.localusername
) - 1);
1995 cfg
.rfc_environ
= IsDlgButtonChecked(hwnd
, IDC_EMRFC
);
1999 cfg
.passive_telnet
=
2000 IsDlgButtonChecked(hwnd
, IDC_TPASSIVE
);
2003 if (HIWORD(wParam
) == BN_CLICKED
||
2004 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2005 char str
[sizeof(cfg
.environmt
)];
2007 GetDlgItemText(hwnd
, IDC_VAREDIT
, str
,
2013 p
= str
+ strlen(str
);
2015 GetDlgItemText(hwnd
, IDC_VALEDIT
, p
,
2016 sizeof(str
) - 1 - (p
- str
));
2027 if ((p
- cfg
.environmt
) + strlen(str
) + 2 <
2028 sizeof(cfg
.environmt
)) {
2030 p
[strlen(str
) + 1] = '\0';
2031 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
2033 SetDlgItemText(hwnd
, IDC_VAREDIT
, "");
2034 SetDlgItemText(hwnd
, IDC_VALEDIT
, "");
2036 MessageBox(hwnd
, "Environment too big",
2037 "PuTTY Error", MB_OK
| MB_ICONERROR
);
2042 if (HIWORD(wParam
) != BN_CLICKED
&&
2043 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
2045 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0,
2052 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
2079 if (HIWORD(wParam
) == BN_CLICKED
||
2080 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2081 cfg
.nopty
= IsDlgButtonChecked(hwnd
, IDC_NOPTY
);
2084 if (HIWORD(wParam
) == BN_CLICKED
||
2085 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2087 IsDlgButtonChecked(hwnd
, IDC_COMPRESS
);
2090 if (HIWORD(wParam
) == BN_CLICKED
||
2091 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2093 IsDlgButtonChecked(hwnd
, IDC_BUGGYMAC
);
2096 if (HIWORD(wParam
) == BN_CLICKED
||
2097 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2099 IsDlgButtonChecked(hwnd
, IDC_AGENTFWD
);
2101 case IDC_CIPHER3DES
:
2102 case IDC_CIPHERBLOWF
:
2105 if (HIWORD(wParam
) == BN_CLICKED
||
2106 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2107 if (IsDlgButtonChecked(hwnd
, IDC_CIPHER3DES
))
2108 cfg
.cipher
= CIPHER_3DES
;
2109 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERBLOWF
))
2110 cfg
.cipher
= CIPHER_BLOWFISH
;
2111 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERDES
))
2112 cfg
.cipher
= CIPHER_DES
;
2113 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERAES
))
2114 cfg
.cipher
= CIPHER_AES
;
2119 if (HIWORD(wParam
) == BN_CLICKED
||
2120 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2121 if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT1
))
2123 else if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT2
))
2128 if (HIWORD(wParam
) == BN_CLICKED
||
2129 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2131 IsDlgButtonChecked(hwnd
, IDC_AUTHTIS
);
2134 if (HIWORD(wParam
) == EN_CHANGE
)
2135 GetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
2136 sizeof(cfg
.keyfile
) - 1);
2139 if (HIWORD(wParam
) == EN_CHANGE
)
2140 GetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
2141 sizeof(cfg
.remote_cmd
) - 1);
2144 memset(&of
, 0, sizeof(of
));
2145 #ifdef OPENFILENAME_SIZE_VERSION_400
2146 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
2148 of
.lStructSize
= sizeof(of
);
2150 of
.hwndOwner
= hwnd
;
2151 of
.lpstrFilter
= "All Files\0*\0\0\0";
2152 of
.lpstrCustomFilter
= NULL
;
2153 of
.nFilterIndex
= 1;
2154 of
.lpstrFile
= filename
;
2155 strcpy(filename
, cfg
.keyfile
);
2156 of
.nMaxFile
= sizeof(filename
);
2157 of
.lpstrFileTitle
= NULL
;
2158 of
.lpstrInitialDir
= NULL
;
2159 of
.lpstrTitle
= "Select Public Key File";
2161 if (GetOpenFileName(&of
)) {
2162 strcpy(cfg
.keyfile
, filename
);
2163 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
2167 cfg
.rawcnp
= IsDlgButtonChecked(hwnd
, IDC_RAWCNP
);
2170 cfg
.mouse_is_xterm
= IsDlgButtonChecked(hwnd
, IDC_MBXTERM
);
2176 int n
= GetDlgItemInt(hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
2181 for (i
= 0; i
< 128; i
++)
2182 if (SendDlgItemMessage
2183 (hwnd
, IDC_CCLIST
, LB_GETSEL
, i
, 0)) {
2185 cfg
.wordness
[i
] = n
;
2186 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2187 LB_DELETESTRING
, i
, 0);
2188 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
2189 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ',
2191 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2198 case IDC_BOLDCOLOUR
:
2199 if (HIWORD(wParam
) == BN_CLICKED
||
2200 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2203 IsDlgButtonChecked(hwnd
, IDC_BOLDCOLOUR
);
2205 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2207 if (n
!= 12 + 10 * cfg
.bold_colour
) {
2208 for (i
= n
; i
-- > 0;)
2209 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2210 LB_DELETESTRING
, i
, 0);
2211 for (i
= 0; i
< 22; i
++)
2212 if (cfg
.bold_colour
|| permcolour
[i
])
2213 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2215 (LPARAM
) colours
[i
]);
2220 if (HIWORD(wParam
) == BN_CLICKED
||
2221 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2223 IsDlgButtonChecked(hwnd
, IDC_PALETTE
);
2225 case IDC_COLOURLIST
:
2226 if (HIWORD(wParam
) == LBN_DBLCLK
||
2227 HIWORD(wParam
) == LBN_SELCHANGE
) {
2228 int i
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2231 if (!cfg
.bold_colour
)
2232 i
= (i
< 3 ? i
* 2 : i
== 3 ?
5 : i
* 2 - 2);
2233 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2235 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2237 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2242 if (HIWORD(wParam
) == BN_CLICKED
||
2243 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2244 static CHOOSECOLOR cc
;
2245 static DWORD custom
[16] = { 0 }; /* zero initialisers */
2246 int i
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2249 if (!cfg
.bold_colour
)
2250 i
= (i
< 3 ? i
* 2 : i
== 3 ?
5 : i
* 2 - 2);
2251 cc
.lStructSize
= sizeof(cc
);
2252 cc
.hwndOwner
= hwnd
;
2253 cc
.hInstance
= (HWND
) hinst
;
2254 cc
.lpCustColors
= custom
;
2256 RGB(cfg
.colours
[i
][0], cfg
.colours
[i
][1],
2258 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
2259 if (ChooseColor(&cc
)) {
2261 (unsigned char) (cc
.rgbResult
& 0xFF);
2263 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
2265 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
2266 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2268 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2270 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2276 if (HIWORD(wParam
) == EN_CHANGE
)
2277 GetDlgItemText(hwnd
, IDC_CODEPAGE
, cfg
.line_codepage
,
2278 sizeof(cfg
.line_codepage
) - 1);
2279 if (HIWORD(wParam
) == EN_KILLFOCUS
) {
2280 int cp
= decode_codepage(cfg
.line_codepage
);
2285 "Unable to identify character set '%s', "
2286 "translation disabled.",
2290 "Character set '%s' is a DBCS, "
2291 "translation is not available.",
2293 MessageBox(hwnd
, buf
, "PuTTY Error",
2294 MB_ICONERROR
| MB_OK
);
2296 strcpy(cfg
.line_codepage
, cp_name(cp
));
2297 SetDlgItemText(hwnd
, IDC_CODEPAGE
, cfg
.line_codepage
);
2300 case IDC_VTXWINDOWS
:
2306 (IsDlgButtonChecked(hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
2307 : IsDlgButtonChecked(hwnd
,
2308 IDC_VTOEMANSI
) ? VT_OEMANSI
:
2309 IsDlgButtonChecked(hwnd
,
2310 IDC_VTOEMONLY
) ? VT_OEMONLY
:
2311 IsDlgButtonChecked(hwnd
,
2312 IDC_VTUNICODE
) ? VT_UNICODE
:
2315 case IDC_X11_FORWARD
:
2316 if (HIWORD(wParam
) == BN_CLICKED
||
2317 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2319 IsDlgButtonChecked(hwnd
, IDC_X11_FORWARD
);
2321 case IDC_X11_DISPLAY
:
2322 if (HIWORD(wParam
) == EN_CHANGE
)
2323 GetDlgItemText(hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
,
2324 sizeof(cfg
.x11_display
) - 1);
2332 /* Grrr Explorer will maximize Dialogs! */
2334 if (wParam
== SIZE_MAXIMIZED
)
2341 static int CALLBACK
MainDlgProc(HWND hwnd
, UINT msg
,
2342 WPARAM wParam
, LPARAM lParam
)
2344 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
2346 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
2347 EnableWindow(hwnd
, 0);
2348 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2349 GetParent(hwnd
), AboutProc
);
2350 EnableWindow(hwnd
, 1);
2351 SetActiveWindow(hwnd
);
2353 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 0);
2356 static int CALLBACK
ReconfDlgProc(HWND hwnd
, UINT msg
,
2357 WPARAM wParam
, LPARAM lParam
)
2359 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 1);
2362 void defuse_showwindow(void)
2365 * Work around the fact that the app's first call to ShowWindow
2366 * will ignore the default in favour of the shell-provided
2371 hwnd
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2373 ShowWindow(hwnd
, SW_HIDE
);
2374 DestroyWindow(hwnd
);
2383 savedsession
[0] = '\0';
2385 DialogBox(hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
2386 get_sesslist(FALSE
);
2391 int do_reconfig(HWND hwnd
)
2396 backup_cfg
= cfg
; /* structure copy */
2398 DialogBox(hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
2400 cfg
= backup_cfg
; /* structure copy */
2405 void logevent(char *string
)
2410 if (nevents
>= negsize
) {
2412 events
= srealloc(events
, negsize
* sizeof(*events
));
2416 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%d %H:%M:%S\t",
2419 events
[nevents
] = smalloc(strlen(timebuf
) + strlen(string
) + 1);
2420 strcpy(events
[nevents
], timebuf
);
2421 strcat(events
[nevents
], string
);
2424 SendDlgItemMessage(logbox
, IDN_LIST
, LB_ADDSTRING
,
2425 0, (LPARAM
) events
[nevents
]);
2426 count
= SendDlgItemMessage(logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
2427 SendDlgItemMessage(logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
- 1, 0);
2432 void showeventlog(HWND hwnd
)
2435 logbox
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
2437 ShowWindow(logbox
, SW_SHOWNORMAL
);
2439 SetActiveWindow(logbox
);
2442 void showabout(HWND hwnd
)
2444 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hwnd
, AboutProc
);
2447 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
2448 char *keystr
, char *fingerprint
)
2452 static const char absentmsg
[] =
2453 "The server's host key is not cached in the registry. You\n"
2454 "have no guarantee that the server is the computer you\n"
2456 "The server's key fingerprint is:\n"
2458 "If you trust this host, hit Yes to add the key to\n"
2459 "PuTTY's cache and carry on connecting.\n"
2460 "If you do not trust this host, hit No to abandon the\n"
2463 static const char wrongmsg
[] =
2464 "WARNING - POTENTIAL SECURITY BREACH!\n"
2466 "The server's host key does not match the one PuTTY has\n"
2467 "cached in the registry. This means that either the\n"
2468 "server administrator has changed the host key, or you\n"
2469 "have actually connected to another computer pretending\n"
2470 "to be the server.\n"
2471 "The new key fingerprint is:\n"
2473 "If you were expecting this change and trust the new key,\n"
2474 "hit Yes to update PuTTY's cache and continue connecting.\n"
2475 "If you want to carry on connecting but without updating\n"
2476 "the cache, hit No.\n"
2477 "If you want to abandon the connection completely, hit\n"
2478 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2480 static const char mbtitle
[] = "PuTTY Security Alert";
2484 /* sensible fingerprint max size */
2485 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
2486 sizeof(absentmsg
) : sizeof(wrongmsg
))];
2489 * Verify the key against the registry.
2491 ret
= verify_host_key(host
, port
, keytype
, keystr
);
2493 if (ret
== 0) /* success - key matched OK */
2495 if (ret
== 2) { /* key was different */
2497 sprintf(message
, wrongmsg
, fingerprint
);
2498 mbret
= MessageBox(NULL
, message
, mbtitle
,
2499 MB_ICONWARNING
| MB_YESNOCANCEL
);
2501 store_host_key(host
, port
, keytype
, keystr
);
2502 if (mbret
== IDCANCEL
)
2505 if (ret
== 1) { /* key was absent */
2507 sprintf(message
, absentmsg
, fingerprint
);
2508 mbret
= MessageBox(NULL
, message
, mbtitle
,
2509 MB_ICONWARNING
| MB_YESNO
);
2512 store_host_key(host
, port
, keytype
, keystr
);
2517 * Ask whether to wipe a session log file before writing to it.
2518 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2520 int askappend(char *filename
)
2522 static const char mbtitle
[] = "PuTTY Log to File";
2523 static const char msgtemplate
[] =
2524 "The session log file \"%.*s\" already exists.\n"
2525 "You can overwrite it with a new session log,\n"
2526 "append your session log to the end of it,\n"
2527 "or disable session logging for this session.\n"
2528 "Hit Yes to wipe the file, No to append to it,\n"
2529 "or Cancel to disable logging.";
2530 char message
[sizeof(msgtemplate
) + FILENAME_MAX
];
2532 if (cfg
.logxfovr
!= LGXF_ASK
) {
2533 return ((cfg
.logxfovr
== LGXF_OVR
) ?
2 : 1);
2535 sprintf(message
, msgtemplate
, FILENAME_MAX
, filename
);
2537 mbret
= MessageBox(NULL
, message
, mbtitle
,
2538 MB_ICONQUESTION
| MB_YESNOCANCEL
);
2541 else if (mbret
== IDNO
)