15 static char **events
= NULL
;
16 static int nevents
= 0, negsize
= 0;
20 void force_normal(HWND hwnd
)
22 static int recurse
= 0;
29 wp
.length
= sizeof(wp
);
30 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
) {
41 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
46 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
47 WPARAM wParam
, LPARAM lParam
) {
53 static int tabs
[4] = {78, 108};
54 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_SETTABSTOPS
, 2,
57 for (i
=0; i
<nevents
; i
++)
58 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
59 0, (LPARAM
)events
[i
]);
62 switch (LOWORD(wParam
)) {
66 SetActiveWindow(GetParent(hwnd
));
70 if (HIWORD(wParam
) == BN_CLICKED
||
71 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
74 selcount
= SendDlgItemMessage(hwnd
, IDN_LIST
,
75 LB_GETSELCOUNT
, 0, 0);
76 if (selcount
== 0) { /* don't even try to copy zero items */
81 selitems
= smalloc(selcount
* sizeof(int));
83 int count
= SendDlgItemMessage(hwnd
, IDN_LIST
,
85 selcount
, (LPARAM
)selitems
);
89 static unsigned char sel_nl
[] = SEL_NL
;
91 if (count
== 0) { /* can't copy zero stuff */
97 for (i
= 0; i
< count
; i
++)
98 size
+= strlen(events
[selitems
[i
]]) + sizeof(sel_nl
);
100 clipdata
= smalloc(size
);
103 for (i
= 0; i
< count
; i
++) {
104 char *q
= events
[selitems
[i
]];
105 int qlen
= strlen(q
);
108 memcpy(p
, sel_nl
, sizeof(sel_nl
));
111 write_clip(clipdata
, size
, TRUE
);
116 for (i
= 0; i
< nevents
; i
++)
117 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_SETSEL
,
126 SetActiveWindow(GetParent(hwnd
));
127 DestroyWindow (hwnd
);
133 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
134 WPARAM wParam
, LPARAM lParam
) {
139 switch (LOWORD(wParam
)) {
152 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
153 WPARAM wParam
, LPARAM lParam
) {
156 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
159 switch (LOWORD(wParam
)) {
162 EndDialog(hwnd
, TRUE
);
165 EnableWindow(hwnd
, 0);
166 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
168 EnableWindow(hwnd
, 1);
169 SetActiveWindow(hwnd
);
173 /* Load web browser */
174 ShellExecute(hwnd
, "open",
175 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
176 0, 0, SW_SHOWDEFAULT
);
181 EndDialog(hwnd
, TRUE
);
188 * Null dialog procedure.
190 static int CALLBACK
NullDlgProc (HWND hwnd
, UINT msg
,
191 WPARAM wParam
, LPARAM lParam
) {
195 static char savedsession
[2048];
197 enum { IDCX_ABOUT
= IDC_ABOUT
, IDCX_TVSTATIC
, IDCX_TREEVIEW
, controlstartvalue
,
335 appearancepanelstart
,
336 IDC_TITLE_APPEARANCE
,
354 connectionpanelstart
,
355 IDC_TITLE_CONNECTION
,
453 translationpanelstart
,
454 IDC_TITLE_TRANSLATION
,
455 IDC_BOX_TRANSLATION1
,
456 IDC_BOX_TRANSLATION2
,
457 IDC_BOX_TRANSLATION3
,
482 static const char *const colours
[] = {
483 "Default Foreground", "Default Bold Foreground",
484 "Default Background", "Default Bold Background",
485 "Cursor Text", "Cursor Colour",
486 "ANSI Black", "ANSI Black Bold",
487 "ANSI Red", "ANSI Red Bold",
488 "ANSI Green", "ANSI Green Bold",
489 "ANSI Yellow", "ANSI Yellow Bold",
490 "ANSI Blue", "ANSI Blue Bold",
491 "ANSI Magenta", "ANSI Magenta Bold",
492 "ANSI Cyan", "ANSI Cyan Bold",
493 "ANSI White", "ANSI White Bold"
495 static const int permcolour
[] = {
496 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
497 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
498 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
501 static void fmtfont (char *buf
) {
502 sprintf (buf
, "Font: %s, ", cfg
.font
);
504 strcat(buf
, "bold, ");
505 if (cfg
.fontheight
== 0)
506 strcat (buf
, "default height");
508 sprintf (buf
+strlen(buf
), "%d-point",
509 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
));
512 static void init_dlg_ctrls(HWND hwnd
) {
514 char fontstatic
[256];
516 SetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
);
517 SetDlgItemText (hwnd
, IDC_SESSEDIT
, savedsession
);
520 n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_GETCOUNT
, 0, 0);
522 SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
523 LB_DELETESTRING
, i
, 0);
524 for (i
= 0; i
< nsessions
; i
++)
525 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
526 0, (LPARAM
) (sessions
[i
]));
528 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
529 CheckRadioButton (hwnd
, IDC_PROTRAW
, IDC_PROTSSH
,
530 cfg
.protocol
==PROT_SSH ? IDC_PROTSSH
:
531 cfg
.protocol
==PROT_TELNET ? IDC_PROTTELNET
:
532 cfg
.protocol
==PROT_RLOGIN ? IDC_PROTRLOGIN
: IDC_PROTRAW
);
533 SetDlgItemInt (hwnd
, IDC_PINGEDIT
, cfg
.ping_interval
, FALSE
);
535 CheckRadioButton (hwnd
, IDC_DEL008
, IDC_DEL127
,
536 cfg
.bksp_is_delete ? IDC_DEL127
: IDC_DEL008
);
537 CheckRadioButton (hwnd
, IDC_HOMETILDE
, IDC_HOMERXVT
,
538 cfg
.rxvt_homeend ? IDC_HOMERXVT
: IDC_HOMETILDE
);
539 CheckRadioButton (hwnd
, IDC_FUNCTILDE
, IDC_FUNCVT400
,
540 cfg
.funky_type
== 0 ? IDC_FUNCTILDE
:
541 cfg
.funky_type
== 1 ? IDC_FUNCLINUX
:
542 cfg
.funky_type
== 2 ? IDC_FUNCXTERM
:
543 cfg
.funky_type
== 3 ? IDC_FUNCVT400
:
545 CheckDlgButton (hwnd
, IDC_NOAPPLICC
, cfg
.no_applic_c
);
546 CheckDlgButton (hwnd
, IDC_NOAPPLICK
, cfg
.no_applic_k
);
547 CheckRadioButton (hwnd
, IDC_CURNORMAL
, IDC_CURAPPLIC
,
548 cfg
.app_cursor ? IDC_CURAPPLIC
: IDC_CURNORMAL
);
549 CheckRadioButton (hwnd
, IDC_KPNORMAL
, IDC_KPNH
,
550 cfg
.nethack_keypad ? IDC_KPNH
:
551 cfg
.app_keypad ? IDC_KPAPPLIC
: IDC_KPNORMAL
);
552 CheckDlgButton (hwnd
, IDC_ALTF4
, cfg
.alt_f4
);
553 CheckDlgButton (hwnd
, IDC_ALTSPACE
, cfg
.alt_space
);
554 CheckDlgButton (hwnd
, IDC_ALTONLY
, cfg
.alt_only
);
555 CheckDlgButton (hwnd
, IDC_COMPOSEKEY
, cfg
.compose_key
);
556 CheckDlgButton (hwnd
, IDC_CTRLALTKEYS
, cfg
.ctrlaltkeys
);
557 CheckRadioButton (hwnd
, IDC_ECHOBACKEND
, IDC_ECHONO
,
558 cfg
.localecho
== LD_BACKEND ? IDC_ECHOBACKEND
:
559 cfg
.localecho
== LD_YES ? IDC_ECHOYES
: IDC_ECHONO
);
560 CheckRadioButton (hwnd
, IDC_EDITBACKEND
, IDC_EDITNO
,
561 cfg
.localedit
== LD_BACKEND ? IDC_EDITBACKEND
:
562 cfg
.localedit
== LD_YES ? IDC_EDITYES
: IDC_EDITNO
);
563 SetDlgItemText (hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
);
564 CheckDlgButton (hwnd
, IDC_ALWAYSONTOP
, cfg
.alwaysontop
);
565 CheckDlgButton (hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
566 CheckDlgButton (hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
568 CheckDlgButton (hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
569 CheckDlgButton (hwnd
, IDC_DECOM
, cfg
.dec_om
);
570 CheckDlgButton (hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
571 SetDlgItemInt (hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
572 SetDlgItemInt (hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
573 SetDlgItemInt (hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
574 fmtfont (fontstatic
);
575 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
576 CheckRadioButton (hwnd
, IDC_BELL_DISABLED
, IDC_BELL_VISUAL
,
577 cfg
.beep
==BELL_DISABLED ? IDC_BELL_DISABLED
:
578 cfg
.beep
==BELL_DEFAULT ? IDC_BELL_DEFAULT
:
579 cfg
.beep
==BELL_WAVEFILE ? IDC_BELL_WAVEFILE
:
580 cfg
.beep
==BELL_VISUAL ? IDC_BELL_VISUAL
: IDC_BELL_DEFAULT
);
581 SetDlgItemText (hwnd
, IDC_BELL_WAVEEDIT
, cfg
.bell_wavefile
);
582 CheckDlgButton (hwnd
, IDC_BELLOVL
, cfg
.bellovl
);
583 SetDlgItemInt (hwnd
, IDC_BELLOVLN
, cfg
.bellovl_n
, FALSE
);
584 SetDlgItemInt (hwnd
, IDC_BELLOVLT
, cfg
.bellovl_t
, FALSE
);
585 SetDlgItemInt (hwnd
, IDC_BELLOVLS
, cfg
.bellovl_s
, FALSE
);
587 CheckDlgButton (hwnd
, IDC_BCE
, cfg
.bce
);
588 CheckDlgButton (hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
590 SetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
591 CheckDlgButton (hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
592 CheckDlgButton (hwnd
, IDC_HIDEMOUSE
, cfg
.hide_mouseptr
);
593 CheckRadioButton (hwnd
, IDC_CURBLOCK
, IDC_CURVERT
,
594 cfg
.cursor_type
==0 ? IDC_CURBLOCK
:
595 cfg
.cursor_type
==1 ? IDC_CURUNDER
: IDC_CURVERT
);
596 CheckDlgButton (hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
597 CheckDlgButton (hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
598 CheckDlgButton (hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
599 CheckRadioButton (hwnd
, IDC_COEALWAYS
, IDC_COENORMAL
,
600 cfg
.close_on_exit
==COE_NORMAL ? IDC_COENORMAL
:
601 cfg
.close_on_exit
==COE_NEVER ? IDC_COENEVER
: IDC_COEALWAYS
);
602 CheckDlgButton (hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
604 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
605 SetDlgItemText (hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
606 SetDlgItemText (hwnd
, IDC_R_TSEDIT
, cfg
.termspeed
);
607 SetDlgItemText (hwnd
, IDC_RLLUSEREDIT
, cfg
.localusername
);
608 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
609 SetDlgItemText (hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
610 CheckRadioButton(hwnd
, IDC_LSTATOFF
, IDC_LSTATRAW
,
611 cfg
.logtype
== 0 ? IDC_LSTATOFF
:
612 cfg
.logtype
== 1 ? IDC_LSTATASCII
:
614 CheckRadioButton(hwnd
, IDC_LSTATXOVR
, IDC_LSTATXASK
,
615 cfg
.logxfovr
== LGXF_OVR ? IDC_LSTATXOVR
:
616 cfg
.logxfovr
== LGXF_ASK ? IDC_LSTATXASK
:
619 char *p
= cfg
.environmt
;
621 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
626 CheckRadioButton (hwnd
, IDC_EMBSD
, IDC_EMRFC
,
627 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
629 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
630 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
631 CheckDlgButton (hwnd
, IDC_NOPTY
, cfg
.nopty
);
632 CheckDlgButton (hwnd
, IDC_COMPRESS
, cfg
.compression
);
633 CheckDlgButton (hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
634 CheckDlgButton (hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
635 CheckRadioButton (hwnd
, IDC_CIPHER3DES
, IDC_CIPHERAES
,
636 cfg
.cipher
== CIPHER_BLOWFISH ? IDC_CIPHERBLOWF
:
637 cfg
.cipher
== CIPHER_DES ? IDC_CIPHERDES
:
638 cfg
.cipher
== CIPHER_AES ? IDC_CIPHERAES
:
640 CheckRadioButton (hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
641 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
642 CheckDlgButton (hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
643 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
644 SetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
646 CheckRadioButton (hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
647 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
648 CheckDlgButton (hwnd
, IDC_RAWCNP
, cfg
.rawcnp
);
650 static int tabs
[4] = {25, 61, 96, 128};
651 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
654 for (i
=0; i
<256; i
++) {
656 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
657 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
659 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
663 CheckDlgButton (hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
664 CheckDlgButton (hwnd
, IDC_PALETTE
, cfg
.try_palette
);
667 n
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
669 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
670 LB_DELETESTRING
, i
, 0);
672 if (cfg
.bold_colour
|| permcolour
[i
])
673 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
674 (LPARAM
) colours
[i
]);
676 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
677 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
678 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
679 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
681 CheckRadioButton (hwnd
, IDC_NOXLAT
, IDC_88592CP852
,
682 cfg
.xlat_88592w1250 ? IDC_88592WIN1250
:
683 cfg
.xlat_88592cp852 ? IDC_88592CP852
:
684 cfg
.xlat_enablekoiwin ? IDC_KOI8WIN1251
:
686 CheckDlgButton (hwnd
, IDC_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
687 CheckRadioButton (hwnd
, IDC_VTXWINDOWS
, IDC_VTPOORMAN
,
688 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
689 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
690 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
693 CheckDlgButton (hwnd
, IDC_X11_FORWARD
, cfg
.x11_forward
);
694 SetDlgItemText (hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
);
697 struct treeview_faff
{
702 static HTREEITEM
treeview_insert(struct treeview_faff
*faff
,
703 int level
, char *text
) {
707 ins
.hParent
= (level
> 0 ? faff
->lastat
[level
-1] : TVI_ROOT
);
708 ins
.hInsertAfter
= faff
->lastat
[level
];
709 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
710 #define INSITEM DUMMYUNIONNAME.item
714 ins
.INSITEM
.mask
= TVIF_TEXT
;
715 ins
.INSITEM
.pszText
= text
;
716 newitem
= TreeView_InsertItem(faff
->treeview
, &ins
);
718 TreeView_Expand(faff
->treeview
, faff
->lastat
[level
-1], TVE_EXPAND
);
719 faff
->lastat
[level
] = newitem
;
720 for (i
= level
+1; i
< 4; i
++) faff
->lastat
[i
] = NULL
;
725 * Create the panelfuls of controls in the configuration box.
727 static void create_controls(HWND hwnd
, int dlgtype
, int panel
) {
728 if (panel
== sessionpanelstart
) {
729 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
731 ctlposinit(&cp
, hwnd
, 80, 3, 13);
732 bartitle(&cp
, "Basic options for your PuTTY session",
735 beginbox(&cp
, "Specify your connection by host name",
738 "Host &Name", IDC_HOSTSTATIC
, IDC_HOST
, 75,
739 "&Port", IDC_PORTSTATIC
, IDC_PORT
, 25, NULL
);
740 if (backends
[3].backend
== NULL
) {
741 /* this is PuTTYtel, so only three protocols available */
742 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 4,
744 "&Telnet", IDC_PROTTELNET
,
745 "Rlog&in", IDC_PROTRLOGIN
, NULL
);
747 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 4,
749 "&Telnet", IDC_PROTTELNET
,
750 "Rlog&in", IDC_PROTRLOGIN
,
759 beginbox(&cp
, "Load, save or delete a stored session",
761 sesssaver(&cp
, "Sav&ed Sessions",
762 IDC_SESSSTATIC
, IDC_SESSEDIT
, IDC_SESSLIST
,
763 "&Load", IDC_SESSLOAD
,
764 "&Save", IDC_SESSSAVE
,
765 "&Delete", IDC_SESSDEL
, NULL
);
768 beginbox(&cp
, NULL
, IDC_BOX_SESSION3
);
769 radioline(&cp
, "Close &window on exit:", IDC_CLOSEEXIT
, 4,
770 "Always", IDC_COEALWAYS
,
771 "Never", IDC_COENEVER
,
772 "Only on clean exit", IDC_COENORMAL
, NULL
);
776 if (panel
== loggingpanelstart
) {
777 /* The Logging panel. Accelerators used: [acgo] tplfwes */
779 ctlposinit(&cp
, hwnd
, 80, 3, 13);
780 bartitle(&cp
, "Options controlling session logging",
782 beginbox(&cp
, NULL
, IDC_BOX_LOGGING1
);
784 "Session logging:", IDC_LSTATSTATIC
,
785 "Logging &turned off completely", IDC_LSTATOFF
,
786 "Log &printable output only", IDC_LSTATASCII
,
787 "&Log all session output", IDC_LSTATRAW
, NULL
);
788 editbutton(&cp
, "Log &file name:",
789 IDC_LGFSTATIC
, IDC_LGFEDIT
, "Bro&wse...",
792 "What to do if the log file already &exists:", IDC_LSTATXIST
,
793 "Always overwrite it", IDC_LSTATXOVR
,
794 "Always append to the end of it", IDC_LSTATXAPN
,
795 "Ask the user every time", IDC_LSTATXASK
, NULL
);
799 if (panel
== terminalpanelstart
) {
800 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
802 ctlposinit(&cp
, hwnd
, 80, 3, 13);
803 bartitle(&cp
, "Options controlling the terminal emulation",
805 beginbox(&cp
, "Set various terminal options",
807 checkbox(&cp
, "Auto &wrap mode initially on", IDC_WRAPMODE
);
808 checkbox(&cp
, "&DEC Origin Mode initially on", IDC_DECOM
);
809 checkbox(&cp
, "Implicit CR in every &LF", IDC_LFHASCR
);
810 checkbox(&cp
, "Use background colour to &erase screen", IDC_BCE
);
811 checkbox(&cp
, "Enable bli&nking text", IDC_BLINKTEXT
);
813 "An&swerback to ^E:", IDC_ANSWERBACK
,
814 IDC_ANSWEREDIT
, 100, NULL
);
817 beginbox(&cp
, "Line discipline options",
819 radioline(&cp
, "Local ec&ho:", IDC_ECHOSTATIC
, 3,
820 "Auto", IDC_ECHOBACKEND
,
821 "Force on", IDC_ECHOYES
,
822 "Force off", IDC_ECHONO
, NULL
);
823 radioline(&cp
, "Local line edi&ting:", IDC_EDITSTATIC
, 3,
824 "Auto", IDC_EDITBACKEND
,
825 "Force on", IDC_EDITYES
,
826 "Force off", IDC_EDITNO
, NULL
);
830 if (panel
== bellpanelstart
) {
831 /* The Bell panel. Accelerators used: [acgo] bdsm wt */
833 ctlposinit(&cp
, hwnd
, 80, 3, 13);
834 bartitle(&cp
, "Options controlling the terminal bell",
836 beginbox(&cp
, "Set the style of bell",
839 "Action to happen when a &bell occurs:", IDC_BELLSTATIC
,
840 "None (bell disabled)", IDC_BELL_DISABLED
,
841 "Play Windows Default Sound", IDC_BELL_DEFAULT
,
842 "Play a custom sound file", IDC_BELL_WAVEFILE
,
843 "Visual bell (flash window)", IDC_BELL_VISUAL
, NULL
);
844 editbutton(&cp
, "Custom sound file to play as a bell:",
845 IDC_BELL_WAVESTATIC
, IDC_BELL_WAVEEDIT
,
846 "Bro&wse...", IDC_BELL_WAVEBROWSE
);
848 beginbox(&cp
, "Control the bell overload behaviour",
850 checkbox(&cp
, "Bell is temporarily &disabled when over-used",
852 staticedit(&cp
, "Over-use means this &many bells...",
853 IDC_BELLOVLNSTATIC
, IDC_BELLOVLN
, 20);
854 staticedit(&cp
, "... in &this many seconds",
855 IDC_BELLOVLTSTATIC
, IDC_BELLOVLT
, 20);
856 statictext(&cp
, "The bell is re-enabled after a few seconds of silence.",
858 staticedit(&cp
, "Seconds of &silence required",
859 IDC_BELLOVLSSTATIC
, IDC_BELLOVLS
, 20);
863 if (panel
== keyboardpanelstart
) {
864 /* The Keyboard panel. Accelerators used: [acgo] h?sr~lxvunpymietd */
866 ctlposinit(&cp
, hwnd
, 80, 3, 13);
867 bartitle(&cp
, "Options controlling the effects of keys",
869 beginbox(&cp
, "Change the sequences sent by:",
871 radioline(&cp
, "The Backspace key", IDC_DELSTATIC
, 2,
872 "Control-&H", IDC_DEL008
,
873 "Control-&? (127)", IDC_DEL127
, NULL
);
874 radioline(&cp
, "The Home and End keys", IDC_HOMESTATIC
, 2,
875 "&Standard", IDC_HOMETILDE
,
876 "&rxvt", IDC_HOMERXVT
, NULL
);
877 radioline(&cp
, "The Function keys and keypad", IDC_FUNCSTATIC
, 4,
878 "ESC[n&~", IDC_FUNCTILDE
,
879 "&Linux", IDC_FUNCLINUX
,
880 "&Xterm R6", IDC_FUNCXTERM
,
881 "&VT400", IDC_FUNCVT400
, NULL
);
883 beginbox(&cp
, "Application keypad settings:",
886 "Application c&ursor keys totally disabled",
888 radioline(&cp
, "Initial state of cursor keys:", IDC_CURSTATIC
, 2,
889 "&Normal", IDC_CURNORMAL
,
890 "A&pplication", IDC_CURAPPLIC
, NULL
);
892 "Application ke&ypad keys totally disabled",
894 radioline(&cp
, "Initial state of numeric keypad:", IDC_KPSTATIC
, 3,
895 "Nor&mal", IDC_KPNORMAL
,
896 "Appl&ication", IDC_KPAPPLIC
,
897 "N&etHack", IDC_KPNH
, NULL
);
899 beginbox(&cp
, "Enable extra keyboard features:",
901 checkbox(&cp
, "AltGr ac&ts as Compose key",
903 checkbox(&cp
, "Control-Alt is &different from AltGr",
908 if (panel
== windowpanelstart
) {
909 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
911 ctlposinit(&cp
, hwnd
, 80, 3, 13);
912 bartitle(&cp
, "Options controlling PuTTY's window",
914 beginbox(&cp
, "Set the size of the window",
917 "&Rows", IDC_ROWSSTATIC
, IDC_ROWSEDIT
, 50,
918 "Colu&mns", IDC_COLSSTATIC
, IDC_COLSEDIT
, 50,
920 checkbox(&cp
, "Lock window size against resi&zing", IDC_LOCKSIZE
);
922 beginbox(&cp
, "Control the scrollback in the window",
924 staticedit(&cp
, "Lines of &scrollback",
925 IDC_SAVESTATIC
, IDC_SAVEEDIT
, 50);
926 checkbox(&cp
, "&Display scrollbar", IDC_SCROLLBAR
);
927 checkbox(&cp
, "Reset scrollback on &keypress", IDC_SCROLLKEY
);
928 checkbox(&cp
, "Reset scrollback on dis&play activity",
931 beginbox(&cp
, NULL
, IDC_BOX_WINDOW3
);
932 checkbox(&cp
, "&Warn before closing window", IDC_CLOSEWARN
);
933 checkbox(&cp
, "Window closes on ALT-F&4", IDC_ALTF4
);
934 checkbox(&cp
, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE
);
935 checkbox(&cp
, "System menu appears on A< alone", IDC_ALTONLY
);
936 checkbox(&cp
, "Ensure window is always on &top", IDC_ALWAYSONTOP
);
940 if (panel
== appearancepanelstart
) {
941 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p */
943 ctlposinit(&cp
, hwnd
, 80, 3, 13);
944 bartitle(&cp
, "Options controlling PuTTY's appearance",
945 IDC_TITLE_APPEARANCE
);
946 beginbox(&cp
, "Adjust the use of the cursor",
947 IDC_BOX_APPEARANCE1
);
948 radioline(&cp
, "Cursor appearance:", IDC_CURSORSTATIC
, 3,
949 "B&lock", IDC_CURBLOCK
,
950 "&Underline", IDC_CURUNDER
,
951 "&Vertical line", IDC_CURVERT
,
953 checkbox(&cp
, "Cursor &blinks", IDC_BLINKCUR
);
955 beginbox(&cp
, "Set the font used in the terminal window",
956 IDC_BOX_APPEARANCE2
);
957 staticbtn(&cp
, "", IDC_FONTSTATIC
, "C&hange...", IDC_CHOOSEFONT
);
959 beginbox(&cp
, "Adjust the use of the window title",
960 IDC_BOX_APPEARANCE3
);
962 "Window &title:", IDC_WINTITLE
,
963 IDC_WINEDIT
, 100, NULL
);
964 checkbox(&cp
, "Avoid ever using &icon title", IDC_WINNAME
);
966 beginbox(&cp
, "Adjust the use of the mouse pointer",
967 IDC_BOX_APPEARANCE4
);
968 checkbox(&cp
, "Hide mouse &pointer when typing in window",
973 if (panel
== translationpanelstart
) {
974 /* The Translation panel. Accelerators used: [acgo] xbep t s */
976 ctlposinit(&cp
, hwnd
, 80, 3, 13);
977 bartitle(&cp
, "Options controlling character set translation",
978 IDC_TITLE_TRANSLATION
);
979 beginbox(&cp
, "Adjust how PuTTY displays line drawing characters",
980 IDC_BOX_TRANSLATION1
);
982 "Handling of line drawing characters:", IDC_VTSTATIC
,
983 "Font has &XWindows encoding", IDC_VTXWINDOWS
,
984 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI
,
985 "Use font in O&EM mode only", IDC_VTOEMONLY
,
986 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
987 IDC_VTPOORMAN
, NULL
);
989 beginbox(&cp
, "Enable character set translation on received data",
990 IDC_BOX_TRANSLATION2
);
992 "Character set &translation:", IDC_XLATSTATIC
,
994 "KOI8 / Win-1251", IDC_KOI8WIN1251
,
995 "ISO-8859-2 / Win-1250", IDC_88592WIN1250
,
996 "ISO-8859-2 / CP852", IDC_88592CP852
, NULL
);
998 beginbox(&cp
, "Enable character set translation on input data",
999 IDC_BOX_TRANSLATION3
);
1000 checkbox(&cp
, "CAP&S LOCK acts as cyrillic switch",
1005 if (panel
== selectionpanelstart
) {
1006 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1008 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1009 bartitle(&cp
, "Options controlling copy and paste",
1010 IDC_TITLE_SELECTION
);
1011 beginbox(&cp
, "Translation of pasted characters",
1012 IDC_BOX_SELECTION1
);
1013 checkbox(&cp
, "&Don't translate line drawing chars into +, - and |",
1016 beginbox(&cp
, "Control which mouse button does which thing",
1017 IDC_BOX_SELECTION2
);
1018 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
1019 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
1020 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
1023 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
1024 IDC_BOX_SELECTION3
);
1025 charclass(&cp
, "C&haracter classes:", IDC_CCSTATIC
, IDC_CCLIST
,
1026 "&Set", IDC_CCSET
, IDC_CCEDIT
,
1027 "&to class", IDC_CCSTATIC2
);
1031 if (panel
== colourspanelstart
) {
1032 /* The Colours panel. Accelerators used: [acgo] blum */
1034 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1035 bartitle(&cp
, "Options controlling use of colours",
1037 beginbox(&cp
, "General options for colour usage",
1039 checkbox(&cp
, "&Bolded text is a different colour", IDC_BOLDCOLOUR
);
1040 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
1042 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
1044 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
1045 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
1046 "&Modify...", IDC_CHANGE
,
1047 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
1048 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
1049 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
1053 if (panel
== connectionpanelstart
) {
1054 /* The Connection panel. Accelerators used: [acgo] tuk */
1056 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1057 bartitle(&cp
, "Options controlling the connection", IDC_TITLE_CONNECTION
);
1059 beginbox(&cp
, "Data to send to the server",
1060 IDC_BOX_CONNECTION1
);
1061 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
, IDC_TTEDIT
, 50);
1062 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
, IDC_LOGEDIT
, 50);
1065 beginbox(&cp
, "Sending of null packets to keep session active",
1066 IDC_BOX_CONNECTION2
);
1067 staticedit(&cp
, "Seconds between &keepalives (0 to turn off)",
1068 IDC_PINGSTATIC
, IDC_PINGEDIT
, 20);
1072 if (panel
== telnetpanelstart
) {
1073 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
1075 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1077 bartitle(&cp
, "Options controlling Telnet connections", IDC_TITLE_TELNET
);
1078 beginbox(&cp
, "Data to send to the server",
1080 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
, IDC_TSEDIT
, 50);
1081 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
1082 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
,
1083 "Va&lue", IDC_VALSTATIC
, IDC_VALEDIT
,
1085 "A&dd", IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
1087 beginbox(&cp
, "Telnet protocol adjustments",
1089 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC
, 2,
1090 "&BSD (commonplace)", IDC_EMBSD
,
1091 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
1096 if (panel
== rloginpanelstart
) {
1097 /* The Rlogin panel. Accelerators used: [acgo] sl */
1099 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1101 bartitle(&cp
, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN
);
1102 beginbox(&cp
, "Data to send to the server",
1104 staticedit(&cp
, "Terminal-&speed string", IDC_R_TSSTATIC
, IDC_R_TSEDIT
, 50);
1105 staticedit(&cp
, "&Local username:", IDC_RLLUSERSTATIC
, IDC_RLLUSEREDIT
, 50);
1110 if (panel
== sshpanelstart
) {
1111 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1113 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1115 bartitle(&cp
, "Options controlling SSH connections", IDC_TITLE_SSH
);
1116 beginbox(&cp
, "Data to send to the server",
1119 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
1122 beginbox(&cp
, "Authentication options",
1124 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
1126 checkbox(&cp
, "Allow agent &forwarding", IDC_AGENTFWD
);
1127 editbutton(&cp
, "Private &key file for authentication:",
1128 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...", IDC_PKBUTTON
);
1130 beginbox(&cp
, "Protocol options",
1132 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
1133 checkbox(&cp
, "Enable compr&ession", IDC_COMPRESS
);
1134 radioline(&cp
, "Preferred SSH protocol version:",
1135 IDC_SSHPROTSTATIC
, 2,
1136 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
1137 radioline(&cp
, "Preferred encryption algorithm:", IDC_CIPHERSTATIC
, 4,
1138 "&3DES", IDC_CIPHER3DES
,
1139 "&Blowfish", IDC_CIPHERBLOWF
,
1140 "&DES", IDC_CIPHERDES
,
1141 "AE&S", IDC_CIPHERAES
,
1143 checkbox(&cp
, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1149 if (panel
== tunnelspanelstart
) {
1150 /* The Tunnels panel. Accelerators used: [acgo] ex */
1152 ctlposinit(&cp
, hwnd
, 80, 3, 13);
1154 bartitle(&cp
, "Options controlling SSH tunnelling",
1156 beginbox(&cp
, "X11 forwarding options",
1158 checkbox(&cp
, "&Enable X11 forwarding",
1160 multiedit(&cp
, "&X display location", IDC_X11_DISPSTATIC
,
1161 IDC_X11_DISPLAY
, 50, NULL
);
1168 * This function is the configuration box.
1170 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1171 WPARAM wParam
, LPARAM lParam
,
1174 struct treeview_faff tvfaff
;
1177 char filename
[sizeof(cfg
.keyfile
)];
1180 char fontstatic
[256];
1182 struct servent
* service
;
1188 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1190 * Centre the window.
1192 { /* centre the window */
1195 hw
= GetDesktopWindow();
1196 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1197 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1198 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1199 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1203 * Create the tree view.
1210 r
.left
= 3; r
.right
= r
.left
+ 75;
1211 r
.top
= 3; r
.bottom
= r
.top
+ 10;
1212 MapDialogRect(hwnd
, &r
);
1213 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
1214 WS_CHILD
| WS_VISIBLE
,
1216 r
.right
-r
.left
, r
.bottom
-r
.top
,
1217 hwnd
, (HMENU
)IDCX_TVSTATIC
, hinst
, NULL
);
1218 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1219 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1221 r
.left
= 3; r
.right
= r
.left
+ 75;
1222 r
.top
= 13; r
.bottom
= r
.top
+ 206;
1223 MapDialogRect(hwnd
, &r
);
1224 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
1225 WS_CHILD
| WS_VISIBLE
|
1226 WS_TABSTOP
| TVS_HASLINES
|
1227 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
|
1228 TVS_LINESATROOT
| TVS_SHOWSELALWAYS
,
1230 r
.right
-r
.left
, r
.bottom
-r
.top
,
1231 hwnd
, (HMENU
)IDCX_TREEVIEW
, hinst
, NULL
);
1232 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1233 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1234 tvfaff
.treeview
= treeview
;
1235 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
1239 * Set up the tree view contents.
1241 hsession
= treeview_insert(&tvfaff
, 0, "Session");
1242 treeview_insert(&tvfaff
, 1, "Logging");
1243 treeview_insert(&tvfaff
, 0, "Terminal");
1244 treeview_insert(&tvfaff
, 1, "Keyboard");
1245 treeview_insert(&tvfaff
, 1, "Bell");
1246 treeview_insert(&tvfaff
, 0, "Window");
1247 treeview_insert(&tvfaff
, 1, "Appearance");
1248 treeview_insert(&tvfaff
, 1, "Translation");
1249 treeview_insert(&tvfaff
, 1, "Selection");
1250 treeview_insert(&tvfaff
, 1, "Colours");
1251 treeview_insert(&tvfaff
, 0, "Connection");
1253 treeview_insert(&tvfaff
, 1, "Telnet");
1254 treeview_insert(&tvfaff
, 1, "Rlogin");
1255 if (backends
[3].backend
!= NULL
) {
1256 treeview_insert(&tvfaff
, 1, "SSH");
1257 treeview_insert(&tvfaff
, 2, "Tunnels");
1262 * Put the treeview selection on to the Session panel. This
1263 * should also cause creation of the relevant controls.
1265 TreeView_SelectItem(treeview
, hsession
);
1268 * Set focus into the first available control.
1272 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
1273 if (!ctl
) ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
1277 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1281 * Button release should trigger WM_OK if there was a
1282 * previous double click on the session list.
1286 SendMessage (hwnd
, WM_COMMAND
, IDOK
, 0);
1289 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1290 ((LPNMHDR
)lParam
)->code
== TVN_SELCHANGED
) {
1291 HTREEITEM i
= TreeView_GetSelection(((LPNMHDR
)lParam
)->hwndFrom
);
1296 item
.pszText
= buffer
;
1297 item
.cchTextMax
= sizeof(buffer
);
1298 item
.mask
= TVIF_TEXT
;
1299 TreeView_GetItem(((LPNMHDR
)lParam
)->hwndFrom
, &item
);
1300 for (j
= controlstartvalue
; j
< controlendvalue
; j
++) {
1301 HWND item
= GetDlgItem(hwnd
, j
);
1303 DestroyWindow(item
);
1305 if (!strcmp(buffer
, "Session"))
1306 create_controls(hwnd
, dlgtype
, sessionpanelstart
);
1307 if (!strcmp(buffer
, "Logging"))
1308 create_controls(hwnd
, dlgtype
, loggingpanelstart
);
1309 if (!strcmp(buffer
, "Keyboard"))
1310 create_controls(hwnd
, dlgtype
, keyboardpanelstart
);
1311 if (!strcmp(buffer
, "Terminal"))
1312 create_controls(hwnd
, dlgtype
, terminalpanelstart
);
1313 if (!strcmp(buffer
, "Bell"))
1314 create_controls(hwnd
, dlgtype
, bellpanelstart
);
1315 if (!strcmp(buffer
, "Window"))
1316 create_controls(hwnd
, dlgtype
, windowpanelstart
);
1317 if (!strcmp(buffer
, "Appearance"))
1318 create_controls(hwnd
, dlgtype
, appearancepanelstart
);
1319 if (!strcmp(buffer
, "Tunnels"))
1320 create_controls(hwnd
, dlgtype
, tunnelspanelstart
);
1321 if (!strcmp(buffer
, "Connection"))
1322 create_controls(hwnd
, dlgtype
, connectionpanelstart
);
1323 if (!strcmp(buffer
, "Telnet"))
1324 create_controls(hwnd
, dlgtype
, telnetpanelstart
);
1325 if (!strcmp(buffer
, "Rlogin"))
1326 create_controls(hwnd
, dlgtype
, rloginpanelstart
);
1327 if (!strcmp(buffer
, "SSH"))
1328 create_controls(hwnd
, dlgtype
, sshpanelstart
);
1329 if (!strcmp(buffer
, "Selection"))
1330 create_controls(hwnd
, dlgtype
, selectionpanelstart
);
1331 if (!strcmp(buffer
, "Colours"))
1332 create_controls(hwnd
, dlgtype
, colourspanelstart
);
1333 if (!strcmp(buffer
, "Translation"))
1334 create_controls(hwnd
, dlgtype
, translationpanelstart
);
1336 init_dlg_ctrls(hwnd
);
1338 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1344 * Only process WM_COMMAND once the dialog is fully formed.
1346 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1) switch (LOWORD(wParam
)) {
1349 EndDialog (hwnd
, 1);
1354 EndDialog (hwnd
, 0);
1356 case IDC_PROTTELNET
:
1357 case IDC_PROTRLOGIN
:
1360 if (HIWORD(wParam
) == BN_CLICKED
||
1361 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1362 int i
= IsDlgButtonChecked (hwnd
, IDC_PROTSSH
);
1363 int j
= IsDlgButtonChecked (hwnd
, IDC_PROTTELNET
);
1364 int k
= IsDlgButtonChecked (hwnd
, IDC_PROTRLOGIN
);
1365 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: k ? PROT_RLOGIN
: PROT_RAW
;
1366 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
!= 22) ||
1367 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
!= 23) ||
1368 (cfg
.protocol
== PROT_RLOGIN
&& cfg
.port
!= 513)) {
1369 cfg
.port
= i ?
22 : j ?
23 : 513;
1370 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1375 if (HIWORD(wParam
) == EN_CHANGE
)
1376 GetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
,
1377 sizeof(cfg
.host
)-1);
1380 if (HIWORD(wParam
) == EN_CHANGE
) {
1381 GetDlgItemText (hwnd
, IDC_PORT
, portname
, 31);
1382 if (isdigit(portname
[0]))
1383 MyGetDlgItemInt (hwnd
, IDC_PORT
, &cfg
.port
);
1385 service
= getservbyname(portname
, NULL
);
1386 if (service
) cfg
.port
= ntohs(service
->s_port
);
1392 if (HIWORD(wParam
) == EN_CHANGE
) {
1393 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1395 GetDlgItemText (hwnd
, IDC_SESSEDIT
,
1396 savedsession
, sizeof(savedsession
)-1);
1397 savedsession
[sizeof(savedsession
)-1] = '\0';
1401 if (HIWORD(wParam
) == BN_CLICKED
||
1402 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1407 GetDlgItemText (hwnd
, IDC_SESSEDIT
, str
, sizeof(str
)-1);
1409 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1410 LB_GETCURSEL
, 0, 0);
1415 strcpy (str
, sessions
[n
]);
1417 save_settings (str
, !!strcmp(str
, "Default Settings"), &cfg
);
1418 get_sesslist (FALSE
);
1419 get_sesslist (TRUE
);
1420 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1422 for (i
= 0; i
< nsessions
; i
++)
1423 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1424 0, (LPARAM
) (sessions
[i
]));
1425 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1431 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1432 HIWORD(wParam
) != BN_CLICKED
&&
1433 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1435 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1436 HIWORD(wParam
) != LBN_DBLCLK
)
1439 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1440 LB_GETCURSEL
, 0, 0);
1446 isdef
= !strcmp(sessions
[n
], "Default Settings");
1447 load_settings (sessions
[n
], !isdef
, &cfg
);
1448 init_dlg_ctrls(hwnd
);
1450 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1452 SetDlgItemText(hwnd
, IDC_SESSEDIT
, "");
1454 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1456 * A double-click on a saved session should
1457 * actually start the session, not just load it.
1458 * Unless it's Default Settings or some other
1459 * host-less set of saved settings.
1468 if (HIWORD(wParam
) == BN_CLICKED
||
1469 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1470 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1471 LB_GETCURSEL
, 0, 0);
1472 if (n
== LB_ERR
|| n
== 0) {
1476 del_settings(sessions
[n
]);
1477 get_sesslist (FALSE
);
1478 get_sesslist (TRUE
);
1479 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1481 for (i
= 0; i
< nsessions
; i
++)
1482 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1483 0, (LPARAM
) (sessions
[i
]));
1484 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1488 if (HIWORD(wParam
) == EN_CHANGE
)
1489 MyGetDlgItemInt (hwnd
, IDC_PINGEDIT
, &cfg
.ping_interval
);
1493 if (HIWORD(wParam
) == BN_CLICKED
||
1494 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1495 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC_DEL127
);
1499 if (HIWORD(wParam
) == BN_CLICKED
||
1500 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1501 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC_HOMERXVT
);
1504 if (HIWORD(wParam
) == BN_CLICKED
||
1505 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1509 if (HIWORD(wParam
) == BN_CLICKED
||
1510 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1515 if (HIWORD(wParam
) == BN_CLICKED
||
1516 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1517 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC_FUNCLINUX
);
1521 if (HIWORD(wParam
) == BN_CLICKED
||
1522 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1523 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC_KPAPPLIC
);
1524 cfg
.nethack_keypad
= FALSE
;
1528 if (HIWORD(wParam
) == BN_CLICKED
||
1529 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1530 cfg
.app_keypad
= FALSE
;
1531 cfg
.nethack_keypad
= TRUE
;
1536 if (HIWORD(wParam
) == BN_CLICKED
||
1537 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1538 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC_CURAPPLIC
);
1541 if (HIWORD(wParam
) == BN_CLICKED
||
1542 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1543 cfg
.no_applic_c
= IsDlgButtonChecked (hwnd
, IDC_NOAPPLICC
);
1546 if (HIWORD(wParam
) == BN_CLICKED
||
1547 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1548 cfg
.no_applic_k
= IsDlgButtonChecked (hwnd
, IDC_NOAPPLICK
);
1551 if (HIWORD(wParam
) == BN_CLICKED
||
1552 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1553 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC_ALTF4
);
1556 if (HIWORD(wParam
) == BN_CLICKED
||
1557 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1558 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC_ALTSPACE
);
1561 if (HIWORD(wParam
) == BN_CLICKED
||
1562 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1563 cfg
.alt_only
= IsDlgButtonChecked (hwnd
, IDC_ALTONLY
);
1565 case IDC_ECHOBACKEND
:
1568 if (HIWORD(wParam
) == BN_CLICKED
||
1569 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1570 if (LOWORD(wParam
)==IDC_ECHOBACKEND
) cfg
.localecho
=LD_BACKEND
;
1571 if (LOWORD(wParam
)==IDC_ECHOYES
) cfg
.localecho
=LD_YES
;
1572 if (LOWORD(wParam
)==IDC_ECHONO
) cfg
.localecho
=LD_NO
;
1575 case IDC_EDITBACKEND
:
1578 if (HIWORD(wParam
) == BN_CLICKED
||
1579 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1580 if (LOWORD(wParam
)==IDC_EDITBACKEND
) cfg
.localedit
=LD_BACKEND
;
1581 if (LOWORD(wParam
)==IDC_EDITYES
) cfg
.localedit
=LD_YES
;
1582 if (LOWORD(wParam
)==IDC_EDITNO
) cfg
.localedit
=LD_NO
;
1585 case IDC_ANSWEREDIT
:
1586 if (HIWORD(wParam
) == EN_CHANGE
)
1587 GetDlgItemText (hwnd
, IDC_ANSWEREDIT
, cfg
.answerback
,
1588 sizeof(cfg
.answerback
)-1);
1590 case IDC_ALWAYSONTOP
:
1591 if (HIWORD(wParam
) == BN_CLICKED
||
1592 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1593 cfg
.alwaysontop
= IsDlgButtonChecked (hwnd
, IDC_ALWAYSONTOP
);
1596 if (HIWORD(wParam
) == BN_CLICKED
||
1597 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1598 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC_SCROLLKEY
);
1600 case IDC_SCROLLDISP
:
1601 if (HIWORD(wParam
) == BN_CLICKED
||
1602 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1603 cfg
.scroll_on_disp
= IsDlgButtonChecked (hwnd
, IDC_SCROLLDISP
);
1605 case IDC_COMPOSEKEY
:
1606 if (HIWORD(wParam
) == BN_CLICKED
||
1607 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1608 cfg
.compose_key
= IsDlgButtonChecked (hwnd
, IDC_COMPOSEKEY
);
1610 case IDC_CTRLALTKEYS
:
1611 if (HIWORD(wParam
) == BN_CLICKED
||
1612 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1613 cfg
.ctrlaltkeys
= IsDlgButtonChecked (hwnd
, IDC_CTRLALTKEYS
);
1616 if (HIWORD(wParam
) == BN_CLICKED
||
1617 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1618 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC_WRAPMODE
);
1621 if (HIWORD(wParam
) == BN_CLICKED
||
1622 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1623 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC_DECOM
);
1626 if (HIWORD(wParam
) == BN_CLICKED
||
1627 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1628 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC_LFHASCR
);
1631 if (HIWORD(wParam
) == EN_CHANGE
)
1632 MyGetDlgItemInt (hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1635 if (HIWORD(wParam
) == EN_CHANGE
)
1636 MyGetDlgItemInt (hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1639 if (HIWORD(wParam
) == EN_CHANGE
)
1640 MyGetDlgItemInt (hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1642 case IDC_CHOOSEFONT
:
1643 lf
.lfHeight
= cfg
.fontheight
;
1644 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1645 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1646 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1647 lf
.lfCharSet
= cfg
.fontcharset
;
1648 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1649 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1650 lf
.lfQuality
= DEFAULT_QUALITY
;
1651 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1652 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
1653 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
1655 cf
.lStructSize
= sizeof(cf
);
1656 cf
.hwndOwner
= hwnd
;
1658 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1659 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1661 if (ChooseFont (&cf
)) {
1662 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
1663 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
1664 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1665 cfg
.fontcharset
= lf
.lfCharSet
;
1666 cfg
.fontheight
= cf
.iPointSize
/ 10;
1667 fmtfont (fontstatic
);
1668 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
1671 case IDC_BELL_DISABLED
:
1672 case IDC_BELL_DEFAULT
:
1673 case IDC_BELL_WAVEFILE
:
1674 case IDC_BELL_VISUAL
:
1675 if (HIWORD(wParam
) == BN_CLICKED
||
1676 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1677 if (LOWORD(wParam
)==IDC_BELL_DISABLED
) cfg
.beep
= BELL_DISABLED
;
1678 if (LOWORD(wParam
)==IDC_BELL_DEFAULT
) cfg
.beep
= BELL_DEFAULT
;
1679 if (LOWORD(wParam
)==IDC_BELL_WAVEFILE
) cfg
.beep
= BELL_WAVEFILE
;
1680 if (LOWORD(wParam
)==IDC_BELL_VISUAL
) cfg
.beep
= BELL_VISUAL
;
1683 case IDC_BELL_WAVEBROWSE
:
1684 memset(&of
, 0, sizeof(of
));
1685 #ifdef OPENFILENAME_SIZE_VERSION_400
1686 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1688 of
.lStructSize
= sizeof(of
);
1690 of
.hwndOwner
= hwnd
;
1691 of
.lpstrFilter
= "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1692 of
.lpstrCustomFilter
= NULL
;
1693 of
.nFilterIndex
= 1;
1694 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.bell_wavefile
);
1695 of
.nMaxFile
= sizeof(filename
);
1696 of
.lpstrFileTitle
= NULL
;
1697 of
.lpstrInitialDir
= NULL
;
1698 of
.lpstrTitle
= "Select Bell Sound File";
1700 if (GetOpenFileName(&of
)) {
1701 strcpy(cfg
.bell_wavefile
, filename
);
1702 SetDlgItemText (hwnd
, IDC_BELL_WAVEEDIT
, cfg
.bell_wavefile
);
1705 case IDC_BELL_WAVEEDIT
:
1706 if (HIWORD(wParam
) == EN_CHANGE
)
1707 GetDlgItemText (hwnd
, IDC_BELL_WAVEEDIT
, cfg
.bell_wavefile
,
1708 sizeof(cfg
.bell_wavefile
)-1);
1711 if (HIWORD(wParam
) == BN_CLICKED
||
1712 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1713 cfg
.bellovl
= IsDlgButtonChecked (hwnd
, IDC_BELLOVL
);
1716 if (HIWORD(wParam
) == EN_CHANGE
)
1717 MyGetDlgItemInt (hwnd
, IDC_BELLOVLN
, &cfg
.bellovl_n
);
1720 if (HIWORD(wParam
) == EN_CHANGE
)
1721 MyGetDlgItemInt (hwnd
, IDC_BELLOVLT
, &cfg
.bellovl_t
);
1724 if (HIWORD(wParam
) == EN_CHANGE
)
1725 MyGetDlgItemInt (hwnd
, IDC_BELLOVLS
, &cfg
.bellovl_s
);
1728 if (HIWORD(wParam
) == BN_CLICKED
||
1729 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1730 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC_BLINKTEXT
);
1733 if (HIWORD(wParam
) == BN_CLICKED
||
1734 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1735 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC_BCE
);
1738 if (HIWORD(wParam
) == BN_CLICKED
||
1739 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1740 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC_WINNAME
);
1743 if (HIWORD(wParam
) == BN_CLICKED
||
1744 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1745 cfg
.hide_mouseptr
= IsDlgButtonChecked (hwnd
, IDC_HIDEMOUSE
);
1748 if (HIWORD(wParam
) == BN_CLICKED
||
1749 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1750 cfg
.cursor_type
= 0;
1753 if (HIWORD(wParam
) == BN_CLICKED
||
1754 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1755 cfg
.cursor_type
= 1;
1758 if (HIWORD(wParam
) == BN_CLICKED
||
1759 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1760 cfg
.cursor_type
= 2;
1763 if (HIWORD(wParam
) == BN_CLICKED
||
1764 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1765 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC_BLINKCUR
);
1768 if (HIWORD(wParam
) == BN_CLICKED
||
1769 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1770 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC_SCROLLBAR
);
1773 if (HIWORD(wParam
) == BN_CLICKED
||
1774 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1775 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC_LOCKSIZE
);
1778 if (HIWORD(wParam
) == EN_CHANGE
)
1779 GetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
1780 sizeof(cfg
.wintitle
)-1);
1785 if (HIWORD(wParam
) == BN_CLICKED
||
1786 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1787 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC_COEALWAYS
) ? COE_ALWAYS
:
1788 IsDlgButtonChecked (hwnd
, IDC_COENEVER
) ? COE_NEVER
:
1793 if (HIWORD(wParam
) == BN_CLICKED
||
1794 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1795 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC_CLOSEWARN
);
1798 if (HIWORD(wParam
) == EN_CHANGE
)
1799 GetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
,
1800 sizeof(cfg
.termtype
)-1);
1803 if (HIWORD(wParam
) == EN_CHANGE
)
1804 GetDlgItemText (hwnd
, IDC_LGFEDIT
, cfg
.logfilename
,
1805 sizeof(cfg
.logfilename
)-1);
1808 memset(&of
, 0, sizeof(of
));
1809 #ifdef OPENFILENAME_SIZE_VERSION_400
1810 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1812 of
.lStructSize
= sizeof(of
);
1814 of
.hwndOwner
= hwnd
;
1815 of
.lpstrFilter
= "All Files\0*\0\0\0";
1816 of
.lpstrCustomFilter
= NULL
;
1817 of
.nFilterIndex
= 1;
1818 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.logfilename
);
1819 of
.nMaxFile
= sizeof(filename
);
1820 of
.lpstrFileTitle
= NULL
;
1821 of
.lpstrInitialDir
= NULL
;
1822 of
.lpstrTitle
= "Select session log file";
1824 if (GetSaveFileName(&of
)) {
1825 strcpy(cfg
.logfilename
, filename
);
1826 SetDlgItemText (hwnd
, IDC_LGFEDIT
, cfg
.logfilename
);
1830 case IDC_LSTATASCII
:
1832 if (HIWORD(wParam
) == BN_CLICKED
||
1833 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1834 if (IsDlgButtonChecked (hwnd
, IDC_LSTATOFF
)) cfg
.logtype
= 0;
1835 if (IsDlgButtonChecked (hwnd
, IDC_LSTATASCII
)) cfg
.logtype
= 1;
1836 if (IsDlgButtonChecked (hwnd
, IDC_LSTATRAW
)) cfg
.logtype
= 2;
1842 if (HIWORD(wParam
) == BN_CLICKED
||
1843 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1844 if (IsDlgButtonChecked (hwnd
, IDC_LSTATXASK
)) cfg
.logxfovr
= LGXF_ASK
;
1845 if (IsDlgButtonChecked (hwnd
, IDC_LSTATXAPN
)) cfg
.logxfovr
= LGXF_APN
;
1846 if (IsDlgButtonChecked (hwnd
, IDC_LSTATXOVR
)) cfg
.logxfovr
= LGXF_OVR
;
1851 if (HIWORD(wParam
) == EN_CHANGE
)
1852 GetDlgItemText (hwnd
, LOWORD(wParam
), cfg
.termspeed
,
1853 sizeof(cfg
.termspeed
)-1);
1856 if (HIWORD(wParam
) == EN_CHANGE
)
1857 GetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
,
1858 sizeof(cfg
.username
)-1);
1860 case IDC_RLLUSEREDIT
:
1861 if (HIWORD(wParam
) == EN_CHANGE
)
1862 GetDlgItemText (hwnd
, IDC_RLLUSEREDIT
, cfg
.localusername
,
1863 sizeof(cfg
.localusername
)-1);
1867 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC_EMRFC
);
1870 if (HIWORD(wParam
) == BN_CLICKED
||
1871 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1872 char str
[sizeof(cfg
.environmt
)];
1874 GetDlgItemText (hwnd
, IDC_VAREDIT
, str
, sizeof(str
)-1);
1879 p
= str
+ strlen(str
);
1881 GetDlgItemText (hwnd
, IDC_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
1891 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
1893 p
[strlen(str
)+1] = '\0';
1894 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
1896 SetDlgItemText (hwnd
, IDC_VAREDIT
, "");
1897 SetDlgItemText (hwnd
, IDC_VALEDIT
, "");
1899 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
1900 MB_OK
| MB_ICONERROR
);
1905 if (HIWORD(wParam
) != BN_CLICKED
&&
1906 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1908 i
= SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0, 0);
1914 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
1939 if (HIWORD(wParam
) == BN_CLICKED
||
1940 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1941 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC_NOPTY
);
1944 if (HIWORD(wParam
) == BN_CLICKED
||
1945 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1946 cfg
.compression
= IsDlgButtonChecked (hwnd
, IDC_COMPRESS
);
1949 if (HIWORD(wParam
) == BN_CLICKED
||
1950 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1951 cfg
.buggymac
= IsDlgButtonChecked (hwnd
, IDC_BUGGYMAC
);
1954 if (HIWORD(wParam
) == BN_CLICKED
||
1955 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1956 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC_AGENTFWD
);
1958 case IDC_CIPHER3DES
:
1959 case IDC_CIPHERBLOWF
:
1962 if (HIWORD(wParam
) == BN_CLICKED
||
1963 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1964 if (IsDlgButtonChecked (hwnd
, IDC_CIPHER3DES
))
1965 cfg
.cipher
= CIPHER_3DES
;
1966 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERBLOWF
))
1967 cfg
.cipher
= CIPHER_BLOWFISH
;
1968 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERDES
))
1969 cfg
.cipher
= CIPHER_DES
;
1970 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERAES
))
1971 cfg
.cipher
= CIPHER_AES
;
1976 if (HIWORD(wParam
) == BN_CLICKED
||
1977 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1978 if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT1
))
1980 else if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT2
))
1985 if (HIWORD(wParam
) == BN_CLICKED
||
1986 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1987 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC_AUTHTIS
);
1990 if (HIWORD(wParam
) == EN_CHANGE
)
1991 GetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
1992 sizeof(cfg
.keyfile
)-1);
1995 if (HIWORD(wParam
) == EN_CHANGE
)
1996 GetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
1997 sizeof(cfg
.remote_cmd
)-1);
2000 memset(&of
, 0, sizeof(of
));
2001 #ifdef OPENFILENAME_SIZE_VERSION_400
2002 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
2004 of
.lStructSize
= sizeof(of
);
2006 of
.hwndOwner
= hwnd
;
2007 of
.lpstrFilter
= "All Files\0*\0\0\0";
2008 of
.lpstrCustomFilter
= NULL
;
2009 of
.nFilterIndex
= 1;
2010 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
2011 of
.nMaxFile
= sizeof(filename
);
2012 of
.lpstrFileTitle
= NULL
;
2013 of
.lpstrInitialDir
= NULL
;
2014 of
.lpstrTitle
= "Select Public Key File";
2016 if (GetOpenFileName(&of
)) {
2017 strcpy(cfg
.keyfile
, filename
);
2018 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
2022 cfg
.rawcnp
= IsDlgButtonChecked (hwnd
, IDC_RAWCNP
);
2025 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC_MBXTERM
);
2031 int n
= GetDlgItemInt (hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
2036 for (i
=0; i
<256; i
++)
2037 if (SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_GETSEL
,
2040 cfg
.wordness
[i
] = n
;
2041 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
2042 LB_DELETESTRING
, i
, 0);
2043 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
2044 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
2046 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
2053 case IDC_BOLDCOLOUR
:
2054 if (HIWORD(wParam
) == BN_CLICKED
||
2055 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2057 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC_BOLDCOLOUR
);
2058 n
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
2059 if (n
!= 12+10*cfg
.bold_colour
) {
2061 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
2062 LB_DELETESTRING
, i
, 0);
2063 for (i
=0; i
<22; i
++)
2064 if (cfg
.bold_colour
|| permcolour
[i
])
2065 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
2067 (LPARAM
) colours
[i
]);
2072 if (HIWORD(wParam
) == BN_CLICKED
||
2073 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2074 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC_PALETTE
);
2076 case IDC_COLOURLIST
:
2077 if (HIWORD(wParam
) == LBN_DBLCLK
||
2078 HIWORD(wParam
) == LBN_SELCHANGE
) {
2079 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
2081 if (!cfg
.bold_colour
)
2082 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
2083 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0], FALSE
);
2084 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1], FALSE
);
2085 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2], FALSE
);
2089 if (HIWORD(wParam
) == BN_CLICKED
||
2090 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2091 static CHOOSECOLOR cc
;
2092 static DWORD custom
[16] = {0}; /* zero initialisers */
2093 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
2095 if (!cfg
.bold_colour
)
2096 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
2097 cc
.lStructSize
= sizeof(cc
);
2098 cc
.hwndOwner
= hwnd
;
2099 cc
.hInstance
= (HWND
)hinst
;
2100 cc
.lpCustColors
= custom
;
2101 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
2103 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
2104 if (ChooseColor(&cc
)) {
2106 (unsigned char) (cc
.rgbResult
& 0xFF);
2108 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
2110 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
2111 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
2113 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
2115 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
2121 case IDC_KOI8WIN1251
:
2122 case IDC_88592WIN1250
:
2123 case IDC_88592CP852
:
2124 cfg
.xlat_enablekoiwin
=
2125 IsDlgButtonChecked (hwnd
, IDC_KOI8WIN1251
);
2126 cfg
.xlat_88592w1250
=
2127 IsDlgButtonChecked (hwnd
, IDC_88592WIN1250
);
2128 cfg
.xlat_88592cp852
=
2129 IsDlgButtonChecked (hwnd
, IDC_88592CP852
);
2131 case IDC_CAPSLOCKCYR
:
2132 if (HIWORD(wParam
) == BN_CLICKED
||
2133 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
2134 cfg
.xlat_capslockcyr
=
2135 IsDlgButtonChecked (hwnd
, IDC_CAPSLOCKCYR
);
2138 case IDC_VTXWINDOWS
:
2143 (IsDlgButtonChecked (hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
:
2144 IsDlgButtonChecked (hwnd
, IDC_VTOEMANSI
) ? VT_OEMANSI
:
2145 IsDlgButtonChecked (hwnd
, IDC_VTOEMONLY
) ? VT_OEMONLY
:
2148 case IDC_X11_FORWARD
:
2149 if (HIWORD(wParam
) == BN_CLICKED
||
2150 HIWORD(wParam
) == BN_DOUBLECLICKED
)
2151 cfg
.x11_forward
= IsDlgButtonChecked (hwnd
, IDC_X11_FORWARD
);
2153 case IDC_X11_DISPLAY
:
2154 if (HIWORD(wParam
) == EN_CHANGE
)
2155 GetDlgItemText (hwnd
, IDC_X11_DISPLAY
, cfg
.x11_display
,
2156 sizeof(cfg
.x11_display
)-1);
2161 EndDialog (hwnd
, 0);
2164 /* Grrr Explorer will maximize Dialogs! */
2166 if (wParam
== SIZE_MAXIMIZED
)
2173 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
2174 WPARAM wParam
, LPARAM lParam
) {
2175 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
2177 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
2178 EnableWindow(hwnd
, 0);
2179 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2180 GetParent(hwnd
), AboutProc
);
2181 EnableWindow(hwnd
, 1);
2182 SetActiveWindow(hwnd
);
2184 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 0);
2187 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
2188 WPARAM wParam
, LPARAM lParam
) {
2189 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 1);
2192 void defuse_showwindow(void) {
2194 * Work around the fact that the app's first call to ShowWindow
2195 * will ignore the default in favour of the shell-provided
2200 hwnd
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2202 ShowWindow(hwnd
, SW_HIDE
);
2203 DestroyWindow(hwnd
);
2207 int do_config (void) {
2211 savedsession
[0] = '\0';
2212 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
2213 get_sesslist(FALSE
);
2218 int do_reconfig (HWND hwnd
) {
2222 backup_cfg
= cfg
; /* structure copy */
2223 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
2225 cfg
= backup_cfg
; /* structure copy */
2230 void logevent (char *string
) {
2234 if (nevents
>= negsize
) {
2236 events
= srealloc (events
, negsize
* sizeof(*events
));
2240 strftime(timebuf
, sizeof(timebuf
), "%Y-%m-%d %H:%M:%S\t", localtime(&t
));
2242 events
[nevents
] = smalloc(strlen(timebuf
)+strlen(string
)+1);
2243 strcpy(events
[nevents
], timebuf
);
2244 strcat(events
[nevents
], string
);
2247 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
2248 0, (LPARAM
)events
[nevents
]);
2249 count
= SendDlgItemMessage (logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
2250 SendDlgItemMessage (logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
-1, 0);
2255 void showeventlog (HWND hwnd
) {
2257 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
2259 ShowWindow (logbox
, SW_SHOWNORMAL
);
2261 SetActiveWindow(logbox
);
2264 void showabout (HWND hwnd
) {
2265 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),hwnd
, AboutProc
);
2268 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
2269 char *keystr
, char *fingerprint
) {
2272 static const char absentmsg
[] =
2273 "The server's host key is not cached in the registry. You\n"
2274 "have no guarantee that the server is the computer you\n"
2276 "The server's key fingerprint is:\n"
2278 "If you trust this host, hit Yes to add the key to\n"
2279 "PuTTY's cache and carry on connecting.\n"
2280 "If you do not trust this host, hit No to abandon the\n"
2283 static const char wrongmsg
[] =
2284 "WARNING - POTENTIAL SECURITY BREACH!\n"
2286 "The server's host key does not match the one PuTTY has\n"
2287 "cached in the registry. This means that either the\n"
2288 "server administrator has changed the host key, or you\n"
2289 "have actually connected to another computer pretending\n"
2290 "to be the server.\n"
2291 "The new key fingerprint is:\n"
2293 "If you were expecting this change and trust the new key,\n"
2294 "hit Yes to update PuTTY's cache and continue connecting.\n"
2295 "If you want to carry on connecting but without updating\n"
2296 "the cache, hit No.\n"
2297 "If you want to abandon the connection completely, hit\n"
2298 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2301 static const char mbtitle
[] = "PuTTY Security Alert";
2304 char message
[160+ /* sensible fingerprint max size */
2305 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
2306 sizeof(absentmsg
) : sizeof(wrongmsg
))];
2309 * Verify the key against the registry.
2311 ret
= verify_host_key(host
, port
, keytype
, keystr
);
2313 if (ret
== 0) /* success - key matched OK */
2315 if (ret
== 2) { /* key was different */
2317 sprintf(message
, wrongmsg
, fingerprint
);
2318 mbret
= MessageBox(NULL
, message
, mbtitle
,
2319 MB_ICONWARNING
| MB_YESNOCANCEL
);
2321 store_host_key(host
, port
, keytype
, keystr
);
2322 if (mbret
== IDCANCEL
)
2325 if (ret
== 1) { /* key was absent */
2327 sprintf(message
, absentmsg
, fingerprint
);
2328 mbret
= MessageBox(NULL
, message
, mbtitle
,
2329 MB_ICONWARNING
| MB_YESNO
);
2332 store_host_key(host
, port
, keytype
, keystr
);
2337 * Ask whether to wipe a session log file before writing to it.
2338 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2340 int askappend(char *filename
) {
2341 static const char mbtitle
[] = "PuTTY Log to File";
2342 static const char msgtemplate
[] =
2343 "The session log file \"%.*s\" already exists.\n"
2344 "You can overwrite it with a new session log,\n"
2345 "append your session log to the end of it,\n"
2346 "or disable session logging for this session.\n"
2347 "Hit Yes to wipe the file, No to append to it,\n"
2348 "or Cancel to disable logging.";
2349 char message
[sizeof(msgtemplate
) + FILENAME_MAX
];
2351 if ( cfg
.logxfovr
!= LGXF_ASK
) {
2352 return ( (cfg
.logxfovr
==LGXF_OVR
) ?
2 : 1);
2354 sprintf(message
, msgtemplate
, FILENAME_MAX
, filename
);
2356 mbret
= MessageBox(NULL
, message
, mbtitle
,
2357 MB_ICONQUESTION
| MB_YESNOCANCEL
);
2360 else if (mbret
== IDNO
)