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_clip(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
,
361 appearancepanelstart
,
362 IDC_TITLE_APPEARANCE
,
382 connectionpanelstart
,
383 IDC_TITLE_CONNECTION
,
481 translationpanelstart
,
482 IDC_TITLE_TRANSLATION
,
483 IDC_BOX_TRANSLATION1
,
484 IDC_BOX_TRANSLATION2
,
485 IDC_BOX_TRANSLATION3
,
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 CheckRadioButton(hwnd
, IDC_ECHOBACKEND
, IDC_ECHONO
,
589 cfg
.localecho
== LD_BACKEND ? IDC_ECHOBACKEND
:
590 cfg
.localecho
== LD_YES ? IDC_ECHOYES
: IDC_ECHONO
);
591 CheckRadioButton(hwnd
, IDC_EDITBACKEND
, IDC_EDITNO
,
592 cfg
.localedit
== LD_BACKEND ? IDC_EDITBACKEND
:
593 cfg
.localedit
== LD_YES ? IDC_EDITYES
: IDC_EDITNO
);
594 SetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
);
595 CheckDlgButton(hwnd
, IDC_ALWAYSONTOP
, cfg
.alwaysontop
);
596 CheckDlgButton(hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
597 CheckDlgButton(hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
599 CheckDlgButton(hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
600 CheckDlgButton(hwnd
, IDC_DECOM
, cfg
.dec_om
);
601 CheckDlgButton(hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
602 SetDlgItemInt(hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
603 SetDlgItemInt(hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
604 SetDlgItemInt(hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
606 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
607 CheckRadioButton(hwnd
, IDC_BELL_DISABLED
, IDC_BELL_VISUAL
,
608 cfg
.beep
== BELL_DISABLED ? IDC_BELL_DISABLED
:
609 cfg
.beep
== BELL_DEFAULT ? IDC_BELL_DEFAULT
:
610 cfg
.beep
== BELL_WAVEFILE ? IDC_BELL_WAVEFILE
:
612 BELL_VISUAL ? IDC_BELL_VISUAL
: IDC_BELL_DEFAULT
);
613 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
, cfg
.bell_wavefile
);
614 CheckDlgButton(hwnd
, IDC_BELLOVL
, cfg
.bellovl
);
615 SetDlgItemInt(hwnd
, IDC_BELLOVLN
, cfg
.bellovl_n
, FALSE
);
616 MySetDlgItemFlt(hwnd
, IDC_BELLOVLT
, cfg
.bellovl_t
/ 1000.0);
617 MySetDlgItemFlt(hwnd
, IDC_BELLOVLS
, cfg
.bellovl_s
/ 1000.0);
619 CheckDlgButton(hwnd
, IDC_BCE
, cfg
.bce
);
620 CheckDlgButton(hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
622 SetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
623 CheckDlgButton(hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
624 CheckDlgButton(hwnd
, IDC_HIDEMOUSE
, cfg
.hide_mouseptr
);
625 CheckDlgButton(hwnd
, IDC_SUNKENEDGE
, cfg
.sunken_edge
);
626 CheckRadioButton(hwnd
, IDC_CURBLOCK
, IDC_CURVERT
,
627 cfg
.cursor_type
== 0 ? IDC_CURBLOCK
:
628 cfg
.cursor_type
== 1 ? IDC_CURUNDER
: IDC_CURVERT
);
629 CheckDlgButton(hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
630 CheckDlgButton(hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
631 CheckDlgButton(hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
632 CheckRadioButton(hwnd
, IDC_COEALWAYS
, IDC_COENORMAL
,
633 cfg
.close_on_exit
== COE_NORMAL ? IDC_COENORMAL
:
635 COE_NEVER ? IDC_COENEVER
: IDC_COEALWAYS
);
636 CheckDlgButton(hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
638 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
639 SetDlgItemText(hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
640 SetDlgItemText(hwnd
, IDC_R_TSEDIT
, cfg
.termspeed
);
641 SetDlgItemText(hwnd
, IDC_RLLUSEREDIT
, cfg
.localusername
);
642 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
643 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
644 CheckRadioButton(hwnd
, IDC_LSTATOFF
, IDC_LSTATRAW
,
645 cfg
.logtype
== 0 ? IDC_LSTATOFF
:
646 cfg
.logtype
== 1 ? IDC_LSTATASCII
: IDC_LSTATRAW
);
647 CheckRadioButton(hwnd
, IDC_LSTATXOVR
, IDC_LSTATXASK
,
648 cfg
.logxfovr
== LGXF_OVR ? IDC_LSTATXOVR
:
649 cfg
.logxfovr
== LGXF_ASK ? IDC_LSTATXASK
:
652 char *p
= cfg
.environmt
;
654 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
659 CheckRadioButton(hwnd
, IDC_EMBSD
, IDC_EMRFC
,
660 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
662 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
663 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
664 CheckDlgButton(hwnd
, IDC_NOPTY
, cfg
.nopty
);
665 CheckDlgButton(hwnd
, IDC_COMPRESS
, cfg
.compression
);
666 CheckDlgButton(hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
667 CheckDlgButton(hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
668 CheckRadioButton(hwnd
, IDC_CIPHER3DES
, IDC_CIPHERAES
,
669 cfg
.cipher
== CIPHER_BLOWFISH ? IDC_CIPHERBLOWF
:
670 cfg
.cipher
== CIPHER_DES ? IDC_CIPHERDES
:
671 cfg
.cipher
== CIPHER_AES ? IDC_CIPHERAES
:
673 CheckRadioButton(hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
674 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
675 CheckDlgButton(hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
676 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
677 SetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
679 CheckRadioButton(hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
680 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
681 CheckDlgButton(hwnd
, IDC_RAWCNP
, cfg
.rawcnp
);
683 static int tabs
[4] = { 25, 61, 96, 128 };
684 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
687 for (i
= 0; i
< 256; i
++) {
689 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
690 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ', cfg
.wordness
[i
]);
691 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
695 CheckDlgButton(hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
696 CheckDlgButton(hwnd
, IDC_PALETTE
, cfg
.try_palette
);
699 n
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
700 for (i
= n
; i
-- > 0;)
701 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
702 LB_DELETESTRING
, i
, 0);
703 for (i
= 0; i
< 22; i
++)
704 if (cfg
.bold_colour
|| permcolour
[i
])
705 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
706 (LPARAM
) colours
[i
]);
708 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
709 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
710 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
711 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
713 CheckRadioButton(hwnd
, IDC_NOXLAT
, IDC_88592CP852
,
714 cfg
.xlat_88592w1250 ? IDC_88592WIN1250
:
715 cfg
.xlat_88592cp852 ? IDC_88592CP852
:
716 cfg
.xlat_enablekoiwin ? IDC_KOI8WIN1251
: IDC_NOXLAT
);
717 CheckDlgButton(hwnd
, IDC_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
718 CheckRadioButton(hwnd
, IDC_VTXWINDOWS
, IDC_VTPOORMAN
,
719 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
720 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
721 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
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
, 4,
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
, NULL
);
1016 beginbox(&cp
, "Enable character set translation on received data",
1017 IDC_BOX_TRANSLATION2
);
1019 "Character set &translation:", IDC_XLATSTATIC
,
1021 "KOI8 / Win-1251", IDC_KOI8WIN1251
,
1022 "ISO-8859-2 / Win-1250", IDC_88592WIN1250
,
1023 "ISO-8859-2 / CP852", IDC_88592CP852
, NULL
);
1025 beginbox(&cp
, "Enable character set translation on input data",
1026 IDC_BOX_TRANSLATION3
);
1027 checkbox(&cp
, "CAP&S LOCK acts as cyrillic switch",
1032 if (panel
== selectionpanelstart
) {
1033 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1035 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1036 bartitle(&cp
, "Options controlling copy and paste",
1037 IDC_TITLE_SELECTION
);
1038 beginbox(&cp
, "Translation of pasted characters",
1039 IDC_BOX_SELECTION1
);
1041 "&Don't translate line drawing chars into +, - and |",
1044 beginbox(&cp
, "Control which mouse button does which thing",
1045 IDC_BOX_SELECTION2
);
1046 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
1047 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
1048 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
1051 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
1052 IDC_BOX_SELECTION3
);
1053 charclass(&cp
, "C&haracter classes:", IDC_CCSTATIC
, IDC_CCLIST
,
1054 "&Set", IDC_CCSET
, IDC_CCEDIT
,
1055 "&to class", IDC_CCSTATIC2
);
1059 if (panel
== colourspanelstart
) {
1060 /* The Colours panel. Accelerators used: [acgo] blum */
1062 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1063 bartitle(&cp
, "Options controlling use of colours",
1065 beginbox(&cp
, "General options for colour usage",
1067 checkbox(&cp
, "&Bolded text is a different colour",
1069 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
1071 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
1073 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
1074 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
1075 "&Modify...", IDC_CHANGE
,
1076 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
1077 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
1078 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
1082 if (panel
== connectionpanelstart
) {
1083 /* The Connection panel. Accelerators used: [acgo] tuk */
1085 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1086 bartitle(&cp
, "Options controlling the connection",
1087 IDC_TITLE_CONNECTION
);
1089 beginbox(&cp
, "Data to send to the server",
1090 IDC_BOX_CONNECTION1
);
1091 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
,
1093 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
,
1097 beginbox(&cp
, "Sending of null packets to keep session active",
1098 IDC_BOX_CONNECTION2
);
1099 staticedit(&cp
, "Seconds between &keepalives (0 to turn off)",
1100 IDC_PINGSTATIC
, IDC_PINGEDIT
, 20);
1104 if (panel
== telnetpanelstart
) {
1105 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
1107 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1109 bartitle(&cp
, "Options controlling Telnet connections",
1111 beginbox(&cp
, "Data to send to the server", IDC_BOX_TELNET1
);
1112 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
,
1114 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
1115 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
, "Va&lue",
1116 IDC_VALSTATIC
, IDC_VALEDIT
, IDC_ENVLIST
, "A&dd",
1117 IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
1119 beginbox(&cp
, "Telnet protocol adjustments", IDC_BOX_TELNET2
);
1120 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:",
1121 IDC_EMSTATIC
, 2, "&BSD (commonplace)", IDC_EMBSD
,
1122 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
1127 if (panel
== rloginpanelstart
) {
1128 /* The Rlogin panel. Accelerators used: [acgo] sl */
1130 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1132 bartitle(&cp
, "Options controlling Rlogin connections",
1134 beginbox(&cp
, "Data to send to the server", IDC_BOX_RLOGIN1
);
1135 staticedit(&cp
, "Terminal-&speed string", IDC_R_TSSTATIC
,
1137 staticedit(&cp
, "&Local username:", IDC_RLLUSERSTATIC
,
1138 IDC_RLLUSEREDIT
, 50);
1143 if (panel
== sshpanelstart
) {
1144 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1146 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1148 bartitle(&cp
, "Options controlling SSH connections",
1150 beginbox(&cp
, "Data to send to the server", IDC_BOX_SSH1
);
1152 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
1155 beginbox(&cp
, "Authentication options", IDC_BOX_SSH2
);
1156 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
1158 checkbox(&cp
, "Allow agent &forwarding", IDC_AGENTFWD
);
1159 editbutton(&cp
, "Private &key file for authentication:",
1160 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...",
1163 beginbox(&cp
, "Protocol options", IDC_BOX_SSH3
);
1164 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
1165 checkbox(&cp
, "Enable compr&ession", IDC_COMPRESS
);
1166 radioline(&cp
, "Preferred SSH protocol version:",
1167 IDC_SSHPROTSTATIC
, 2,
1168 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
1169 radioline(&cp
, "Preferred encryption algorithm:",
1170 IDC_CIPHERSTATIC
, 4, "&3DES", IDC_CIPHER3DES
,
1171 "&Blowfish", IDC_CIPHERBLOWF
, "&DES", IDC_CIPHERDES
,
1172 "AE&S", IDC_CIPHERAES
, NULL
);
1173 checkbox(&cp
, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1179 if (panel
== tunnelspanelstart
) {
1180 /* The Tunnels panel. Accelerators used: [acgo] ex */
1182 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1184 bartitle(&cp
, "Options controlling SSH tunnelling",
1186 beginbox(&cp
, "X11 forwarding options", IDC_BOX_TUNNELS
);
1187 checkbox(&cp
, "&Enable X11 forwarding", IDC_X11_FORWARD
);
1188 multiedit(&cp
, "&X display location", IDC_X11_DISPSTATIC
,
1189 IDC_X11_DISPLAY
, 50, NULL
);
1196 * This function is the configuration box.
1198 static int GenericMainDlgProc(HWND hwnd
, UINT msg
,
1199 WPARAM wParam
, LPARAM lParam
, int dlgtype
)
1202 struct treeview_faff tvfaff
;
1205 char filename
[sizeof(cfg
.keyfile
)];
1208 char fontstatic
[256];
1210 struct servent
*service
;
1216 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1218 * Centre the window.
1220 { /* centre the window */
1223 hw
= GetDesktopWindow();
1224 if (GetWindowRect(hw
, &rs
) && GetWindowRect(hwnd
, &rd
))
1226 (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
) / 2,
1227 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
) / 2,
1228 rd
.right
- rd
.left
, rd
.bottom
- rd
.top
, TRUE
);
1232 * Create the tree view.
1240 r
.right
= r
.left
+ 75;
1242 r
.bottom
= r
.top
+ 10;
1243 MapDialogRect(hwnd
, &r
);
1244 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
1245 WS_CHILD
| WS_VISIBLE
,
1247 r
.right
- r
.left
, r
.bottom
- r
.top
,
1248 hwnd
, (HMENU
) IDCX_TVSTATIC
, hinst
,
1250 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1251 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1254 r
.right
= r
.left
+ 75;
1256 r
.bottom
= r
.top
+ 206;
1257 MapDialogRect(hwnd
, &r
);
1258 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
1259 WS_CHILD
| WS_VISIBLE
|
1260 WS_TABSTOP
| TVS_HASLINES
|
1261 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
1263 TVS_SHOWSELALWAYS
, r
.left
, r
.top
,
1264 r
.right
- r
.left
, r
.bottom
- r
.top
,
1265 hwnd
, (HMENU
) IDCX_TREEVIEW
, hinst
,
1267 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1268 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1269 tvfaff
.treeview
= treeview
;
1270 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
1274 * Set up the tree view contents.
1276 hsession
= treeview_insert(&tvfaff
, 0, "Session");
1277 treeview_insert(&tvfaff
, 1, "Logging");
1278 treeview_insert(&tvfaff
, 0, "Terminal");
1279 treeview_insert(&tvfaff
, 1, "Keyboard");
1280 treeview_insert(&tvfaff
, 1, "Bell");
1281 treeview_insert(&tvfaff
, 0, "Window");
1282 treeview_insert(&tvfaff
, 1, "Appearance");
1283 treeview_insert(&tvfaff
, 1, "Translation");
1284 treeview_insert(&tvfaff
, 1, "Selection");
1285 treeview_insert(&tvfaff
, 1, "Colours");
1286 treeview_insert(&tvfaff
, 0, "Connection");
1288 treeview_insert(&tvfaff
, 1, "Telnet");
1289 treeview_insert(&tvfaff
, 1, "Rlogin");
1290 if (backends
[3].backend
!= NULL
) {
1291 treeview_insert(&tvfaff
, 1, "SSH");
1292 treeview_insert(&tvfaff
, 2, "Tunnels");
1297 * Put the treeview selection on to the Session panel. This
1298 * should also cause creation of the relevant controls.
1300 TreeView_SelectItem(treeview
, hsession
);
1303 * Set focus into the first available control.
1307 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
1309 ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
1313 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1317 * Button release should trigger WM_OK if there was a
1318 * previous double click on the session list.
1322 SendMessage(hwnd
, WM_COMMAND
, IDOK
, 0);
1325 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1326 ((LPNMHDR
) lParam
)->code
== TVN_SELCHANGED
) {
1328 TreeView_GetSelection(((LPNMHDR
) lParam
)->hwndFrom
);
1333 item
.pszText
= buffer
;
1334 item
.cchTextMax
= sizeof(buffer
);
1335 item
.mask
= TVIF_TEXT
;
1336 TreeView_GetItem(((LPNMHDR
) lParam
)->hwndFrom
, &item
);
1337 for (j
= controlstartvalue
; j
< controlendvalue
; j
++) {
1338 HWND item
= GetDlgItem(hwnd
, j
);
1340 DestroyWindow(item
);
1342 if (!strcmp(buffer
, "Session"))
1343 create_controls(hwnd
, dlgtype
, sessionpanelstart
);
1344 if (!strcmp(buffer
, "Logging"))
1345 create_controls(hwnd
, dlgtype
, loggingpanelstart
);
1346 if (!strcmp(buffer
, "Keyboard"))
1347 create_controls(hwnd
, dlgtype
, keyboardpanelstart
);
1348 if (!strcmp(buffer
, "Terminal"))
1349 create_controls(hwnd
, dlgtype
, terminalpanelstart
);
1350 if (!strcmp(buffer
, "Bell"))
1351 create_controls(hwnd
, dlgtype
, bellpanelstart
);
1352 if (!strcmp(buffer
, "Window"))
1353 create_controls(hwnd
, dlgtype
, windowpanelstart
);
1354 if (!strcmp(buffer
, "Appearance"))
1355 create_controls(hwnd
, dlgtype
, appearancepanelstart
);
1356 if (!strcmp(buffer
, "Tunnels"))
1357 create_controls(hwnd
, dlgtype
, tunnelspanelstart
);
1358 if (!strcmp(buffer
, "Connection"))
1359 create_controls(hwnd
, dlgtype
, connectionpanelstart
);
1360 if (!strcmp(buffer
, "Telnet"))
1361 create_controls(hwnd
, dlgtype
, telnetpanelstart
);
1362 if (!strcmp(buffer
, "Rlogin"))
1363 create_controls(hwnd
, dlgtype
, rloginpanelstart
);
1364 if (!strcmp(buffer
, "SSH"))
1365 create_controls(hwnd
, dlgtype
, sshpanelstart
);
1366 if (!strcmp(buffer
, "Selection"))
1367 create_controls(hwnd
, dlgtype
, selectionpanelstart
);
1368 if (!strcmp(buffer
, "Colours"))
1369 create_controls(hwnd
, dlgtype
, colourspanelstart
);
1370 if (!strcmp(buffer
, "Translation"))
1371 create_controls(hwnd
, dlgtype
, translationpanelstart
);
1373 init_dlg_ctrls(hwnd
);
1375 SetFocus(((LPNMHDR
) lParam
)->hwndFrom
); /* ensure focus stays */
1381 * Only process WM_COMMAND once the dialog is fully formed.
1383 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1)
1384 switch (LOWORD(wParam
)) {
1394 case IDC_PROTTELNET
:
1395 case IDC_PROTRLOGIN
:
1398 if (HIWORD(wParam
) == BN_CLICKED
||
1399 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1400 int i
= IsDlgButtonChecked(hwnd
, IDC_PROTSSH
);
1401 int j
= IsDlgButtonChecked(hwnd
, IDC_PROTTELNET
);
1402 int k
= IsDlgButtonChecked(hwnd
, IDC_PROTRLOGIN
);
1404 i ? PROT_SSH
: j ? PROT_TELNET
: k ? PROT_RLOGIN
:
1406 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
!= 22)
1407 || (cfg
.protocol
== PROT_TELNET
&& cfg
.port
!= 23)
1408 || (cfg
.protocol
== PROT_RLOGIN
1409 && cfg
.port
!= 513)) {
1410 cfg
.port
= i ?
22 : j ?
23 : 513;
1411 SetDlgItemInt(hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1416 if (HIWORD(wParam
) == EN_CHANGE
)
1417 GetDlgItemText(hwnd
, IDC_HOST
, cfg
.host
,
1418 sizeof(cfg
.host
) - 1);
1421 if (HIWORD(wParam
) == EN_CHANGE
) {
1422 GetDlgItemText(hwnd
, IDC_PORT
, portname
, 31);
1423 if (isdigit(portname
[0]))
1424 MyGetDlgItemInt(hwnd
, IDC_PORT
, &cfg
.port
);
1426 service
= getservbyname(portname
, NULL
);
1428 cfg
.port
= ntohs(service
->s_port
);
1435 if (HIWORD(wParam
) == EN_CHANGE
) {
1436 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1438 GetDlgItemText(hwnd
, IDC_SESSEDIT
,
1439 savedsession
, sizeof(savedsession
) - 1);
1440 savedsession
[sizeof(savedsession
) - 1] = '\0';
1444 if (HIWORD(wParam
) == BN_CLICKED
||
1445 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1450 GetDlgItemText(hwnd
, IDC_SESSEDIT
, str
,
1453 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1454 LB_GETCURSEL
, 0, 0);
1459 strcpy(str
, sessions
[n
]);
1461 save_settings(str
, !!strcmp(str
, "Default Settings"),
1463 get_sesslist(FALSE
);
1465 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1467 for (i
= 0; i
< nsessions
; i
++)
1468 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1470 (LPARAM
) (sessions
[i
]));
1471 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1477 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1478 HIWORD(wParam
) != BN_CLICKED
&&
1479 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
1480 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1481 HIWORD(wParam
) != LBN_DBLCLK
) break;
1483 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1484 LB_GETCURSEL
, 0, 0);
1490 isdef
= !strcmp(sessions
[n
], "Default Settings");
1491 load_settings(sessions
[n
], !isdef
, &cfg
);
1492 init_dlg_ctrls(hwnd
);
1494 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1496 SetDlgItemText(hwnd
, IDC_SESSEDIT
, "");
1498 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1500 * A double-click on a saved session should
1501 * actually start the session, not just load it.
1502 * Unless it's Default Settings or some other
1503 * host-less set of saved settings.
1512 if (HIWORD(wParam
) == BN_CLICKED
||
1513 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1514 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1515 LB_GETCURSEL
, 0, 0);
1516 if (n
== LB_ERR
|| n
== 0) {
1520 del_settings(sessions
[n
]);
1521 get_sesslist(FALSE
);
1523 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1525 for (i
= 0; i
< nsessions
; i
++)
1526 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1528 (LPARAM
) (sessions
[i
]));
1529 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1533 if (HIWORD(wParam
) == EN_CHANGE
)
1534 MyGetDlgItemInt(hwnd
, IDC_PINGEDIT
,
1535 &cfg
.ping_interval
);
1539 if (HIWORD(wParam
) == BN_CLICKED
||
1540 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1541 cfg
.bksp_is_delete
=
1542 IsDlgButtonChecked(hwnd
, IDC_DEL127
);
1546 if (HIWORD(wParam
) == BN_CLICKED
||
1547 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1549 IsDlgButtonChecked(hwnd
, IDC_HOMERXVT
);
1555 case IDC_FUNCVT100P
:
1557 if (HIWORD(wParam
) == BN_CLICKED
||
1558 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1559 switch (LOWORD(wParam
)) {
1572 case IDC_FUNCVT100P
:
1582 if (HIWORD(wParam
) == BN_CLICKED
||
1583 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1585 IsDlgButtonChecked(hwnd
, IDC_KPAPPLIC
);
1586 cfg
.nethack_keypad
= FALSE
;
1590 if (HIWORD(wParam
) == BN_CLICKED
||
1591 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1592 cfg
.app_keypad
= FALSE
;
1593 cfg
.nethack_keypad
= TRUE
;
1598 if (HIWORD(wParam
) == BN_CLICKED
||
1599 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1601 IsDlgButtonChecked(hwnd
, IDC_CURAPPLIC
);
1604 if (HIWORD(wParam
) == BN_CLICKED
||
1605 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1607 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICC
);
1610 if (HIWORD(wParam
) == BN_CLICKED
||
1611 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1613 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICK
);
1616 if (HIWORD(wParam
) == BN_CLICKED
||
1617 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1618 cfg
.alt_f4
= IsDlgButtonChecked(hwnd
, IDC_ALTF4
);
1621 if (HIWORD(wParam
) == BN_CLICKED
||
1622 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1624 IsDlgButtonChecked(hwnd
, IDC_ALTSPACE
);
1627 if (HIWORD(wParam
) == BN_CLICKED
||
1628 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1630 IsDlgButtonChecked(hwnd
, IDC_ALTONLY
);
1632 case IDC_ECHOBACKEND
:
1635 if (HIWORD(wParam
) == BN_CLICKED
||
1636 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1637 if (LOWORD(wParam
) == IDC_ECHOBACKEND
)
1638 cfg
.localecho
= LD_BACKEND
;
1639 if (LOWORD(wParam
) == IDC_ECHOYES
)
1640 cfg
.localecho
= LD_YES
;
1641 if (LOWORD(wParam
) == IDC_ECHONO
)
1642 cfg
.localecho
= LD_NO
;
1645 case IDC_EDITBACKEND
:
1648 if (HIWORD(wParam
) == BN_CLICKED
||
1649 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1650 if (LOWORD(wParam
) == IDC_EDITBACKEND
)
1651 cfg
.localedit
= LD_BACKEND
;
1652 if (LOWORD(wParam
) == IDC_EDITYES
)
1653 cfg
.localedit
= LD_YES
;
1654 if (LOWORD(wParam
) == IDC_EDITNO
)
1655 cfg
.localedit
= LD_NO
;
1658 case IDC_ANSWEREDIT
:
1659 if (HIWORD(wParam
) == EN_CHANGE
)
1660 GetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
,
1661 sizeof(cfg
.answerback
) - 1);
1663 case IDC_ALWAYSONTOP
:
1664 if (HIWORD(wParam
) == BN_CLICKED
||
1665 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1667 IsDlgButtonChecked(hwnd
, IDC_ALWAYSONTOP
);
1670 if (HIWORD(wParam
) == BN_CLICKED
||
1671 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1673 IsDlgButtonChecked(hwnd
, IDC_SCROLLKEY
);
1675 case IDC_SCROLLDISP
:
1676 if (HIWORD(wParam
) == BN_CLICKED
||
1677 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1678 cfg
.scroll_on_disp
=
1679 IsDlgButtonChecked(hwnd
, IDC_SCROLLDISP
);
1681 case IDC_COMPOSEKEY
:
1682 if (HIWORD(wParam
) == BN_CLICKED
||
1683 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1685 IsDlgButtonChecked(hwnd
, IDC_COMPOSEKEY
);
1687 case IDC_CTRLALTKEYS
:
1688 if (HIWORD(wParam
) == BN_CLICKED
||
1689 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1691 IsDlgButtonChecked(hwnd
, IDC_CTRLALTKEYS
);
1694 if (HIWORD(wParam
) == BN_CLICKED
||
1695 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1697 IsDlgButtonChecked(hwnd
, IDC_WRAPMODE
);
1700 if (HIWORD(wParam
) == BN_CLICKED
||
1701 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1702 cfg
.dec_om
= IsDlgButtonChecked(hwnd
, IDC_DECOM
);
1705 if (HIWORD(wParam
) == BN_CLICKED
||
1706 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1708 IsDlgButtonChecked(hwnd
, IDC_LFHASCR
);
1711 if (HIWORD(wParam
) == EN_CHANGE
)
1712 MyGetDlgItemInt(hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1715 if (HIWORD(wParam
) == EN_CHANGE
)
1716 MyGetDlgItemInt(hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1719 if (HIWORD(wParam
) == EN_CHANGE
)
1720 MyGetDlgItemInt(hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1722 case IDC_CHOOSEFONT
:
1723 lf
.lfHeight
= cfg
.fontheight
;
1724 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1725 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1726 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1727 lf
.lfCharSet
= cfg
.fontcharset
;
1728 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1729 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1730 lf
.lfQuality
= DEFAULT_QUALITY
;
1731 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1732 strncpy(lf
.lfFaceName
, cfg
.font
,
1733 sizeof(lf
.lfFaceName
) - 1);
1734 lf
.lfFaceName
[sizeof(lf
.lfFaceName
) - 1] = '\0';
1736 cf
.lStructSize
= sizeof(cf
);
1737 cf
.hwndOwner
= hwnd
;
1739 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1740 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1742 if (ChooseFont(&cf
)) {
1743 strncpy(cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
) - 1);
1744 cfg
.font
[sizeof(cfg
.font
) - 1] = '\0';
1745 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1746 cfg
.fontcharset
= lf
.lfCharSet
;
1747 cfg
.fontheight
= cf
.iPointSize
/ 10;
1748 fmtfont(fontstatic
);
1749 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
1752 case IDC_BELL_DISABLED
:
1753 case IDC_BELL_DEFAULT
:
1754 case IDC_BELL_WAVEFILE
:
1755 case IDC_BELL_VISUAL
:
1756 if (HIWORD(wParam
) == BN_CLICKED
||
1757 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1758 if (LOWORD(wParam
) == IDC_BELL_DISABLED
)
1759 cfg
.beep
= BELL_DISABLED
;
1760 if (LOWORD(wParam
) == IDC_BELL_DEFAULT
)
1761 cfg
.beep
= BELL_DEFAULT
;
1762 if (LOWORD(wParam
) == IDC_BELL_WAVEFILE
)
1763 cfg
.beep
= BELL_WAVEFILE
;
1764 if (LOWORD(wParam
) == IDC_BELL_VISUAL
)
1765 cfg
.beep
= BELL_VISUAL
;
1768 case IDC_BELL_WAVEBROWSE
:
1769 memset(&of
, 0, sizeof(of
));
1770 #ifdef OPENFILENAME_SIZE_VERSION_400
1771 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1773 of
.lStructSize
= sizeof(of
);
1775 of
.hwndOwner
= hwnd
;
1776 of
.lpstrFilter
= "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1777 of
.lpstrCustomFilter
= NULL
;
1778 of
.nFilterIndex
= 1;
1779 of
.lpstrFile
= filename
;
1780 strcpy(filename
, cfg
.bell_wavefile
);
1781 of
.nMaxFile
= sizeof(filename
);
1782 of
.lpstrFileTitle
= NULL
;
1783 of
.lpstrInitialDir
= NULL
;
1784 of
.lpstrTitle
= "Select Bell Sound File";
1786 if (GetOpenFileName(&of
)) {
1787 strcpy(cfg
.bell_wavefile
, filename
);
1788 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
1792 case IDC_BELL_WAVEEDIT
:
1793 if (HIWORD(wParam
) == EN_CHANGE
)
1794 GetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
1796 sizeof(cfg
.bell_wavefile
) - 1);
1799 if (HIWORD(wParam
) == BN_CLICKED
||
1800 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1802 IsDlgButtonChecked(hwnd
, IDC_BELLOVL
);
1805 if (HIWORD(wParam
) == EN_CHANGE
)
1806 MyGetDlgItemInt(hwnd
, IDC_BELLOVLN
, &cfg
.bellovl_n
);
1809 if (HIWORD(wParam
) == EN_CHANGE
)
1810 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLT
, &cfg
.bellovl_t
,
1814 if (HIWORD(wParam
) == EN_CHANGE
)
1815 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLS
, &cfg
.bellovl_s
,
1819 if (HIWORD(wParam
) == BN_CLICKED
||
1820 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1822 IsDlgButtonChecked(hwnd
, IDC_BLINKTEXT
);
1825 if (HIWORD(wParam
) == BN_CLICKED
||
1826 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1827 cfg
.bce
= IsDlgButtonChecked(hwnd
, IDC_BCE
);
1830 if (HIWORD(wParam
) == BN_CLICKED
||
1831 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1832 cfg
.win_name_always
=
1833 IsDlgButtonChecked(hwnd
, IDC_WINNAME
);
1836 if (HIWORD(wParam
) == BN_CLICKED
||
1837 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1839 IsDlgButtonChecked(hwnd
, IDC_HIDEMOUSE
);
1841 case IDC_SUNKENEDGE
:
1842 if (HIWORD(wParam
) == BN_CLICKED
||
1843 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1845 IsDlgButtonChecked(hwnd
, IDC_SUNKENEDGE
);
1848 if (HIWORD(wParam
) == BN_CLICKED
||
1849 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1850 cfg
.cursor_type
= 0;
1853 if (HIWORD(wParam
) == BN_CLICKED
||
1854 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1855 cfg
.cursor_type
= 1;
1858 if (HIWORD(wParam
) == BN_CLICKED
||
1859 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1860 cfg
.cursor_type
= 2;
1863 if (HIWORD(wParam
) == BN_CLICKED
||
1864 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1866 IsDlgButtonChecked(hwnd
, IDC_BLINKCUR
);
1869 if (HIWORD(wParam
) == BN_CLICKED
||
1870 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1872 IsDlgButtonChecked(hwnd
, IDC_SCROLLBAR
);
1875 if (HIWORD(wParam
) == BN_CLICKED
||
1876 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1878 IsDlgButtonChecked(hwnd
, IDC_LOCKSIZE
);
1881 if (HIWORD(wParam
) == EN_CHANGE
)
1882 GetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
1883 sizeof(cfg
.wintitle
) - 1);
1888 if (HIWORD(wParam
) == BN_CLICKED
||
1889 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1891 IsDlgButtonChecked(hwnd
,
1892 IDC_COEALWAYS
) ? COE_ALWAYS
:
1893 IsDlgButtonChecked(hwnd
,
1894 IDC_COENEVER
) ? COE_NEVER
:
1899 if (HIWORD(wParam
) == BN_CLICKED
||
1900 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1902 IsDlgButtonChecked(hwnd
, IDC_CLOSEWARN
);
1905 if (HIWORD(wParam
) == EN_CHANGE
)
1906 GetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
,
1907 sizeof(cfg
.termtype
) - 1);
1910 if (HIWORD(wParam
) == EN_CHANGE
)
1911 GetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
,
1912 sizeof(cfg
.logfilename
) - 1);
1915 memset(&of
, 0, sizeof(of
));
1916 #ifdef OPENFILENAME_SIZE_VERSION_400
1917 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1919 of
.lStructSize
= sizeof(of
);
1921 of
.hwndOwner
= hwnd
;
1922 of
.lpstrFilter
= "All Files\0*\0\0\0";
1923 of
.lpstrCustomFilter
= NULL
;
1924 of
.nFilterIndex
= 1;
1925 of
.lpstrFile
= filename
;
1926 strcpy(filename
, cfg
.logfilename
);
1927 of
.nMaxFile
= sizeof(filename
);
1928 of
.lpstrFileTitle
= NULL
;
1929 of
.lpstrInitialDir
= NULL
;
1930 of
.lpstrTitle
= "Select session log file";
1932 if (GetSaveFileName(&of
)) {
1933 strcpy(cfg
.logfilename
, filename
);
1934 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
1938 case IDC_LSTATASCII
:
1940 if (HIWORD(wParam
) == BN_CLICKED
||
1941 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1942 if (IsDlgButtonChecked(hwnd
, IDC_LSTATOFF
))
1944 if (IsDlgButtonChecked(hwnd
, IDC_LSTATASCII
))
1946 if (IsDlgButtonChecked(hwnd
, IDC_LSTATRAW
))
1953 if (HIWORD(wParam
) == BN_CLICKED
||
1954 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1955 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXASK
))
1956 cfg
.logxfovr
= LGXF_ASK
;
1957 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXAPN
))
1958 cfg
.logxfovr
= LGXF_APN
;
1959 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXOVR
))
1960 cfg
.logxfovr
= LGXF_OVR
;
1965 if (HIWORD(wParam
) == EN_CHANGE
)
1966 GetDlgItemText(hwnd
, LOWORD(wParam
), cfg
.termspeed
,
1967 sizeof(cfg
.termspeed
) - 1);
1970 if (HIWORD(wParam
) == EN_CHANGE
)
1971 GetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
,
1972 sizeof(cfg
.username
) - 1);
1974 case IDC_RLLUSEREDIT
:
1975 if (HIWORD(wParam
) == EN_CHANGE
)
1976 GetDlgItemText(hwnd
, IDC_RLLUSEREDIT
,
1978 sizeof(cfg
.localusername
) - 1);
1982 cfg
.rfc_environ
= IsDlgButtonChecked(hwnd
, IDC_EMRFC
);
1985 if (HIWORD(wParam
) == BN_CLICKED
||
1986 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1987 char str
[sizeof(cfg
.environmt
)];
1989 GetDlgItemText(hwnd
, IDC_VAREDIT
, str
,
1995 p
= str
+ strlen(str
);
1997 GetDlgItemText(hwnd
, IDC_VALEDIT
, p
,
1998 sizeof(str
) - 1 - (p
- str
));
2009 if ((p
- cfg
.environmt
) + strlen(str
) + 2 <
2010 sizeof(cfg
.environmt
)) {
2012 p
[strlen(str
) + 1] = '\0';
2013 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
2015 SetDlgItemText(hwnd
, IDC_VAREDIT
, "");
2016 SetDlgItemText(hwnd
, IDC_VALEDIT
, "");
2018 MessageBox(hwnd
, "Environment too big",
2019 "PuTTY Error", MB_OK
| MB_ICONERROR
);
2024 if (HIWORD(wParam
) != BN_CLICKED
&&
2025 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
2027 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0,
2034 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
2061 if (HIWORD(wParam
) == BN_CLICKED
||
2062 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2063 cfg
.nopty
= IsDlgButtonChecked(hwnd
, IDC_NOPTY
);
2066 if (HIWORD(wParam
) == BN_CLICKED
||
2067 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2069 IsDlgButtonChecked(hwnd
, IDC_COMPRESS
);
2072 if (HIWORD(wParam
) == BN_CLICKED
||
2073 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2075 IsDlgButtonChecked(hwnd
, IDC_BUGGYMAC
);
2078 if (HIWORD(wParam
) == BN_CLICKED
||
2079 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2081 IsDlgButtonChecked(hwnd
, IDC_AGENTFWD
);
2083 case IDC_CIPHER3DES
:
2084 case IDC_CIPHERBLOWF
:
2087 if (HIWORD(wParam
) == BN_CLICKED
||
2088 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2089 if (IsDlgButtonChecked(hwnd
, IDC_CIPHER3DES
))
2090 cfg
.cipher
= CIPHER_3DES
;
2091 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERBLOWF
))
2092 cfg
.cipher
= CIPHER_BLOWFISH
;
2093 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERDES
))
2094 cfg
.cipher
= CIPHER_DES
;
2095 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERAES
))
2096 cfg
.cipher
= CIPHER_AES
;
2101 if (HIWORD(wParam
) == BN_CLICKED
||
2102 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2103 if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT1
))
2105 else if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT2
))
2110 if (HIWORD(wParam
) == BN_CLICKED
||
2111 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2113 IsDlgButtonChecked(hwnd
, IDC_AUTHTIS
);
2116 if (HIWORD(wParam
) == EN_CHANGE
)
2117 GetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
2118 sizeof(cfg
.keyfile
) - 1);
2121 if (HIWORD(wParam
) == EN_CHANGE
)
2122 GetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
2123 sizeof(cfg
.remote_cmd
) - 1);
2126 memset(&of
, 0, sizeof(of
));
2127 #ifdef OPENFILENAME_SIZE_VERSION_400
2128 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
2130 of
.lStructSize
= sizeof(of
);
2132 of
.hwndOwner
= hwnd
;
2133 of
.lpstrFilter
= "All Files\0*\0\0\0";
2134 of
.lpstrCustomFilter
= NULL
;
2135 of
.nFilterIndex
= 1;
2136 of
.lpstrFile
= filename
;
2137 strcpy(filename
, cfg
.keyfile
);
2138 of
.nMaxFile
= sizeof(filename
);
2139 of
.lpstrFileTitle
= NULL
;
2140 of
.lpstrInitialDir
= NULL
;
2141 of
.lpstrTitle
= "Select Public Key File";
2143 if (GetOpenFileName(&of
)) {
2144 strcpy(cfg
.keyfile
, filename
);
2145 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
2149 cfg
.rawcnp
= IsDlgButtonChecked(hwnd
, IDC_RAWCNP
);
2152 cfg
.mouse_is_xterm
= IsDlgButtonChecked(hwnd
, IDC_MBXTERM
);
2158 int n
= GetDlgItemInt(hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
2163 for (i
= 0; i
< 256; i
++)
2164 if (SendDlgItemMessage
2165 (hwnd
, IDC_CCLIST
, LB_GETSEL
, i
, 0)) {
2167 cfg
.wordness
[i
] = n
;
2168 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2169 LB_DELETESTRING
, i
, 0);
2170 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
2171 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ',
2173 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2180 case IDC_BOLDCOLOUR
:
2181 if (HIWORD(wParam
) == BN_CLICKED
||
2182 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2185 IsDlgButtonChecked(hwnd
, IDC_BOLDCOLOUR
);
2187 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2189 if (n
!= 12 + 10 * cfg
.bold_colour
) {
2190 for (i
= n
; i
-- > 0;)
2191 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2192 LB_DELETESTRING
, i
, 0);
2193 for (i
= 0; i
< 22; i
++)
2194 if (cfg
.bold_colour
|| permcolour
[i
])
2195 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2197 (LPARAM
) colours
[i
]);
2202 if (HIWORD(wParam
) == BN_CLICKED
||
2203 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2205 IsDlgButtonChecked(hwnd
, IDC_PALETTE
);
2207 case IDC_COLOURLIST
:
2208 if (HIWORD(wParam
) == LBN_DBLCLK
||
2209 HIWORD(wParam
) == LBN_SELCHANGE
) {
2210 int i
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2213 if (!cfg
.bold_colour
)
2214 i
= (i
< 3 ? i
* 2 : i
== 3 ?
5 : i
* 2 - 2);
2215 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2217 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2219 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2224 if (HIWORD(wParam
) == BN_CLICKED
||
2225 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2226 static CHOOSECOLOR cc
;
2227 static DWORD custom
[16] = { 0 }; /* zero initialisers */
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 cc
.lStructSize
= sizeof(cc
);
2234 cc
.hwndOwner
= hwnd
;
2235 cc
.hInstance
= (HWND
) hinst
;
2236 cc
.lpCustColors
= custom
;
2238 RGB(cfg
.colours
[i
][0], cfg
.colours
[i
][1],
2240 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
2241 if (ChooseColor(&cc
)) {
2243 (unsigned char) (cc
.rgbResult
& 0xFF);
2245 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
2247 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
2248 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2250 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2252 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2258 case IDC_KOI8WIN1251
:
2259 case IDC_88592WIN1250
:
2260 case IDC_88592CP852
:
2261 cfg
.xlat_enablekoiwin
=
2262 IsDlgButtonChecked(hwnd
, IDC_KOI8WIN1251
);
2263 cfg
.xlat_88592w1250
=
2264 IsDlgButtonChecked(hwnd
, IDC_88592WIN1250
);
2265 cfg
.xlat_88592cp852
=
2266 IsDlgButtonChecked(hwnd
, IDC_88592CP852
);
2268 case IDC_CAPSLOCKCYR
:
2269 if (HIWORD(wParam
) == BN_CLICKED
||
2270 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2271 cfg
.xlat_capslockcyr
=
2272 IsDlgButtonChecked(hwnd
, IDC_CAPSLOCKCYR
);
2275 case IDC_VTXWINDOWS
:
2280 (IsDlgButtonChecked(hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
2281 : IsDlgButtonChecked(hwnd
,
2282 IDC_VTOEMANSI
) ? VT_OEMANSI
:
2283 IsDlgButtonChecked(hwnd
,
2284 IDC_VTOEMONLY
) ? VT_OEMONLY
:
2287 case IDC_X11_FORWARD
:
2288 if (HIWORD(wParam
) == BN_CLICKED
||
2289 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2291 IsDlgButtonChecked(hwnd
, IDC_X11_FORWARD
);
2293 case IDC_X11_DISPLAY
:
2294 if (HIWORD(wParam
) == EN_CHANGE
)
2295 GetDlgItemText(hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
,
2296 sizeof(cfg
.x11_display
) - 1);
2304 /* Grrr Explorer will maximize Dialogs! */
2306 if (wParam
== SIZE_MAXIMIZED
)
2313 static int CALLBACK
MainDlgProc(HWND hwnd
, UINT msg
,
2314 WPARAM wParam
, LPARAM lParam
)
2316 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
2318 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
2319 EnableWindow(hwnd
, 0);
2320 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2321 GetParent(hwnd
), AboutProc
);
2322 EnableWindow(hwnd
, 1);
2323 SetActiveWindow(hwnd
);
2325 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 0);
2328 static int CALLBACK
ReconfDlgProc(HWND hwnd
, UINT msg
,
2329 WPARAM wParam
, LPARAM lParam
)
2331 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 1);
2334 void defuse_showwindow(void)
2337 * Work around the fact that the app's first call to ShowWindow
2338 * will ignore the default in favour of the shell-provided
2343 hwnd
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2345 ShowWindow(hwnd
, SW_HIDE
);
2346 DestroyWindow(hwnd
);
2355 savedsession
[0] = '\0';
2357 DialogBox(hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
2358 get_sesslist(FALSE
);
2363 int do_reconfig(HWND hwnd
)
2368 backup_cfg
= cfg
; /* structure copy */
2370 DialogBox(hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
2372 cfg
= backup_cfg
; /* structure copy */
2377 void logevent(char *string
)
2382 if (nevents
>= negsize
) {
2384 events
= srealloc(events
, negsize
* sizeof(*events
));
2388 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%d %H:%M:%S\t",
2391 events
[nevents
] = smalloc(strlen(timebuf
) + strlen(string
) + 1);
2392 strcpy(events
[nevents
], timebuf
);
2393 strcat(events
[nevents
], string
);
2396 SendDlgItemMessage(logbox
, IDN_LIST
, LB_ADDSTRING
,
2397 0, (LPARAM
) events
[nevents
]);
2398 count
= SendDlgItemMessage(logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
2399 SendDlgItemMessage(logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
- 1, 0);
2404 void showeventlog(HWND hwnd
)
2407 logbox
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
2409 ShowWindow(logbox
, SW_SHOWNORMAL
);
2411 SetActiveWindow(logbox
);
2414 void showabout(HWND hwnd
)
2416 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hwnd
, AboutProc
);
2419 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
2420 char *keystr
, char *fingerprint
)
2424 static const char absentmsg
[] =
2425 "The server's host key is not cached in the registry. You\n"
2426 "have no guarantee that the server is the computer you\n"
2428 "The server's key fingerprint is:\n"
2430 "If you trust this host, hit Yes to add the key to\n"
2431 "PuTTY's cache and carry on connecting.\n"
2432 "If you do not trust this host, hit No to abandon the\n"
2435 static const char wrongmsg
[] =
2436 "WARNING - POTENTIAL SECURITY BREACH!\n"
2438 "The server's host key does not match the one PuTTY has\n"
2439 "cached in the registry. This means that either the\n"
2440 "server administrator has changed the host key, or you\n"
2441 "have actually connected to another computer pretending\n"
2442 "to be the server.\n"
2443 "The new key fingerprint is:\n"
2445 "If you were expecting this change and trust the new key,\n"
2446 "hit Yes to update PuTTY's cache and continue connecting.\n"
2447 "If you want to carry on connecting but without updating\n"
2448 "the cache, hit No.\n"
2449 "If you want to abandon the connection completely, hit\n"
2450 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2452 static const char mbtitle
[] = "PuTTY Security Alert";
2456 /* sensible fingerprint max size */
2457 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
2458 sizeof(absentmsg
) : sizeof(wrongmsg
))];
2461 * Verify the key against the registry.
2463 ret
= verify_host_key(host
, port
, keytype
, keystr
);
2465 if (ret
== 0) /* success - key matched OK */
2467 if (ret
== 2) { /* key was different */
2469 sprintf(message
, wrongmsg
, fingerprint
);
2470 mbret
= MessageBox(NULL
, message
, mbtitle
,
2471 MB_ICONWARNING
| MB_YESNOCANCEL
);
2473 store_host_key(host
, port
, keytype
, keystr
);
2474 if (mbret
== IDCANCEL
)
2477 if (ret
== 1) { /* key was absent */
2479 sprintf(message
, absentmsg
, fingerprint
);
2480 mbret
= MessageBox(NULL
, message
, mbtitle
,
2481 MB_ICONWARNING
| MB_YESNO
);
2484 store_host_key(host
, port
, keytype
, keystr
);
2489 * Ask whether to wipe a session log file before writing to it.
2490 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2492 int askappend(char *filename
)
2494 static const char mbtitle
[] = "PuTTY Log to File";
2495 static const char msgtemplate
[] =
2496 "The session log file \"%.*s\" already exists.\n"
2497 "You can overwrite it with a new session log,\n"
2498 "append your session log to the end of it,\n"
2499 "or disable session logging for this session.\n"
2500 "Hit Yes to wipe the file, No to append to it,\n"
2501 "or Cancel to disable logging.";
2502 char message
[sizeof(msgtemplate
) + FILENAME_MAX
];
2504 if (cfg
.logxfovr
!= LGXF_ASK
) {
2505 return ((cfg
.logxfovr
== LGXF_OVR
) ?
2 : 1);
2507 sprintf(message
, msgtemplate
, FILENAME_MAX
, filename
);
2509 mbret
= MessageBox(NULL
, message
, mbtitle
,
2510 MB_ICONQUESTION
| MB_YESNOCANCEL
);
2513 else if (mbret
== IDNO
)