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
,
484 translationpanelstart
,
485 IDC_TITLE_TRANSLATION
,
486 IDC_BOX_TRANSLATION1
,
487 IDC_BOX_TRANSLATION2
,
488 IDC_BOX_TRANSLATION3
,
513 static const char *const colours
[] = {
514 "Default Foreground", "Default Bold Foreground",
515 "Default Background", "Default Bold Background",
516 "Cursor Text", "Cursor Colour",
517 "ANSI Black", "ANSI Black Bold",
518 "ANSI Red", "ANSI Red Bold",
519 "ANSI Green", "ANSI Green Bold",
520 "ANSI Yellow", "ANSI Yellow Bold",
521 "ANSI Blue", "ANSI Blue Bold",
522 "ANSI Magenta", "ANSI Magenta Bold",
523 "ANSI Cyan", "ANSI Cyan Bold",
524 "ANSI White", "ANSI White Bold"
526 static const int permcolour
[] = {
527 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
528 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
529 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
532 static void fmtfont(char *buf
)
534 sprintf(buf
, "Font: %s, ", cfg
.font
);
536 strcat(buf
, "bold, ");
537 if (cfg
.fontheight
== 0)
538 strcat(buf
, "default height");
540 sprintf(buf
+ strlen(buf
), "%d-point",
541 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
));
544 static void init_dlg_ctrls(HWND hwnd
)
547 char fontstatic
[256];
549 SetDlgItemText(hwnd
, IDC_HOST
, cfg
.host
);
550 SetDlgItemText(hwnd
, IDC_SESSEDIT
, savedsession
);
553 n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_GETCOUNT
, 0, 0);
554 for (i
= n
; i
-- > 0;)
555 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_DELETESTRING
, i
, 0);
556 for (i
= 0; i
< nsessions
; i
++)
557 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
558 0, (LPARAM
) (sessions
[i
]));
560 SetDlgItemInt(hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
561 CheckRadioButton(hwnd
, IDC_PROTRAW
, IDC_PROTSSH
,
562 cfg
.protocol
== PROT_SSH ? IDC_PROTSSH
:
563 cfg
.protocol
== PROT_TELNET ? IDC_PROTTELNET
:
565 PROT_RLOGIN ? IDC_PROTRLOGIN
: IDC_PROTRAW
);
566 SetDlgItemInt(hwnd
, IDC_PINGEDIT
, cfg
.ping_interval
, FALSE
);
568 CheckRadioButton(hwnd
, IDC_DEL008
, IDC_DEL127
,
569 cfg
.bksp_is_delete ? IDC_DEL127
: IDC_DEL008
);
570 CheckRadioButton(hwnd
, IDC_HOMETILDE
, IDC_HOMERXVT
,
571 cfg
.rxvt_homeend ? IDC_HOMERXVT
: IDC_HOMETILDE
);
572 CheckRadioButton(hwnd
, IDC_FUNCTILDE
, IDC_FUNCSCO
,
573 cfg
.funky_type
== 0 ? IDC_FUNCTILDE
:
574 cfg
.funky_type
== 1 ? IDC_FUNCLINUX
:
575 cfg
.funky_type
== 2 ? IDC_FUNCXTERM
:
576 cfg
.funky_type
== 3 ? IDC_FUNCVT400
:
577 cfg
.funky_type
== 4 ? IDC_FUNCVT100P
:
578 cfg
.funky_type
== 5 ? IDC_FUNCSCO
: IDC_FUNCTILDE
);
579 CheckDlgButton(hwnd
, IDC_NOAPPLICC
, cfg
.no_applic_c
);
580 CheckDlgButton(hwnd
, IDC_NOAPPLICK
, cfg
.no_applic_k
);
581 CheckRadioButton(hwnd
, IDC_CURNORMAL
, IDC_CURAPPLIC
,
582 cfg
.app_cursor ? IDC_CURAPPLIC
: IDC_CURNORMAL
);
583 CheckRadioButton(hwnd
, IDC_KPNORMAL
, IDC_KPNH
,
584 cfg
.nethack_keypad ? IDC_KPNH
:
585 cfg
.app_keypad ? IDC_KPAPPLIC
: IDC_KPNORMAL
);
586 CheckDlgButton(hwnd
, IDC_ALTF4
, cfg
.alt_f4
);
587 CheckDlgButton(hwnd
, IDC_ALTSPACE
, cfg
.alt_space
);
588 CheckDlgButton(hwnd
, IDC_ALTONLY
, cfg
.alt_only
);
589 CheckDlgButton(hwnd
, IDC_COMPOSEKEY
, cfg
.compose_key
);
590 CheckDlgButton(hwnd
, IDC_CTRLALTKEYS
, cfg
.ctrlaltkeys
);
591 CheckRadioButton(hwnd
, IDC_ECHOBACKEND
, IDC_ECHONO
,
592 cfg
.localecho
== LD_BACKEND ? IDC_ECHOBACKEND
:
593 cfg
.localecho
== LD_YES ? IDC_ECHOYES
: IDC_ECHONO
);
594 CheckRadioButton(hwnd
, IDC_EDITBACKEND
, IDC_EDITNO
,
595 cfg
.localedit
== LD_BACKEND ? IDC_EDITBACKEND
:
596 cfg
.localedit
== LD_YES ? IDC_EDITYES
: IDC_EDITNO
);
597 SetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
);
598 CheckDlgButton(hwnd
, IDC_ALWAYSONTOP
, cfg
.alwaysontop
);
599 CheckDlgButton(hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
600 CheckDlgButton(hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
602 CheckDlgButton(hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
603 CheckDlgButton(hwnd
, IDC_DECOM
, cfg
.dec_om
);
604 CheckDlgButton(hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
605 SetDlgItemInt(hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
606 SetDlgItemInt(hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
607 SetDlgItemInt(hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
609 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
610 CheckRadioButton(hwnd
, IDC_BELL_DISABLED
, IDC_BELL_VISUAL
,
611 cfg
.beep
== BELL_DISABLED ? IDC_BELL_DISABLED
:
612 cfg
.beep
== BELL_DEFAULT ? IDC_BELL_DEFAULT
:
613 cfg
.beep
== BELL_WAVEFILE ? IDC_BELL_WAVEFILE
:
615 BELL_VISUAL ? IDC_BELL_VISUAL
: IDC_BELL_DEFAULT
);
616 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
, cfg
.bell_wavefile
);
617 CheckDlgButton(hwnd
, IDC_BELLOVL
, cfg
.bellovl
);
618 SetDlgItemInt(hwnd
, IDC_BELLOVLN
, cfg
.bellovl_n
, FALSE
);
619 MySetDlgItemFlt(hwnd
, IDC_BELLOVLT
, cfg
.bellovl_t
/ 1000.0);
620 MySetDlgItemFlt(hwnd
, IDC_BELLOVLS
, cfg
.bellovl_s
/ 1000.0);
622 CheckDlgButton(hwnd
, IDC_BCE
, cfg
.bce
);
623 CheckDlgButton(hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
625 SetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
626 CheckDlgButton(hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
627 CheckDlgButton(hwnd
, IDC_HIDEMOUSE
, cfg
.hide_mouseptr
);
628 CheckDlgButton(hwnd
, IDC_SUNKENEDGE
, cfg
.sunken_edge
);
629 CheckRadioButton(hwnd
, IDC_CURBLOCK
, IDC_CURVERT
,
630 cfg
.cursor_type
== 0 ? IDC_CURBLOCK
:
631 cfg
.cursor_type
== 1 ? IDC_CURUNDER
: IDC_CURVERT
);
632 CheckDlgButton(hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
633 CheckDlgButton(hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
634 CheckDlgButton(hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
635 CheckRadioButton(hwnd
, IDC_COEALWAYS
, IDC_COENORMAL
,
636 cfg
.close_on_exit
== COE_NORMAL ? IDC_COENORMAL
:
638 COE_NEVER ? IDC_COENEVER
: IDC_COEALWAYS
);
639 CheckDlgButton(hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
641 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
642 SetDlgItemText(hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
643 SetDlgItemText(hwnd
, IDC_R_TSEDIT
, cfg
.termspeed
);
644 SetDlgItemText(hwnd
, IDC_RLLUSEREDIT
, cfg
.localusername
);
645 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
646 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
647 CheckRadioButton(hwnd
, IDC_LSTATOFF
, IDC_LSTATRAW
,
648 cfg
.logtype
== 0 ? IDC_LSTATOFF
:
649 cfg
.logtype
== 1 ? IDC_LSTATASCII
: IDC_LSTATRAW
);
650 CheckRadioButton(hwnd
, IDC_LSTATXOVR
, IDC_LSTATXASK
,
651 cfg
.logxfovr
== LGXF_OVR ? IDC_LSTATXOVR
:
652 cfg
.logxfovr
== LGXF_ASK ? IDC_LSTATXASK
:
655 char *p
= cfg
.environmt
;
657 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
662 CheckRadioButton(hwnd
, IDC_EMBSD
, IDC_EMRFC
,
663 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
664 CheckRadioButton(hwnd
, IDC_TPASSIVE
, IDC_TACTIVE
,
665 cfg
.passive_telnet ? IDC_TPASSIVE
: IDC_TACTIVE
);
667 SetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
);
668 SetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
);
669 CheckDlgButton(hwnd
, IDC_NOPTY
, cfg
.nopty
);
670 CheckDlgButton(hwnd
, IDC_COMPRESS
, cfg
.compression
);
671 CheckDlgButton(hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
672 CheckDlgButton(hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
673 CheckRadioButton(hwnd
, IDC_CIPHER3DES
, IDC_CIPHERAES
,
674 cfg
.cipher
== CIPHER_BLOWFISH ? IDC_CIPHERBLOWF
:
675 cfg
.cipher
== CIPHER_DES ? IDC_CIPHERDES
:
676 cfg
.cipher
== CIPHER_AES ? IDC_CIPHERAES
:
678 CheckRadioButton(hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
679 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
680 CheckDlgButton(hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
681 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
682 SetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
684 CheckRadioButton(hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
685 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
686 CheckDlgButton(hwnd
, IDC_RAWCNP
, cfg
.rawcnp
);
688 static int tabs
[4] = { 25, 61, 96, 128 };
689 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
692 for (i
= 0; i
< 256; i
++) {
694 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
695 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ', cfg
.wordness
[i
]);
696 SendDlgItemMessage(hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
700 CheckDlgButton(hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
701 CheckDlgButton(hwnd
, IDC_PALETTE
, cfg
.try_palette
);
704 n
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
705 for (i
= n
; i
-- > 0;)
706 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
707 LB_DELETESTRING
, i
, 0);
708 for (i
= 0; i
< 22; i
++)
709 if (cfg
.bold_colour
|| permcolour
[i
])
710 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
711 (LPARAM
) colours
[i
]);
713 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
714 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
715 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
716 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
718 CheckRadioButton(hwnd
, IDC_NOXLAT
, IDC_88592CP852
,
719 cfg
.xlat_88592w1250 ? IDC_88592WIN1250
:
720 cfg
.xlat_88592cp852 ? IDC_88592CP852
:
721 cfg
.xlat_enablekoiwin ? IDC_KOI8WIN1251
: IDC_NOXLAT
);
722 CheckDlgButton(hwnd
, IDC_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
723 CheckRadioButton(hwnd
, IDC_VTXWINDOWS
, IDC_VTPOORMAN
,
724 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
725 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
726 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
729 CheckDlgButton(hwnd
, IDC_X11_FORWARD
, cfg
.x11_forward
);
730 SetDlgItemText(hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
);
733 struct treeview_faff
{
738 static HTREEITEM
treeview_insert(struct treeview_faff
*faff
,
739 int level
, char *text
)
744 ins
.hParent
= (level
> 0 ? faff
->lastat
[level
- 1] : TVI_ROOT
);
745 ins
.hInsertAfter
= faff
->lastat
[level
];
746 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
747 #define INSITEM DUMMYUNIONNAME.item
751 ins
.INSITEM
.mask
= TVIF_TEXT
;
752 ins
.INSITEM
.pszText
= text
;
753 newitem
= TreeView_InsertItem(faff
->treeview
, &ins
);
755 TreeView_Expand(faff
->treeview
, faff
->lastat
[level
- 1],
757 faff
->lastat
[level
] = newitem
;
758 for (i
= level
+ 1; i
< 4; i
++)
759 faff
->lastat
[i
] = NULL
;
764 * Create the panelfuls of controls in the configuration box.
766 static void create_controls(HWND hwnd
, int dlgtype
, int panel
)
768 if (panel
== sessionpanelstart
) {
769 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
771 ctlposinit(&cp
, hwnd
, 80, 3, 13);
772 bartitle(&cp
, "Basic options for your PuTTY session",
775 beginbox(&cp
, "Specify your connection by host name",
778 "Host &Name", IDC_HOSTSTATIC
, IDC_HOST
, 75,
779 "&Port", IDC_PORTSTATIC
, IDC_PORT
, 25, NULL
);
780 if (backends
[3].backend
== NULL
) {
781 /* this is PuTTYtel, so only three protocols available */
782 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 4,
784 "&Telnet", IDC_PROTTELNET
,
785 "Rlog&in", IDC_PROTRLOGIN
, NULL
);
787 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 4,
789 "&Telnet", IDC_PROTTELNET
,
790 "Rlog&in", IDC_PROTRLOGIN
,
799 beginbox(&cp
, "Load, save or delete a stored session",
801 sesssaver(&cp
, "Sav&ed Sessions",
802 IDC_SESSSTATIC
, IDC_SESSEDIT
, IDC_SESSLIST
,
803 "&Load", IDC_SESSLOAD
,
804 "&Save", IDC_SESSSAVE
, "&Delete", IDC_SESSDEL
, NULL
);
807 beginbox(&cp
, NULL
, IDC_BOX_SESSION3
);
808 radioline(&cp
, "Close &window on exit:", IDC_CLOSEEXIT
, 4,
809 "Always", IDC_COEALWAYS
,
810 "Never", IDC_COENEVER
,
811 "Only on clean exit", IDC_COENORMAL
, NULL
);
815 if (panel
== loggingpanelstart
) {
816 /* The Logging panel. Accelerators used: [acgo] tplfwe */
818 ctlposinit(&cp
, hwnd
, 80, 3, 13);
819 bartitle(&cp
, "Options controlling session logging",
821 beginbox(&cp
, NULL
, IDC_BOX_LOGGING1
);
823 "Session logging:", IDC_LSTATSTATIC
,
824 "Logging &turned off completely", IDC_LSTATOFF
,
825 "Log &printable output only", IDC_LSTATASCII
,
826 "&Log all session output", IDC_LSTATRAW
, NULL
);
827 editbutton(&cp
, "Log &file name:",
828 IDC_LGFSTATIC
, IDC_LGFEDIT
, "Bro&wse...",
831 "What to do if the log file already &exists:",
832 IDC_LSTATXIST
, "Always overwrite it", IDC_LSTATXOVR
,
833 "Always append to the end of it", IDC_LSTATXAPN
,
834 "Ask the user every time", IDC_LSTATXASK
, NULL
);
838 if (panel
== terminalpanelstart
) {
839 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
841 ctlposinit(&cp
, hwnd
, 80, 3, 13);
842 bartitle(&cp
, "Options controlling the terminal emulation",
844 beginbox(&cp
, "Set various terminal options", IDC_BOX_TERMINAL1
);
845 checkbox(&cp
, "Auto &wrap mode initially on", IDC_WRAPMODE
);
846 checkbox(&cp
, "&DEC Origin Mode initially on", IDC_DECOM
);
847 checkbox(&cp
, "Implicit CR in every &LF", IDC_LFHASCR
);
848 checkbox(&cp
, "Use background colour to &erase screen", IDC_BCE
);
849 checkbox(&cp
, "Enable bli&nking text", IDC_BLINKTEXT
);
851 "An&swerback to ^E:", IDC_ANSWERBACK
,
852 IDC_ANSWEREDIT
, 100, NULL
);
855 beginbox(&cp
, "Line discipline options", IDC_BOX_TERMINAL2
);
856 radioline(&cp
, "Local ec&ho:", IDC_ECHOSTATIC
, 3,
857 "Auto", IDC_ECHOBACKEND
,
858 "Force on", IDC_ECHOYES
, "Force off", IDC_ECHONO
, NULL
);
859 radioline(&cp
, "Local line edi&ting:", IDC_EDITSTATIC
, 3,
860 "Auto", IDC_EDITBACKEND
,
861 "Force on", IDC_EDITYES
, "Force off", IDC_EDITNO
, NULL
);
865 if (panel
== bellpanelstart
) {
866 /* The Bell panel. Accelerators used: [acgo] bdsm wt */
868 ctlposinit(&cp
, hwnd
, 80, 3, 13);
869 bartitle(&cp
, "Options controlling the terminal bell",
871 beginbox(&cp
, "Set the style of bell", IDC_BOX_BELL1
);
873 "Action to happen when a &bell occurs:", IDC_BELLSTATIC
,
874 "None (bell disabled)", IDC_BELL_DISABLED
,
875 "Play Windows Default Sound", IDC_BELL_DEFAULT
,
876 "Play a custom sound file", IDC_BELL_WAVEFILE
,
877 "Visual bell (flash window)", IDC_BELL_VISUAL
, NULL
);
878 editbutton(&cp
, "Custom sound file to play as a bell:",
879 IDC_BELL_WAVESTATIC
, IDC_BELL_WAVEEDIT
,
880 "Bro&wse...", IDC_BELL_WAVEBROWSE
);
882 beginbox(&cp
, "Control the bell overload behaviour",
884 checkbox(&cp
, "Bell is temporarily &disabled when over-used",
886 staticedit(&cp
, "Over-use means this &many bells...",
887 IDC_BELLOVLNSTATIC
, IDC_BELLOVLN
, 20);
888 staticedit(&cp
, "... in &this many seconds",
889 IDC_BELLOVLTSTATIC
, IDC_BELLOVLT
, 20);
891 "The bell is re-enabled after a few seconds of silence.",
893 staticedit(&cp
, "Seconds of &silence required", IDC_BELLOVLSSTATIC
,
898 if (panel
== keyboardpanelstart
) {
899 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
901 ctlposinit(&cp
, hwnd
, 80, 3, 13);
903 bartitle(&cp, "Options controlling the effects of keys",
906 beginbox(&cp
, "Change the sequences sent by:", IDC_BOX_KEYBOARD1
);
907 radioline(&cp
, "The &Backspace key", IDC_DELSTATIC
, 2,
908 "Control-H", IDC_DEL008
,
909 "Control-? (127)", IDC_DEL127
, NULL
);
910 radioline(&cp
, "The &Home and End keys", IDC_HOMESTATIC
, 2,
911 "Standard", IDC_HOMETILDE
, "rxvt", IDC_HOMERXVT
, NULL
);
912 radioline(&cp
, "The &Function keys and keypad", IDC_FUNCSTATIC
, 3,
913 "ESC[n~", IDC_FUNCTILDE
,
914 "Linux", IDC_FUNCLINUX
,
915 "Xterm R6", IDC_FUNCXTERM
,
916 "VT400", IDC_FUNCVT400
,
917 "VT100+", IDC_FUNCVT100P
, "SCO", IDC_FUNCSCO
, NULL
);
919 beginbox(&cp
, "Application keypad settings:", IDC_BOX_KEYBOARD2
);
921 "Application c&ursor keys totally disabled",
923 radioline(&cp
, "Initial state of cu&rsor keys:", IDC_CURSTATIC
, 2,
924 "Normal", IDC_CURNORMAL
,
925 "Application", IDC_CURAPPLIC
, NULL
);
927 "Application ke&ypad keys totally disabled",
929 radioline(&cp
, "Initial state of &numeric keypad:", IDC_KPSTATIC
,
930 3, "Normal", IDC_KPNORMAL
, "Application", IDC_KPAPPLIC
,
931 "NetHack", IDC_KPNH
, NULL
);
933 beginbox(&cp
, "Enable extra keyboard features:",
935 checkbox(&cp
, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY
);
936 checkbox(&cp
, "Control-Alt is &different from AltGr",
941 if (panel
== windowpanelstart
) {
942 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
944 ctlposinit(&cp
, hwnd
, 80, 3, 13);
945 bartitle(&cp
, "Options controlling PuTTY's window",
947 beginbox(&cp
, "Set the size of the window", IDC_BOX_WINDOW1
);
949 "&Rows", IDC_ROWSSTATIC
, IDC_ROWSEDIT
, 50,
950 "Colu&mns", IDC_COLSSTATIC
, IDC_COLSEDIT
, 50, NULL
);
951 checkbox(&cp
, "Lock window size against resi&zing", IDC_LOCKSIZE
);
953 beginbox(&cp
, "Control the scrollback in the window",
955 staticedit(&cp
, "Lines of &scrollback",
956 IDC_SAVESTATIC
, IDC_SAVEEDIT
, 50);
957 checkbox(&cp
, "&Display scrollbar", IDC_SCROLLBAR
);
958 checkbox(&cp
, "Reset scrollback on &keypress", IDC_SCROLLKEY
);
959 checkbox(&cp
, "Reset scrollback on dis&play activity",
962 beginbox(&cp
, NULL
, IDC_BOX_WINDOW3
);
963 checkbox(&cp
, "&Warn before closing window", IDC_CLOSEWARN
);
964 checkbox(&cp
, "Window closes on ALT-F&4", IDC_ALTF4
);
965 checkbox(&cp
, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE
);
966 checkbox(&cp
, "System menu appears on A< alone", IDC_ALTONLY
);
967 checkbox(&cp
, "Ensure window is always on &top", IDC_ALWAYSONTOP
);
971 if (panel
== appearancepanelstart
) {
972 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
974 ctlposinit(&cp
, hwnd
, 80, 3, 13);
975 bartitle(&cp
, "Options controlling PuTTY's appearance",
976 IDC_TITLE_APPEARANCE
);
977 beginbox(&cp
, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1
);
978 radioline(&cp
, "Cursor appearance:", IDC_CURSORSTATIC
, 3,
979 "B&lock", IDC_CURBLOCK
,
980 "&Underline", IDC_CURUNDER
,
981 "&Vertical line", IDC_CURVERT
, NULL
);
982 checkbox(&cp
, "Cursor &blinks", IDC_BLINKCUR
);
984 beginbox(&cp
, "Set the font used in the terminal window",
985 IDC_BOX_APPEARANCE2
);
986 staticbtn(&cp
, "", IDC_FONTSTATIC
, "C&hange...", IDC_CHOOSEFONT
);
988 beginbox(&cp
, "Adjust the use of the window title",
989 IDC_BOX_APPEARANCE3
);
991 "Window &title:", IDC_WINTITLE
, IDC_WINEDIT
, 100, NULL
);
992 checkbox(&cp
, "Avoid ever using &icon title", IDC_WINNAME
);
994 beginbox(&cp
, "Adjust the use of the mouse pointer",
995 IDC_BOX_APPEARANCE4
);
996 checkbox(&cp
, "Hide mouse &pointer when typing in window",
999 beginbox(&cp
, "Adjust the window border", IDC_BOX_APPEARANCE5
);
1000 checkbox(&cp
, "&Sunken-edge border (slightly thicker)",
1005 if (panel
== translationpanelstart
) {
1006 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1008 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1009 bartitle(&cp
, "Options controlling character set translation",
1010 IDC_TITLE_TRANSLATION
);
1011 beginbox(&cp
, "Adjust how PuTTY displays line drawing characters",
1012 IDC_BOX_TRANSLATION1
);
1014 "Handling of line drawing characters:", IDC_VTSTATIC
,
1015 "Font has &XWindows encoding", IDC_VTXWINDOWS
,
1016 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI
,
1017 "Use font in O&EM mode only", IDC_VTOEMONLY
,
1018 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1019 IDC_VTPOORMAN
, NULL
);
1021 beginbox(&cp
, "Enable character set translation on received data",
1022 IDC_BOX_TRANSLATION2
);
1024 "Character set &translation:", IDC_XLATSTATIC
,
1026 "KOI8 / Win-1251", IDC_KOI8WIN1251
,
1027 "ISO-8859-2 / Win-1250", IDC_88592WIN1250
,
1028 "ISO-8859-2 / CP852", IDC_88592CP852
, NULL
);
1030 beginbox(&cp
, "Enable character set translation on input data",
1031 IDC_BOX_TRANSLATION3
);
1032 checkbox(&cp
, "CAP&S LOCK acts as cyrillic switch",
1037 if (panel
== selectionpanelstart
) {
1038 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1040 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1041 bartitle(&cp
, "Options controlling copy and paste",
1042 IDC_TITLE_SELECTION
);
1043 beginbox(&cp
, "Translation of pasted characters",
1044 IDC_BOX_SELECTION1
);
1046 "&Don't translate line drawing chars into +, - and |",
1049 beginbox(&cp
, "Control which mouse button does which thing",
1050 IDC_BOX_SELECTION2
);
1051 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
1052 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
1053 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
1056 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
1057 IDC_BOX_SELECTION3
);
1058 charclass(&cp
, "C&haracter classes:", IDC_CCSTATIC
, IDC_CCLIST
,
1059 "&Set", IDC_CCSET
, IDC_CCEDIT
,
1060 "&to class", IDC_CCSTATIC2
);
1064 if (panel
== colourspanelstart
) {
1065 /* The Colours panel. Accelerators used: [acgo] blum */
1067 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1068 bartitle(&cp
, "Options controlling use of colours",
1070 beginbox(&cp
, "General options for colour usage",
1072 checkbox(&cp
, "&Bolded text is a different colour",
1074 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
1076 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
1078 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
1079 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
1080 "&Modify...", IDC_CHANGE
,
1081 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
1082 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
1083 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
1087 if (panel
== connectionpanelstart
) {
1088 /* The Connection panel. Accelerators used: [acgo] tuk */
1090 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1091 bartitle(&cp
, "Options controlling the connection",
1092 IDC_TITLE_CONNECTION
);
1094 beginbox(&cp
, "Data to send to the server",
1095 IDC_BOX_CONNECTION1
);
1096 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
,
1098 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
,
1102 beginbox(&cp
, "Sending of null packets to keep session active",
1103 IDC_BOX_CONNECTION2
);
1104 staticedit(&cp
, "Seconds between &keepalives (0 to turn off)",
1105 IDC_PINGSTATIC
, IDC_PINGEDIT
, 20);
1109 if (panel
== telnetpanelstart
) {
1110 /* The Telnet panel. Accelerators used: [acgo] svldr bft */
1112 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1114 bartitle(&cp
, "Options controlling Telnet connections",
1116 beginbox(&cp
, "Data to send to the server", IDC_BOX_TELNET1
);
1117 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
,
1119 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
1120 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
, "Va&lue",
1121 IDC_VALSTATIC
, IDC_VALEDIT
, IDC_ENVLIST
, "A&dd",
1122 IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
1124 beginbox(&cp
, "Telnet protocol adjustments", IDC_BOX_TELNET2
);
1125 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:",
1126 IDC_EMSTATIC
, 2, "&BSD (commonplace)", IDC_EMBSD
,
1127 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
1128 radioline(&cp
, "&Telnet negotiation mode:", IDC_ACTSTATIC
, 2,
1129 "Passive", IDC_TPASSIVE
, "Active",
1135 if (panel
== rloginpanelstart
) {
1136 /* The Rlogin panel. Accelerators used: [acgo] sl */
1138 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1140 bartitle(&cp
, "Options controlling Rlogin connections",
1142 beginbox(&cp
, "Data to send to the server", IDC_BOX_RLOGIN1
);
1143 staticedit(&cp
, "Terminal-&speed string", IDC_R_TSSTATIC
,
1145 staticedit(&cp
, "&Local username:", IDC_RLLUSERSTATIC
,
1146 IDC_RLLUSEREDIT
, 50);
1151 if (panel
== sshpanelstart
) {
1152 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1154 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1156 bartitle(&cp
, "Options controlling SSH connections",
1158 beginbox(&cp
, "Data to send to the server", IDC_BOX_SSH1
);
1160 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
1163 beginbox(&cp
, "Authentication options", IDC_BOX_SSH2
);
1164 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
1166 checkbox(&cp
, "Allow agent &forwarding", IDC_AGENTFWD
);
1167 editbutton(&cp
, "Private &key file for authentication:",
1168 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...",
1171 beginbox(&cp
, "Protocol options", IDC_BOX_SSH3
);
1172 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
1173 checkbox(&cp
, "Enable compr&ession", IDC_COMPRESS
);
1174 radioline(&cp
, "Preferred SSH protocol version:",
1175 IDC_SSHPROTSTATIC
, 2,
1176 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
1177 radioline(&cp
, "Preferred encryption algorithm:",
1178 IDC_CIPHERSTATIC
, 4, "&3DES", IDC_CIPHER3DES
,
1179 "&Blowfish", IDC_CIPHERBLOWF
, "&DES", IDC_CIPHERDES
,
1180 "AE&S", IDC_CIPHERAES
, NULL
);
1181 checkbox(&cp
, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1187 if (panel
== tunnelspanelstart
) {
1188 /* The Tunnels panel. Accelerators used: [acgo] ex */
1190 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1192 bartitle(&cp
, "Options controlling SSH tunnelling",
1194 beginbox(&cp
, "X11 forwarding options", IDC_BOX_TUNNELS
);
1195 checkbox(&cp
, "&Enable X11 forwarding", IDC_X11_FORWARD
);
1196 multiedit(&cp
, "&X display location", IDC_X11_DISPSTATIC
,
1197 IDC_X11_DISPLAY
, 50, NULL
);
1204 * This function is the configuration box.
1206 static int GenericMainDlgProc(HWND hwnd
, UINT msg
,
1207 WPARAM wParam
, LPARAM lParam
, int dlgtype
)
1210 struct treeview_faff tvfaff
;
1213 char filename
[sizeof(cfg
.keyfile
)];
1216 char fontstatic
[256];
1218 struct servent
*service
;
1224 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1226 * Centre the window.
1228 { /* centre the window */
1231 hw
= GetDesktopWindow();
1232 if (GetWindowRect(hw
, &rs
) && GetWindowRect(hwnd
, &rd
))
1234 (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
) / 2,
1235 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
) / 2,
1236 rd
.right
- rd
.left
, rd
.bottom
- rd
.top
, TRUE
);
1240 * Create the tree view.
1248 r
.right
= r
.left
+ 75;
1250 r
.bottom
= r
.top
+ 10;
1251 MapDialogRect(hwnd
, &r
);
1252 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
1253 WS_CHILD
| WS_VISIBLE
,
1255 r
.right
- r
.left
, r
.bottom
- r
.top
,
1256 hwnd
, (HMENU
) IDCX_TVSTATIC
, hinst
,
1258 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1259 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1262 r
.right
= r
.left
+ 75;
1264 r
.bottom
= r
.top
+ 206;
1265 MapDialogRect(hwnd
, &r
);
1266 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
1267 WS_CHILD
| WS_VISIBLE
|
1268 WS_TABSTOP
| TVS_HASLINES
|
1269 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
1271 TVS_SHOWSELALWAYS
, r
.left
, r
.top
,
1272 r
.right
- r
.left
, r
.bottom
- r
.top
,
1273 hwnd
, (HMENU
) IDCX_TREEVIEW
, hinst
,
1275 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1276 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1277 tvfaff
.treeview
= treeview
;
1278 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
1282 * Set up the tree view contents.
1284 hsession
= treeview_insert(&tvfaff
, 0, "Session");
1285 treeview_insert(&tvfaff
, 1, "Logging");
1286 treeview_insert(&tvfaff
, 0, "Terminal");
1287 treeview_insert(&tvfaff
, 1, "Keyboard");
1288 treeview_insert(&tvfaff
, 1, "Bell");
1289 treeview_insert(&tvfaff
, 0, "Window");
1290 treeview_insert(&tvfaff
, 1, "Appearance");
1291 treeview_insert(&tvfaff
, 1, "Translation");
1292 treeview_insert(&tvfaff
, 1, "Selection");
1293 treeview_insert(&tvfaff
, 1, "Colours");
1294 treeview_insert(&tvfaff
, 0, "Connection");
1296 treeview_insert(&tvfaff
, 1, "Telnet");
1297 treeview_insert(&tvfaff
, 1, "Rlogin");
1298 if (backends
[3].backend
!= NULL
) {
1299 treeview_insert(&tvfaff
, 1, "SSH");
1300 treeview_insert(&tvfaff
, 2, "Tunnels");
1305 * Put the treeview selection on to the Session panel. This
1306 * should also cause creation of the relevant controls.
1308 TreeView_SelectItem(treeview
, hsession
);
1311 * Set focus into the first available control.
1315 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
1317 ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
1321 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1325 * Button release should trigger WM_OK if there was a
1326 * previous double click on the session list.
1330 SendMessage(hwnd
, WM_COMMAND
, IDOK
, 0);
1333 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1334 ((LPNMHDR
) lParam
)->code
== TVN_SELCHANGED
) {
1336 TreeView_GetSelection(((LPNMHDR
) lParam
)->hwndFrom
);
1341 item
.pszText
= buffer
;
1342 item
.cchTextMax
= sizeof(buffer
);
1343 item
.mask
= TVIF_TEXT
;
1344 TreeView_GetItem(((LPNMHDR
) lParam
)->hwndFrom
, &item
);
1345 for (j
= controlstartvalue
; j
< controlendvalue
; j
++) {
1346 HWND item
= GetDlgItem(hwnd
, j
);
1348 DestroyWindow(item
);
1350 if (!strcmp(buffer
, "Session"))
1351 create_controls(hwnd
, dlgtype
, sessionpanelstart
);
1352 if (!strcmp(buffer
, "Logging"))
1353 create_controls(hwnd
, dlgtype
, loggingpanelstart
);
1354 if (!strcmp(buffer
, "Keyboard"))
1355 create_controls(hwnd
, dlgtype
, keyboardpanelstart
);
1356 if (!strcmp(buffer
, "Terminal"))
1357 create_controls(hwnd
, dlgtype
, terminalpanelstart
);
1358 if (!strcmp(buffer
, "Bell"))
1359 create_controls(hwnd
, dlgtype
, bellpanelstart
);
1360 if (!strcmp(buffer
, "Window"))
1361 create_controls(hwnd
, dlgtype
, windowpanelstart
);
1362 if (!strcmp(buffer
, "Appearance"))
1363 create_controls(hwnd
, dlgtype
, appearancepanelstart
);
1364 if (!strcmp(buffer
, "Tunnels"))
1365 create_controls(hwnd
, dlgtype
, tunnelspanelstart
);
1366 if (!strcmp(buffer
, "Connection"))
1367 create_controls(hwnd
, dlgtype
, connectionpanelstart
);
1368 if (!strcmp(buffer
, "Telnet"))
1369 create_controls(hwnd
, dlgtype
, telnetpanelstart
);
1370 if (!strcmp(buffer
, "Rlogin"))
1371 create_controls(hwnd
, dlgtype
, rloginpanelstart
);
1372 if (!strcmp(buffer
, "SSH"))
1373 create_controls(hwnd
, dlgtype
, sshpanelstart
);
1374 if (!strcmp(buffer
, "Selection"))
1375 create_controls(hwnd
, dlgtype
, selectionpanelstart
);
1376 if (!strcmp(buffer
, "Colours"))
1377 create_controls(hwnd
, dlgtype
, colourspanelstart
);
1378 if (!strcmp(buffer
, "Translation"))
1379 create_controls(hwnd
, dlgtype
, translationpanelstart
);
1381 init_dlg_ctrls(hwnd
);
1383 SetFocus(((LPNMHDR
) lParam
)->hwndFrom
); /* ensure focus stays */
1389 * Only process WM_COMMAND once the dialog is fully formed.
1391 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1)
1392 switch (LOWORD(wParam
)) {
1402 case IDC_PROTTELNET
:
1403 case IDC_PROTRLOGIN
:
1406 if (HIWORD(wParam
) == BN_CLICKED
||
1407 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1408 int i
= IsDlgButtonChecked(hwnd
, IDC_PROTSSH
);
1409 int j
= IsDlgButtonChecked(hwnd
, IDC_PROTTELNET
);
1410 int k
= IsDlgButtonChecked(hwnd
, IDC_PROTRLOGIN
);
1412 i ? PROT_SSH
: j ? PROT_TELNET
: k ? PROT_RLOGIN
:
1414 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
!= 22)
1415 || (cfg
.protocol
== PROT_TELNET
&& cfg
.port
!= 23)
1416 || (cfg
.protocol
== PROT_RLOGIN
1417 && cfg
.port
!= 513)) {
1418 cfg
.port
= i ?
22 : j ?
23 : 513;
1419 SetDlgItemInt(hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1424 if (HIWORD(wParam
) == EN_CHANGE
)
1425 GetDlgItemText(hwnd
, IDC_HOST
, cfg
.host
,
1426 sizeof(cfg
.host
) - 1);
1429 if (HIWORD(wParam
) == EN_CHANGE
) {
1430 GetDlgItemText(hwnd
, IDC_PORT
, portname
, 31);
1431 if (isdigit(portname
[0]))
1432 MyGetDlgItemInt(hwnd
, IDC_PORT
, &cfg
.port
);
1434 service
= getservbyname(portname
, NULL
);
1436 cfg
.port
= ntohs(service
->s_port
);
1443 if (HIWORD(wParam
) == EN_CHANGE
) {
1444 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1446 GetDlgItemText(hwnd
, IDC_SESSEDIT
,
1447 savedsession
, sizeof(savedsession
) - 1);
1448 savedsession
[sizeof(savedsession
) - 1] = '\0';
1452 if (HIWORD(wParam
) == BN_CLICKED
||
1453 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1458 GetDlgItemText(hwnd
, IDC_SESSEDIT
, str
,
1461 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1462 LB_GETCURSEL
, 0, 0);
1467 strcpy(str
, sessions
[n
]);
1469 save_settings(str
, !!strcmp(str
, "Default Settings"),
1471 get_sesslist(FALSE
);
1473 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1475 for (i
= 0; i
< nsessions
; i
++)
1476 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1478 (LPARAM
) (sessions
[i
]));
1479 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1485 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1486 HIWORD(wParam
) != BN_CLICKED
&&
1487 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
1488 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1489 HIWORD(wParam
) != LBN_DBLCLK
) break;
1491 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1492 LB_GETCURSEL
, 0, 0);
1498 isdef
= !strcmp(sessions
[n
], "Default Settings");
1499 load_settings(sessions
[n
], !isdef
, &cfg
);
1500 init_dlg_ctrls(hwnd
);
1502 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1504 SetDlgItemText(hwnd
, IDC_SESSEDIT
, "");
1506 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1508 * A double-click on a saved session should
1509 * actually start the session, not just load it.
1510 * Unless it's Default Settings or some other
1511 * host-less set of saved settings.
1520 if (HIWORD(wParam
) == BN_CLICKED
||
1521 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1522 int n
= SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1523 LB_GETCURSEL
, 0, 0);
1524 if (n
== LB_ERR
|| n
== 0) {
1528 del_settings(sessions
[n
]);
1529 get_sesslist(FALSE
);
1531 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1533 for (i
= 0; i
< nsessions
; i
++)
1534 SendDlgItemMessage(hwnd
, IDC_SESSLIST
,
1536 (LPARAM
) (sessions
[i
]));
1537 SendDlgItemMessage(hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1541 if (HIWORD(wParam
) == EN_CHANGE
)
1542 MyGetDlgItemInt(hwnd
, IDC_PINGEDIT
,
1543 &cfg
.ping_interval
);
1547 if (HIWORD(wParam
) == BN_CLICKED
||
1548 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1549 cfg
.bksp_is_delete
=
1550 IsDlgButtonChecked(hwnd
, IDC_DEL127
);
1554 if (HIWORD(wParam
) == BN_CLICKED
||
1555 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1557 IsDlgButtonChecked(hwnd
, IDC_HOMERXVT
);
1563 case IDC_FUNCVT100P
:
1565 if (HIWORD(wParam
) == BN_CLICKED
||
1566 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1567 switch (LOWORD(wParam
)) {
1580 case IDC_FUNCVT100P
:
1590 if (HIWORD(wParam
) == BN_CLICKED
||
1591 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1593 IsDlgButtonChecked(hwnd
, IDC_KPAPPLIC
);
1594 cfg
.nethack_keypad
= FALSE
;
1598 if (HIWORD(wParam
) == BN_CLICKED
||
1599 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1600 cfg
.app_keypad
= FALSE
;
1601 cfg
.nethack_keypad
= TRUE
;
1606 if (HIWORD(wParam
) == BN_CLICKED
||
1607 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1609 IsDlgButtonChecked(hwnd
, IDC_CURAPPLIC
);
1612 if (HIWORD(wParam
) == BN_CLICKED
||
1613 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1615 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICC
);
1618 if (HIWORD(wParam
) == BN_CLICKED
||
1619 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1621 IsDlgButtonChecked(hwnd
, IDC_NOAPPLICK
);
1624 if (HIWORD(wParam
) == BN_CLICKED
||
1625 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1626 cfg
.alt_f4
= IsDlgButtonChecked(hwnd
, IDC_ALTF4
);
1629 if (HIWORD(wParam
) == BN_CLICKED
||
1630 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1632 IsDlgButtonChecked(hwnd
, IDC_ALTSPACE
);
1635 if (HIWORD(wParam
) == BN_CLICKED
||
1636 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1638 IsDlgButtonChecked(hwnd
, IDC_ALTONLY
);
1640 case IDC_ECHOBACKEND
:
1643 if (HIWORD(wParam
) == BN_CLICKED
||
1644 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1645 if (LOWORD(wParam
) == IDC_ECHOBACKEND
)
1646 cfg
.localecho
= LD_BACKEND
;
1647 if (LOWORD(wParam
) == IDC_ECHOYES
)
1648 cfg
.localecho
= LD_YES
;
1649 if (LOWORD(wParam
) == IDC_ECHONO
)
1650 cfg
.localecho
= LD_NO
;
1653 case IDC_EDITBACKEND
:
1656 if (HIWORD(wParam
) == BN_CLICKED
||
1657 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1658 if (LOWORD(wParam
) == IDC_EDITBACKEND
)
1659 cfg
.localedit
= LD_BACKEND
;
1660 if (LOWORD(wParam
) == IDC_EDITYES
)
1661 cfg
.localedit
= LD_YES
;
1662 if (LOWORD(wParam
) == IDC_EDITNO
)
1663 cfg
.localedit
= LD_NO
;
1666 case IDC_ANSWEREDIT
:
1667 if (HIWORD(wParam
) == EN_CHANGE
)
1668 GetDlgItemText(hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
,
1669 sizeof(cfg
.answerback
) - 1);
1671 case IDC_ALWAYSONTOP
:
1672 if (HIWORD(wParam
) == BN_CLICKED
||
1673 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1675 IsDlgButtonChecked(hwnd
, IDC_ALWAYSONTOP
);
1678 if (HIWORD(wParam
) == BN_CLICKED
||
1679 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1681 IsDlgButtonChecked(hwnd
, IDC_SCROLLKEY
);
1683 case IDC_SCROLLDISP
:
1684 if (HIWORD(wParam
) == BN_CLICKED
||
1685 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1686 cfg
.scroll_on_disp
=
1687 IsDlgButtonChecked(hwnd
, IDC_SCROLLDISP
);
1689 case IDC_COMPOSEKEY
:
1690 if (HIWORD(wParam
) == BN_CLICKED
||
1691 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1693 IsDlgButtonChecked(hwnd
, IDC_COMPOSEKEY
);
1695 case IDC_CTRLALTKEYS
:
1696 if (HIWORD(wParam
) == BN_CLICKED
||
1697 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1699 IsDlgButtonChecked(hwnd
, IDC_CTRLALTKEYS
);
1702 if (HIWORD(wParam
) == BN_CLICKED
||
1703 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1705 IsDlgButtonChecked(hwnd
, IDC_WRAPMODE
);
1708 if (HIWORD(wParam
) == BN_CLICKED
||
1709 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1710 cfg
.dec_om
= IsDlgButtonChecked(hwnd
, IDC_DECOM
);
1713 if (HIWORD(wParam
) == BN_CLICKED
||
1714 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1716 IsDlgButtonChecked(hwnd
, IDC_LFHASCR
);
1719 if (HIWORD(wParam
) == EN_CHANGE
)
1720 MyGetDlgItemInt(hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1723 if (HIWORD(wParam
) == EN_CHANGE
)
1724 MyGetDlgItemInt(hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1727 if (HIWORD(wParam
) == EN_CHANGE
)
1728 MyGetDlgItemInt(hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1730 case IDC_CHOOSEFONT
:
1733 lf
.lfHeight
= -MulDiv(cfg
.fontheight
,
1734 GetDeviceCaps(hdc
, LOGPIXELSY
),
1738 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1739 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1740 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1741 lf
.lfCharSet
= cfg
.fontcharset
;
1742 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1743 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1744 lf
.lfQuality
= DEFAULT_QUALITY
;
1745 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1746 strncpy(lf
.lfFaceName
, cfg
.font
,
1747 sizeof(lf
.lfFaceName
) - 1);
1748 lf
.lfFaceName
[sizeof(lf
.lfFaceName
) - 1] = '\0';
1750 cf
.lStructSize
= sizeof(cf
);
1751 cf
.hwndOwner
= hwnd
;
1753 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1754 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1756 if (ChooseFont(&cf
)) {
1757 strncpy(cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
) - 1);
1758 cfg
.font
[sizeof(cfg
.font
) - 1] = '\0';
1759 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1760 cfg
.fontcharset
= lf
.lfCharSet
;
1761 cfg
.fontheight
= cf
.iPointSize
/ 10;
1762 fmtfont(fontstatic
);
1763 SetDlgItemText(hwnd
, IDC_FONTSTATIC
, fontstatic
);
1766 case IDC_BELL_DISABLED
:
1767 case IDC_BELL_DEFAULT
:
1768 case IDC_BELL_WAVEFILE
:
1769 case IDC_BELL_VISUAL
:
1770 if (HIWORD(wParam
) == BN_CLICKED
||
1771 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1772 if (LOWORD(wParam
) == IDC_BELL_DISABLED
)
1773 cfg
.beep
= BELL_DISABLED
;
1774 if (LOWORD(wParam
) == IDC_BELL_DEFAULT
)
1775 cfg
.beep
= BELL_DEFAULT
;
1776 if (LOWORD(wParam
) == IDC_BELL_WAVEFILE
)
1777 cfg
.beep
= BELL_WAVEFILE
;
1778 if (LOWORD(wParam
) == IDC_BELL_VISUAL
)
1779 cfg
.beep
= BELL_VISUAL
;
1782 case IDC_BELL_WAVEBROWSE
:
1783 memset(&of
, 0, sizeof(of
));
1784 #ifdef OPENFILENAME_SIZE_VERSION_400
1785 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1787 of
.lStructSize
= sizeof(of
);
1789 of
.hwndOwner
= hwnd
;
1790 of
.lpstrFilter
= "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1791 of
.lpstrCustomFilter
= NULL
;
1792 of
.nFilterIndex
= 1;
1793 of
.lpstrFile
= filename
;
1794 strcpy(filename
, cfg
.bell_wavefile
);
1795 of
.nMaxFile
= sizeof(filename
);
1796 of
.lpstrFileTitle
= NULL
;
1797 of
.lpstrInitialDir
= NULL
;
1798 of
.lpstrTitle
= "Select Bell Sound File";
1800 if (GetOpenFileName(&of
)) {
1801 strcpy(cfg
.bell_wavefile
, filename
);
1802 SetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
1806 case IDC_BELL_WAVEEDIT
:
1807 if (HIWORD(wParam
) == EN_CHANGE
)
1808 GetDlgItemText(hwnd
, IDC_BELL_WAVEEDIT
,
1810 sizeof(cfg
.bell_wavefile
) - 1);
1813 if (HIWORD(wParam
) == BN_CLICKED
||
1814 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1816 IsDlgButtonChecked(hwnd
, IDC_BELLOVL
);
1819 if (HIWORD(wParam
) == EN_CHANGE
)
1820 MyGetDlgItemInt(hwnd
, IDC_BELLOVLN
, &cfg
.bellovl_n
);
1823 if (HIWORD(wParam
) == EN_CHANGE
)
1824 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLT
, &cfg
.bellovl_t
,
1828 if (HIWORD(wParam
) == EN_CHANGE
)
1829 MyGetDlgItemFlt(hwnd
, IDC_BELLOVLS
, &cfg
.bellovl_s
,
1833 if (HIWORD(wParam
) == BN_CLICKED
||
1834 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1836 IsDlgButtonChecked(hwnd
, IDC_BLINKTEXT
);
1839 if (HIWORD(wParam
) == BN_CLICKED
||
1840 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1841 cfg
.bce
= IsDlgButtonChecked(hwnd
, IDC_BCE
);
1844 if (HIWORD(wParam
) == BN_CLICKED
||
1845 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1846 cfg
.win_name_always
=
1847 IsDlgButtonChecked(hwnd
, IDC_WINNAME
);
1850 if (HIWORD(wParam
) == BN_CLICKED
||
1851 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1853 IsDlgButtonChecked(hwnd
, IDC_HIDEMOUSE
);
1855 case IDC_SUNKENEDGE
:
1856 if (HIWORD(wParam
) == BN_CLICKED
||
1857 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1859 IsDlgButtonChecked(hwnd
, IDC_SUNKENEDGE
);
1862 if (HIWORD(wParam
) == BN_CLICKED
||
1863 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1864 cfg
.cursor_type
= 0;
1867 if (HIWORD(wParam
) == BN_CLICKED
||
1868 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1869 cfg
.cursor_type
= 1;
1872 if (HIWORD(wParam
) == BN_CLICKED
||
1873 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1874 cfg
.cursor_type
= 2;
1877 if (HIWORD(wParam
) == BN_CLICKED
||
1878 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1880 IsDlgButtonChecked(hwnd
, IDC_BLINKCUR
);
1883 if (HIWORD(wParam
) == BN_CLICKED
||
1884 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1886 IsDlgButtonChecked(hwnd
, IDC_SCROLLBAR
);
1889 if (HIWORD(wParam
) == BN_CLICKED
||
1890 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1892 IsDlgButtonChecked(hwnd
, IDC_LOCKSIZE
);
1895 if (HIWORD(wParam
) == EN_CHANGE
)
1896 GetDlgItemText(hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
1897 sizeof(cfg
.wintitle
) - 1);
1902 if (HIWORD(wParam
) == BN_CLICKED
||
1903 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1905 IsDlgButtonChecked(hwnd
,
1906 IDC_COEALWAYS
) ? COE_ALWAYS
:
1907 IsDlgButtonChecked(hwnd
,
1908 IDC_COENEVER
) ? COE_NEVER
:
1913 if (HIWORD(wParam
) == BN_CLICKED
||
1914 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1916 IsDlgButtonChecked(hwnd
, IDC_CLOSEWARN
);
1919 if (HIWORD(wParam
) == EN_CHANGE
)
1920 GetDlgItemText(hwnd
, IDC_TTEDIT
, cfg
.termtype
,
1921 sizeof(cfg
.termtype
) - 1);
1924 if (HIWORD(wParam
) == EN_CHANGE
)
1925 GetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
,
1926 sizeof(cfg
.logfilename
) - 1);
1929 memset(&of
, 0, sizeof(of
));
1930 #ifdef OPENFILENAME_SIZE_VERSION_400
1931 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1933 of
.lStructSize
= sizeof(of
);
1935 of
.hwndOwner
= hwnd
;
1936 of
.lpstrFilter
= "All Files\0*\0\0\0";
1937 of
.lpstrCustomFilter
= NULL
;
1938 of
.nFilterIndex
= 1;
1939 of
.lpstrFile
= filename
;
1940 strcpy(filename
, cfg
.logfilename
);
1941 of
.nMaxFile
= sizeof(filename
);
1942 of
.lpstrFileTitle
= NULL
;
1943 of
.lpstrInitialDir
= NULL
;
1944 of
.lpstrTitle
= "Select session log file";
1946 if (GetSaveFileName(&of
)) {
1947 strcpy(cfg
.logfilename
, filename
);
1948 SetDlgItemText(hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
1952 case IDC_LSTATASCII
:
1954 if (HIWORD(wParam
) == BN_CLICKED
||
1955 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1956 if (IsDlgButtonChecked(hwnd
, IDC_LSTATOFF
))
1958 if (IsDlgButtonChecked(hwnd
, IDC_LSTATASCII
))
1960 if (IsDlgButtonChecked(hwnd
, IDC_LSTATRAW
))
1967 if (HIWORD(wParam
) == BN_CLICKED
||
1968 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1969 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXASK
))
1970 cfg
.logxfovr
= LGXF_ASK
;
1971 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXAPN
))
1972 cfg
.logxfovr
= LGXF_APN
;
1973 if (IsDlgButtonChecked(hwnd
, IDC_LSTATXOVR
))
1974 cfg
.logxfovr
= LGXF_OVR
;
1979 if (HIWORD(wParam
) == EN_CHANGE
)
1980 GetDlgItemText(hwnd
, LOWORD(wParam
), cfg
.termspeed
,
1981 sizeof(cfg
.termspeed
) - 1);
1984 if (HIWORD(wParam
) == EN_CHANGE
)
1985 GetDlgItemText(hwnd
, IDC_LOGEDIT
, cfg
.username
,
1986 sizeof(cfg
.username
) - 1);
1988 case IDC_RLLUSEREDIT
:
1989 if (HIWORD(wParam
) == EN_CHANGE
)
1990 GetDlgItemText(hwnd
, IDC_RLLUSEREDIT
,
1992 sizeof(cfg
.localusername
) - 1);
1996 cfg
.rfc_environ
= IsDlgButtonChecked(hwnd
, IDC_EMRFC
);
2000 cfg
.passive_telnet
=
2001 IsDlgButtonChecked(hwnd
, IDC_TPASSIVE
);
2004 if (HIWORD(wParam
) == BN_CLICKED
||
2005 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2006 char str
[sizeof(cfg
.environmt
)];
2008 GetDlgItemText(hwnd
, IDC_VAREDIT
, str
,
2014 p
= str
+ strlen(str
);
2016 GetDlgItemText(hwnd
, IDC_VALEDIT
, p
,
2017 sizeof(str
) - 1 - (p
- str
));
2028 if ((p
- cfg
.environmt
) + strlen(str
) + 2 <
2029 sizeof(cfg
.environmt
)) {
2031 p
[strlen(str
) + 1] = '\0';
2032 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
2034 SetDlgItemText(hwnd
, IDC_VAREDIT
, "");
2035 SetDlgItemText(hwnd
, IDC_VALEDIT
, "");
2037 MessageBox(hwnd
, "Environment too big",
2038 "PuTTY Error", MB_OK
| MB_ICONERROR
);
2043 if (HIWORD(wParam
) != BN_CLICKED
&&
2044 HIWORD(wParam
) != BN_DOUBLECLICKED
) break;
2046 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0,
2053 SendDlgItemMessage(hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
2080 if (HIWORD(wParam
) == BN_CLICKED
||
2081 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2082 cfg
.nopty
= IsDlgButtonChecked(hwnd
, IDC_NOPTY
);
2085 if (HIWORD(wParam
) == BN_CLICKED
||
2086 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2088 IsDlgButtonChecked(hwnd
, IDC_COMPRESS
);
2091 if (HIWORD(wParam
) == BN_CLICKED
||
2092 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2094 IsDlgButtonChecked(hwnd
, IDC_BUGGYMAC
);
2097 if (HIWORD(wParam
) == BN_CLICKED
||
2098 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2100 IsDlgButtonChecked(hwnd
, IDC_AGENTFWD
);
2102 case IDC_CIPHER3DES
:
2103 case IDC_CIPHERBLOWF
:
2106 if (HIWORD(wParam
) == BN_CLICKED
||
2107 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2108 if (IsDlgButtonChecked(hwnd
, IDC_CIPHER3DES
))
2109 cfg
.cipher
= CIPHER_3DES
;
2110 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERBLOWF
))
2111 cfg
.cipher
= CIPHER_BLOWFISH
;
2112 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERDES
))
2113 cfg
.cipher
= CIPHER_DES
;
2114 else if (IsDlgButtonChecked(hwnd
, IDC_CIPHERAES
))
2115 cfg
.cipher
= CIPHER_AES
;
2120 if (HIWORD(wParam
) == BN_CLICKED
||
2121 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2122 if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT1
))
2124 else if (IsDlgButtonChecked(hwnd
, IDC_SSHPROT2
))
2129 if (HIWORD(wParam
) == BN_CLICKED
||
2130 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2132 IsDlgButtonChecked(hwnd
, IDC_AUTHTIS
);
2135 if (HIWORD(wParam
) == EN_CHANGE
)
2136 GetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
2137 sizeof(cfg
.keyfile
) - 1);
2140 if (HIWORD(wParam
) == EN_CHANGE
)
2141 GetDlgItemText(hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
2142 sizeof(cfg
.remote_cmd
) - 1);
2145 memset(&of
, 0, sizeof(of
));
2146 #ifdef OPENFILENAME_SIZE_VERSION_400
2147 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
2149 of
.lStructSize
= sizeof(of
);
2151 of
.hwndOwner
= hwnd
;
2152 of
.lpstrFilter
= "All Files\0*\0\0\0";
2153 of
.lpstrCustomFilter
= NULL
;
2154 of
.nFilterIndex
= 1;
2155 of
.lpstrFile
= filename
;
2156 strcpy(filename
, cfg
.keyfile
);
2157 of
.nMaxFile
= sizeof(filename
);
2158 of
.lpstrFileTitle
= NULL
;
2159 of
.lpstrInitialDir
= NULL
;
2160 of
.lpstrTitle
= "Select Public Key File";
2162 if (GetOpenFileName(&of
)) {
2163 strcpy(cfg
.keyfile
, filename
);
2164 SetDlgItemText(hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
2168 cfg
.rawcnp
= IsDlgButtonChecked(hwnd
, IDC_RAWCNP
);
2171 cfg
.mouse_is_xterm
= IsDlgButtonChecked(hwnd
, IDC_MBXTERM
);
2177 int n
= GetDlgItemInt(hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
2182 for (i
= 0; i
< 256; i
++)
2183 if (SendDlgItemMessage
2184 (hwnd
, IDC_CCLIST
, LB_GETSEL
, i
, 0)) {
2186 cfg
.wordness
[i
] = n
;
2187 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2188 LB_DELETESTRING
, i
, 0);
2189 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
2190 (i
>= 0x21 && i
!= 0x7F) ? i
: ' ',
2192 SendDlgItemMessage(hwnd
, IDC_CCLIST
,
2199 case IDC_BOLDCOLOUR
:
2200 if (HIWORD(wParam
) == BN_CLICKED
||
2201 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2204 IsDlgButtonChecked(hwnd
, IDC_BOLDCOLOUR
);
2206 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2208 if (n
!= 12 + 10 * cfg
.bold_colour
) {
2209 for (i
= n
; i
-- > 0;)
2210 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2211 LB_DELETESTRING
, i
, 0);
2212 for (i
= 0; i
< 22; i
++)
2213 if (cfg
.bold_colour
|| permcolour
[i
])
2214 SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2216 (LPARAM
) colours
[i
]);
2221 if (HIWORD(wParam
) == BN_CLICKED
||
2222 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2224 IsDlgButtonChecked(hwnd
, IDC_PALETTE
);
2226 case IDC_COLOURLIST
:
2227 if (HIWORD(wParam
) == LBN_DBLCLK
||
2228 HIWORD(wParam
) == LBN_SELCHANGE
) {
2229 int i
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2232 if (!cfg
.bold_colour
)
2233 i
= (i
< 3 ? i
* 2 : i
== 3 ?
5 : i
* 2 - 2);
2234 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2236 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2238 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2243 if (HIWORD(wParam
) == BN_CLICKED
||
2244 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2245 static CHOOSECOLOR cc
;
2246 static DWORD custom
[16] = { 0 }; /* zero initialisers */
2247 int i
= SendDlgItemMessage(hwnd
, IDC_COLOURLIST
,
2250 if (!cfg
.bold_colour
)
2251 i
= (i
< 3 ? i
* 2 : i
== 3 ?
5 : i
* 2 - 2);
2252 cc
.lStructSize
= sizeof(cc
);
2253 cc
.hwndOwner
= hwnd
;
2254 cc
.hInstance
= (HWND
) hinst
;
2255 cc
.lpCustColors
= custom
;
2257 RGB(cfg
.colours
[i
][0], cfg
.colours
[i
][1],
2259 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
2260 if (ChooseColor(&cc
)) {
2262 (unsigned char) (cc
.rgbResult
& 0xFF);
2264 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
2266 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
2267 SetDlgItemInt(hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2269 SetDlgItemInt(hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2271 SetDlgItemInt(hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2277 case IDC_KOI8WIN1251
:
2278 case IDC_88592WIN1250
:
2279 case IDC_88592CP852
:
2280 cfg
.xlat_enablekoiwin
=
2281 IsDlgButtonChecked(hwnd
, IDC_KOI8WIN1251
);
2282 cfg
.xlat_88592w1250
=
2283 IsDlgButtonChecked(hwnd
, IDC_88592WIN1250
);
2284 cfg
.xlat_88592cp852
=
2285 IsDlgButtonChecked(hwnd
, IDC_88592CP852
);
2287 case IDC_CAPSLOCKCYR
:
2288 if (HIWORD(wParam
) == BN_CLICKED
||
2289 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2290 cfg
.xlat_capslockcyr
=
2291 IsDlgButtonChecked(hwnd
, IDC_CAPSLOCKCYR
);
2294 case IDC_VTXWINDOWS
:
2299 (IsDlgButtonChecked(hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
2300 : IsDlgButtonChecked(hwnd
,
2301 IDC_VTOEMANSI
) ? VT_OEMANSI
:
2302 IsDlgButtonChecked(hwnd
,
2303 IDC_VTOEMONLY
) ? VT_OEMONLY
:
2306 case IDC_X11_FORWARD
:
2307 if (HIWORD(wParam
) == BN_CLICKED
||
2308 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2310 IsDlgButtonChecked(hwnd
, IDC_X11_FORWARD
);
2312 case IDC_X11_DISPLAY
:
2313 if (HIWORD(wParam
) == EN_CHANGE
)
2314 GetDlgItemText(hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
,
2315 sizeof(cfg
.x11_display
) - 1);
2323 /* Grrr Explorer will maximize Dialogs! */
2325 if (wParam
== SIZE_MAXIMIZED
)
2332 static int CALLBACK
MainDlgProc(HWND hwnd
, UINT msg
,
2333 WPARAM wParam
, LPARAM lParam
)
2335 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
2337 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
2338 EnableWindow(hwnd
, 0);
2339 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2340 GetParent(hwnd
), AboutProc
);
2341 EnableWindow(hwnd
, 1);
2342 SetActiveWindow(hwnd
);
2344 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 0);
2347 static int CALLBACK
ReconfDlgProc(HWND hwnd
, UINT msg
,
2348 WPARAM wParam
, LPARAM lParam
)
2350 return GenericMainDlgProc(hwnd
, msg
, wParam
, lParam
, 1);
2353 void defuse_showwindow(void)
2356 * Work around the fact that the app's first call to ShowWindow
2357 * will ignore the default in favour of the shell-provided
2362 hwnd
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2364 ShowWindow(hwnd
, SW_HIDE
);
2365 DestroyWindow(hwnd
);
2374 savedsession
[0] = '\0';
2376 DialogBox(hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
2377 get_sesslist(FALSE
);
2382 int do_reconfig(HWND hwnd
)
2387 backup_cfg
= cfg
; /* structure copy */
2389 DialogBox(hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
2391 cfg
= backup_cfg
; /* structure copy */
2396 void logevent(char *string
)
2401 if (nevents
>= negsize
) {
2403 events
= srealloc(events
, negsize
* sizeof(*events
));
2407 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%d %H:%M:%S\t",
2410 events
[nevents
] = smalloc(strlen(timebuf
) + strlen(string
) + 1);
2411 strcpy(events
[nevents
], timebuf
);
2412 strcat(events
[nevents
], string
);
2415 SendDlgItemMessage(logbox
, IDN_LIST
, LB_ADDSTRING
,
2416 0, (LPARAM
) events
[nevents
]);
2417 count
= SendDlgItemMessage(logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
2418 SendDlgItemMessage(logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
- 1, 0);
2423 void showeventlog(HWND hwnd
)
2426 logbox
= CreateDialog(hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
2428 ShowWindow(logbox
, SW_SHOWNORMAL
);
2430 SetActiveWindow(logbox
);
2433 void showabout(HWND hwnd
)
2435 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
), hwnd
, AboutProc
);
2438 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
2439 char *keystr
, char *fingerprint
)
2443 static const char absentmsg
[] =
2444 "The server's host key is not cached in the registry. You\n"
2445 "have no guarantee that the server is the computer you\n"
2447 "The server's key fingerprint is:\n"
2449 "If you trust this host, hit Yes to add the key to\n"
2450 "PuTTY's cache and carry on connecting.\n"
2451 "If you do not trust this host, hit No to abandon the\n"
2454 static const char wrongmsg
[] =
2455 "WARNING - POTENTIAL SECURITY BREACH!\n"
2457 "The server's host key does not match the one PuTTY has\n"
2458 "cached in the registry. This means that either the\n"
2459 "server administrator has changed the host key, or you\n"
2460 "have actually connected to another computer pretending\n"
2461 "to be the server.\n"
2462 "The new key fingerprint is:\n"
2464 "If you were expecting this change and trust the new key,\n"
2465 "hit Yes to update PuTTY's cache and continue connecting.\n"
2466 "If you want to carry on connecting but without updating\n"
2467 "the cache, hit No.\n"
2468 "If you want to abandon the connection completely, hit\n"
2469 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2471 static const char mbtitle
[] = "PuTTY Security Alert";
2475 /* sensible fingerprint max size */
2476 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
2477 sizeof(absentmsg
) : sizeof(wrongmsg
))];
2480 * Verify the key against the registry.
2482 ret
= verify_host_key(host
, port
, keytype
, keystr
);
2484 if (ret
== 0) /* success - key matched OK */
2486 if (ret
== 2) { /* key was different */
2488 sprintf(message
, wrongmsg
, fingerprint
);
2489 mbret
= MessageBox(NULL
, message
, mbtitle
,
2490 MB_ICONWARNING
| MB_YESNOCANCEL
);
2492 store_host_key(host
, port
, keytype
, keystr
);
2493 if (mbret
== IDCANCEL
)
2496 if (ret
== 1) { /* key was absent */
2498 sprintf(message
, absentmsg
, fingerprint
);
2499 mbret
= MessageBox(NULL
, message
, mbtitle
,
2500 MB_ICONWARNING
| MB_YESNO
);
2503 store_host_key(host
, port
, keytype
, keystr
);
2508 * Ask whether to wipe a session log file before writing to it.
2509 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2511 int askappend(char *filename
)
2513 static const char mbtitle
[] = "PuTTY Log to File";
2514 static const char msgtemplate
[] =
2515 "The session log file \"%.*s\" already exists.\n"
2516 "You can overwrite it with a new session log,\n"
2517 "append your session log to the end of it,\n"
2518 "or disable session logging for this session.\n"
2519 "Hit Yes to wipe the file, No to append to it,\n"
2520 "or Cancel to disable logging.";
2521 char message
[sizeof(msgtemplate
) + FILENAME_MAX
];
2523 if (cfg
.logxfovr
!= LGXF_ASK
) {
2524 return ((cfg
.logxfovr
== LGXF_OVR
) ?
2 : 1);
2526 sprintf(message
, msgtemplate
, FILENAME_MAX
, filename
);
2528 mbret
= MessageBox(NULL
, message
, mbtitle
,
2529 MB_ICONQUESTION
| MB_YESNOCANCEL
);
2532 else if (mbret
== IDNO
)