15 static char **events = NULL;
16 static int nevents = 0, negsize = 0;
19 static int sesslist_has_focus;
20 static int requested_help;
22 static struct prefslist cipherlist;
24 void force_normal(HWND hwnd)
26 static int recurse = 0;
34 wp.length = sizeof(wp);
35 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
36 wp.showCmd = SW_SHOWNORMAL;
37 SetWindowPlacement(hwnd, &wp);
42 static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
46 n = GetDlgItemInt(hwnd, id, &ok, FALSE);
51 static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
55 ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
57 *result = (int) (scale * atof(text));
60 static void MySetDlgItemFlt(HWND hwnd, int id, double value)
63 sprintf(text, "%g", value);
64 SetDlgItemText(hwnd, id, text);
67 static int CALLBACK LogProc(HWND hwnd, UINT msg,
68 WPARAM wParam, LPARAM lParam)
75 static int tabs[4] = { 78, 108 };
76 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
79 for (i = 0; i < nevents; i++)
80 SendDlgItemMessage(hwnd, IDN_LIST, LB_ADDSTRING,
81 0, (LPARAM) events[i]);
84 switch (LOWORD(wParam)) {
88 SetActiveWindow(GetParent(hwnd));
92 if (HIWORD(wParam) == BN_CLICKED ||
93 HIWORD(wParam) == BN_DOUBLECLICKED) {
96 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
97 LB_GETSELCOUNT, 0, 0);
98 if (selcount == 0) { /* don't even try to copy zero items */
103 selitems = smalloc(selcount * sizeof(int));
105 int count = SendDlgItemMessage(hwnd, IDN_LIST,
112 static unsigned char sel_nl[] = SEL_NL;
114 if (count == 0) { /* can't copy zero stuff */
120 for (i = 0; i < count; i++)
122 strlen(events[selitems[i]]) + sizeof(sel_nl);
124 clipdata = smalloc(size);
127 for (i = 0; i < count; i++) {
128 char *q = events[selitems[i]];
129 int qlen = strlen(q);
132 memcpy(p, sel_nl, sizeof(sel_nl));
135 write_aclip(clipdata, size, TRUE);
140 for (i = 0; i < nevents; i++)
141 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
150 SetActiveWindow(GetParent(hwnd));
157 static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
158 WPARAM wParam, LPARAM lParam)
164 switch (LOWORD(wParam)) {
177 static int CALLBACK AboutProc(HWND hwnd, UINT msg,
178 WPARAM wParam, LPARAM lParam)
182 SetDlgItemText(hwnd, IDA_VERSION, ver);
185 switch (LOWORD(wParam)) {
188 EndDialog(hwnd, TRUE);
191 EnableWindow(hwnd, 0);
192 DialogBox(hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
194 EnableWindow(hwnd, 1);
195 SetActiveWindow(hwnd);
199 /* Load web browser */
200 ShellExecute(hwnd, "open",
201 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
202 0, 0, SW_SHOWDEFAULT);
207 EndDialog(hwnd, TRUE);
214 * Null dialog procedure.
216 static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
217 WPARAM wParam, LPARAM lParam)
222 static char savedsession[2048];
225 IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
363 IDC_SCROLLBARFULLSCREEN,
378 IDC_FULLSCREENONALTENTER,
381 appearancepanelstart,
382 IDC_TITLE_APPEARANCE,
404 connectionpanelstart,
405 IDC_TITLE_CONNECTION,
523 translationpanelstart,
524 IDC_TITLE_TRANSLATION,
525 IDC_BOX_TRANSLATION1,
526 IDC_BOX_TRANSLATION2,
527 IDC_BOX_TRANSLATION3,
564 static const char *const colours[] = {
565 "Default Foreground", "Default Bold Foreground",
566 "Default Background", "Default Bold Background",
567 "Cursor Text", "Cursor Colour",
568 "ANSI Black", "ANSI Black Bold",
569 "ANSI Red", "ANSI Red Bold",
570 "ANSI Green", "ANSI Green Bold",
571 "ANSI Yellow", "ANSI Yellow Bold",
572 "ANSI Blue", "ANSI Blue Bold",
573 "ANSI Magenta", "ANSI Magenta Bold",
574 "ANSI Cyan", "ANSI Cyan Bold",
575 "ANSI White", "ANSI White Bold"
577 static const int permcolour[] = {
578 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
579 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
580 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
583 static void fmtfont(char *buf)
585 sprintf(buf, "Font: %s, ", cfg.font);
587 strcat(buf, "bold, ");
588 if (cfg.fontheight == 0)
589 strcat(buf, "default height");
591 sprintf(buf + strlen(buf), "%d-point",
592 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
595 char *help_context_cmd(int id)
607 return "JI(`',`session.hostname')";
614 return "JI(`',`session.saved')";
619 return "JI(`',`session.coe')";
620 case IDC_LSTATSTATIC:
624 return "JI(`',`logging.main')";
629 return "JI(`',`logging.filename')";
634 return "JI(`',`logging.exists')";
639 return "JI(`',`keyboard.backspace')";
643 return "JI(`',`keyboard.homeend')";
651 return "JI(`',`keyboard.funkeys')";
656 return "JI(`',`keyboard.appkeypad')";
661 return "JI(`',`keyboard.appcursor')";
663 return "JI(`',`keyboard.nethack')";
665 return "JI(`',`keyboard.compose')";
666 case IDC_CTRLALTKEYS:
667 return "JI(`',`keyboard.ctrlalt')";
670 return "JI(`',`terminal.autowrap')";
672 return "JI(`',`terminal.decom')";
674 return "JI(`',`terminal.lfhascr')";
676 return "JI(`',`terminal.bce')";
678 return "JI(`',`terminal.blink')";
681 return "JI(`',`terminal.answerback')";
683 case IDC_ECHOBACKEND:
686 return "JI(`',`terminal.localecho')";
688 case IDC_EDITBACKEND:
691 return "JI(`',`terminal.localedit')";
694 case IDC_BELL_DISABLED:
695 case IDC_BELL_DEFAULT:
696 case IDC_BELL_WAVEFILE:
697 case IDC_BELL_VISUAL:
698 case IDC_BELL_WAVESTATIC:
699 case IDC_BELL_WAVEEDIT:
700 case IDC_BELL_WAVEBROWSE:
701 return "JI(`',`bell.style')";
702 case IDC_B_IND_STATIC:
703 case IDC_B_IND_DISABLED:
704 case IDC_B_IND_FLASH:
705 case IDC_B_IND_STEADY:
706 return "JI(`',`bell.taskbar')";
708 case IDC_BELLOVLNSTATIC:
710 case IDC_BELLOVLTSTATIC:
712 case IDC_BELLOVLEXPLAIN:
713 case IDC_BELLOVLSSTATIC:
715 return "JI(`',`bell.overload')";
721 return "JI(`',`window.size')";
722 case IDC_RESIZESTATIC:
726 case IDC_RESIZEEITHER:
727 return "JI(`',`window.resize')";
729 case IDC_SCROLLBARFULLSCREEN:
734 return "JI(`',`window.scrollback')";
737 return "JI(`',`behaviour.closewarn')";
739 return "JI(`',`behaviour.altf4')";
741 return "JI(`',`behaviour.altspace')";
743 return "JI(`',`behaviour.altonly')";
744 case IDC_ALWAYSONTOP:
745 return "JI(`',`behaviour.alwaysontop')";
746 case IDC_FULLSCREENONALTENTER:
747 return "JI(`',`behaviour.altenter')";
749 case IDC_CURSORSTATIC:
754 return "JI(`',`appearance.cursor')";
757 return "JI(`',`appearance.font')";
761 return "JI(`',`appearance.title')";
763 return "JI(`',`appearance.hidemouse')";
767 return "JI(`',`appearance.border')";
771 return "JI(`',`connection.termtype')";
774 return "JI(`',`connection.username')";
777 return "JI(`',`connection.keepalive')";
779 return "JI(`',`connection.nodelay')";
783 return "JI(`',`telnet.termspeed')";
792 return "JI(`',`telnet.environ')";
796 return "JI(`',`telnet.oldenviron')";
800 return "JI(`',`telnet.passive')";
802 return "JI(`',`telnet.specialkeys')";
806 return "JI(`',`rlogin.termspeed')";
807 case IDC_RLLUSERSTATIC:
808 case IDC_RLLUSEREDIT:
809 return "JI(`',`rlogin.localuser')";
812 return "JI(`',`ssh.nopty')";
813 case IDC_CIPHERSTATIC2:
818 return "JI(`',`ssh.ciphers')";
820 return "JI(`',`ssh.buggymac')";
821 case IDC_SSHPROTSTATIC:
824 return "JI(`',`ssh.protocol')";
827 return "JI(`',`ssh.command')";
829 return "JI(`',`ssh.compress')";
834 return "JI(`',`ssh.auth.privkey')";
836 return "JI(`',`ssh.auth.agentfwd')";
838 return "JI(`',`ssh.auth.changeuser')";
840 return "JI(`',`ssh.auth.tis')";
842 return "JI(`',`ssh.auth.ki')";
847 return "JI(`',`selection.buttons')";
848 case IDC_MOUSEOVERRIDE:
849 return "JI(`',`selection.shiftdrag')";
850 case IDC_SELTYPESTATIC:
852 case IDC_SELTYPERECT:
853 return "JI(`',`selection.rect')";
859 return "JI(`',`selection.charclasses')";
861 return "JI(`',`selection.linedraw')";
863 return "JI(`',`selection.rtf')";
866 return "JI(`',`colours.bold')";
868 return "JI(`',`colours.logpal')";
869 case IDC_COLOURSTATIC:
878 return "JI(`',`colours.config')";
880 case IDC_CODEPAGESTATIC:
882 return "JI(`',`translation.codepage')";
883 case IDC_CAPSLOCKCYR:
884 return "JI(`',`translation.cyrillic')";
891 return "JI(`',`translation.linedraw')";
893 case IDC_X11_FORWARD:
894 case IDC_X11_DISPSTATIC:
895 case IDC_X11_DISPLAY:
896 return "JI(`',`ssh.tunnels.x11')";
899 case IDC_PFWDSTATIC2:
903 case IDC_SPORTSTATIC:
905 case IDC_DPORTSTATIC:
909 return "JI(`',`ssh.tunnels.portfwd')";
916 /* 2nd arg: NZ => don't redraw session list (use when loading
918 static void init_dlg_ctrls(HWND hwnd, int keepsess)
921 char fontstatic[256];
923 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
924 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
927 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
928 for (i = n; i-- > 0;)
929 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
930 for (i = 0; i < nsessions; i++)
931 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
932 0, (LPARAM) (sessions[i]));
934 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
935 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
936 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
937 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
939 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
940 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
941 CheckDlgButton(hwnd, IDC_NODELAY, cfg.tcp_nodelay);
943 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
944 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
945 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
946 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
947 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
948 cfg.funky_type == 0 ? IDC_FUNCTILDE :
949 cfg.funky_type == 1 ? IDC_FUNCLINUX :
950 cfg.funky_type == 2 ? IDC_FUNCXTERM :
951 cfg.funky_type == 3 ? IDC_FUNCVT400 :
952 cfg.funky_type == 4 ? IDC_FUNCVT100P :
953 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
954 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
955 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
956 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
957 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
958 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
959 cfg.nethack_keypad ? IDC_KPNH :
960 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
961 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
962 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
963 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
964 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
965 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
966 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
967 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
968 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
969 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
970 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
971 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
972 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
973 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
974 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
975 CheckDlgButton(hwnd, IDC_FULLSCREENONALTENTER, cfg.fullscreenonaltenter);
976 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
977 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
979 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
980 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
981 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
982 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
983 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
984 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
986 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
987 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
988 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
989 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
990 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
992 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
993 CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
995 B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
996 B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
997 B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
998 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
999 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
1000 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
1001 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
1002 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
1004 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
1005 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
1007 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
1008 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
1009 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
1010 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
1011 SetDlgItemInt(hwnd, IDC_WINBEDIT, cfg.window_border, FALSE);
1012 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
1013 cfg.cursor_type == 0 ? IDC_CURBLOCK :
1014 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
1015 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
1016 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
1017 CheckDlgButton(hwnd, IDC_SCROLLBARFULLSCREEN, cfg.scrollbar_in_fullscreen);
1018 CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZEEITHER,
1019 cfg.resize_action == RESIZE_TERM ? IDC_RESIZETERM :
1020 cfg.resize_action == RESIZE_FONT ? IDC_RESIZEFONT :
1021 cfg.resize_action == RESIZE_EITHER ? IDC_RESIZEEITHER :
1023 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
1024 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
1025 cfg.close_on_exit ==
1026 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
1027 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
1029 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
1030 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
1031 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
1032 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
1033 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
1034 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
1035 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
1036 cfg.logtype == 0 ? IDC_LSTATOFF :
1037 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
1038 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
1039 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
1040 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
1043 char *p = cfg.environmt;
1044 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
1046 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
1052 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
1057 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
1058 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
1059 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
1060 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
1062 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
1063 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
1064 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
1065 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
1066 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
1067 CheckDlgButton(hwnd, IDC_SSH2DES, cfg.ssh2_des_cbc);
1068 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
1069 CheckDlgButton(hwnd, IDC_CHANGEUSER, cfg.change_username);
1070 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
1071 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
1072 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
1073 CheckDlgButton(hwnd, IDC_AUTHKI, cfg.try_ki_auth);
1074 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
1075 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
1079 static const struct { char *s; int c; } ciphers[] = {
1080 { "3DES", CIPHER_3DES },
1081 { "Blowfish", CIPHER_BLOWFISH },
1082 { "DES", CIPHER_DES },
1083 { "AES (SSH 2 only)", CIPHER_AES },
1084 { "-- warn below here --", CIPHER_WARN }
1087 /* Set up the "selected ciphers" box. */
1088 /* (cipherlist assumed to contain all ciphers) */
1089 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0);
1090 for (i = 0; i < CIPHER_MAX; i++) {
1091 int c = cfg.ssh_cipherlist[i];
1094 for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
1095 if (ciphers[j].c == c) {
1096 cstr = ciphers[j].s;
1100 pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING,
1102 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA,
1108 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
1109 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
1110 CheckRadioButton(hwnd, IDC_SELTYPELEX, IDC_SELTYPERECT,
1111 cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT);
1112 CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
1113 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
1114 CheckDlgButton(hwnd, IDC_RTFPASTE, cfg.rtf_paste);
1116 static int tabs[4] = { 25, 61, 96, 128 };
1117 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
1120 for (i = 0; i < 128; i++) {
1122 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1123 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
1124 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
1128 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
1129 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
1132 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1133 for (i = n; i-- > 0;)
1134 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
1135 LB_DELETESTRING, i, 0);
1136 for (i = 0; i < 22; i++)
1137 if (cfg.bold_colour || permcolour[i])
1138 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
1139 (LPARAM) colours[i]);
1141 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
1142 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
1143 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
1144 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
1149 strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
1150 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
1151 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1152 for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
1153 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
1156 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
1159 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
1160 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
1161 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
1162 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
1163 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
1166 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
1167 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
1169 CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
1170 CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
1173 struct treeview_faff {
1175 HTREEITEM lastat[4];
1178 static HTREEITEM treeview_insert(struct treeview_faff *faff,
1179 int level, char *text)
1184 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
1185 ins.hInsertAfter = faff->lastat[level];
1186 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
1187 #define INSITEM DUMMYUNIONNAME.item
1189 #define INSITEM item
1191 ins.INSITEM.mask = TVIF_TEXT;
1192 ins.INSITEM.pszText = text;
1193 newitem = TreeView_InsertItem(faff->treeview, &ins);
1195 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
1197 faff->lastat[level] = newitem;
1198 for (i = level + 1; i < 4; i++)
1199 faff->lastat[i] = NULL;
1204 * Create the panelfuls of controls in the configuration box.
1206 static void create_controls(HWND hwnd, int dlgtype, int panel)
1208 if (panel == sessionpanelstart) {
1209 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
1211 ctlposinit(&cp, hwnd, 80, 3, 13);
1212 bartitle(&cp, "Basic options for your PuTTY session",
1215 beginbox(&cp, "Specify your connection by host name or IP address",
1218 "Host &Name (or IP address)",
1219 IDC_HOSTSTATIC, IDC_HOST, 75,
1220 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
1221 if (backends[3].backend == NULL) {
1222 /* this is PuTTYtel, so only three protocols available */
1223 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
1224 "&Raw", IDC_PROTRAW,
1225 "&Telnet", IDC_PROTTELNET,
1226 "Rlog&in", IDC_PROTRLOGIN, NULL);
1228 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
1229 "&Raw", IDC_PROTRAW,
1230 "&Telnet", IDC_PROTTELNET,
1231 "Rlog&in", IDC_PROTRLOGIN,
1240 beginbox(&cp, "Load, save or delete a stored session",
1242 sesssaver(&cp, "Sav&ed Sessions",
1243 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
1244 "&Load", IDC_SESSLOAD,
1245 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
1248 beginbox(&cp, NULL, IDC_BOX_SESSION3);
1249 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
1250 "Always", IDC_COEALWAYS,
1251 "Never", IDC_COENEVER,
1252 "Only on clean exit", IDC_COENORMAL, NULL);
1256 if (panel == loggingpanelstart) {
1257 /* The Logging panel. Accelerators used: [acgo] tplfwe */
1259 ctlposinit(&cp, hwnd, 80, 3, 13);
1260 bartitle(&cp, "Options controlling session logging",
1262 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
1264 "Session logging:", IDC_LSTATSTATIC,
1265 "Logging &turned off completely", IDC_LSTATOFF,
1266 "Log &printable output only", IDC_LSTATASCII,
1267 "&Log all session output", IDC_LSTATRAW, NULL);
1268 editbutton(&cp, "Log &file name:",
1269 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
1271 statictext(&cp, "(Log file name can contain &&Y, &&M, &&D for date,"
1272 " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN);
1274 "What to do if the log file already &exists:",
1275 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
1276 "Always append to the end of it", IDC_LSTATXAPN,
1277 "Ask the user every time", IDC_LSTATXASK, NULL);
1281 if (panel == terminalpanelstart) {
1282 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
1284 ctlposinit(&cp, hwnd, 80, 3, 13);
1285 bartitle(&cp, "Options controlling the terminal emulation",
1286 IDC_TITLE_TERMINAL);
1287 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
1288 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
1289 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
1290 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
1291 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
1292 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
1294 "An&swerback to ^E:", IDC_ANSWERBACK,
1295 IDC_ANSWEREDIT, 100, NULL);
1298 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
1299 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
1300 "Auto", IDC_ECHOBACKEND,
1301 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
1302 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
1303 "Auto", IDC_EDITBACKEND,
1304 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
1308 if (panel == bellpanelstart) {
1309 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
1311 ctlposinit(&cp, hwnd, 80, 3, 13);
1312 bartitle(&cp, "Options controlling the terminal bell",
1314 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
1316 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
1317 "None (bell disabled)", IDC_BELL_DISABLED,
1318 "Play Windows Default Sound", IDC_BELL_DEFAULT,
1319 "Play a custom sound file", IDC_BELL_WAVEFILE,
1320 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
1321 editbutton(&cp, "Custom sound file to play as a bell:",
1322 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
1323 "Bro&wse...", IDC_BELL_WAVEBROWSE);
1324 radioline(&cp, "Taskbar/caption &indication on bell:",
1325 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
1326 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
1329 beginbox(&cp, "Control the bell overload behaviour",
1331 checkbox(&cp, "Bell is temporarily &disabled when over-used",
1333 staticedit(&cp, "Over-use means this &many bells...",
1334 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
1335 staticedit(&cp, "... in &this many seconds",
1336 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
1338 "The bell is re-enabled after a few seconds of silence.",
1339 1, IDC_BELLOVLEXPLAIN);
1340 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
1345 if (panel == keyboardpanelstart) {
1346 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
1348 ctlposinit(&cp, hwnd, 80, 3, 13);
1349 bartitle(&cp, "Options controlling the effects of keys",
1350 IDC_TITLE_KEYBOARD);
1351 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
1352 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
1353 "Control-H", IDC_DEL008,
1354 "Control-? (127)", IDC_DEL127, NULL);
1355 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
1356 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
1357 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
1358 "ESC[n~", IDC_FUNCTILDE,
1359 "Linux", IDC_FUNCLINUX,
1360 "Xterm R6", IDC_FUNCXTERM,
1361 "VT400", IDC_FUNCVT400,
1362 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
1364 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
1366 "Application c&ursor keys totally disabled",
1368 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
1369 "Normal", IDC_CURNORMAL,
1370 "Application", IDC_CURAPPLIC, NULL);
1372 "Application ke&ypad keys totally disabled",
1374 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
1375 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
1376 "NetHack", IDC_KPNH, NULL);
1378 beginbox(&cp, "Enable extra keyboard features:",
1380 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
1381 checkbox(&cp, "Control-Alt is &different from AltGr",
1386 if (panel == windowpanelstart) {
1387 /* The Window panel. Accelerators used: [acgo] rmz sdikp */
1389 ctlposinit(&cp, hwnd, 80, 3, 13);
1390 bartitle(&cp, "Options controlling PuTTY's window",
1392 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
1394 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
1395 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
1396 radiobig(&cp, "When window is resi&zed:", IDC_RESIZESTATIC,
1397 "Change the number of rows and columns", IDC_RESIZETERM,
1398 "Change the size of the font", IDC_RESIZEFONT,
1399 "Change font size only when maximised", IDC_RESIZEEITHER,
1400 "Forbid resizing completely", IDC_RESIZENONE, NULL);
1402 beginbox(&cp, "Control the scrollback in the window",
1404 staticedit(&cp, "Lines of &scrollback",
1405 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
1406 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
1407 checkbox(&cp, "D&isplay scrollbar in full screen mode", IDC_SCROLLBARFULLSCREEN);
1408 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
1409 checkbox(&cp, "Reset scrollback on dis&play activity",
1414 if (panel == appearancepanelstart) {
1415 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
1417 ctlposinit(&cp, hwnd, 80, 3, 13);
1418 bartitle(&cp, "Configure the appearance of PuTTY's window",
1419 IDC_TITLE_APPEARANCE);
1420 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
1421 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
1422 "B&lock", IDC_CURBLOCK,
1423 "&Underline", IDC_CURUNDER,
1424 "&Vertical line", IDC_CURVERT, NULL);
1425 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
1427 beginbox(&cp, "Set the font used in the terminal window",
1428 IDC_BOX_APPEARANCE2);
1429 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
1431 beginbox(&cp, "Adjust the use of the window title",
1432 IDC_BOX_APPEARANCE3);
1434 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1435 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1437 beginbox(&cp, "Adjust the use of the mouse pointer",
1438 IDC_BOX_APPEARANCE4);
1439 checkbox(&cp, "Hide mouse &pointer when typing in window",
1442 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1443 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1445 staticedit(&cp, "Gap between text and window edge",
1446 IDC_WINBSTATIC, IDC_WINBEDIT, 20);
1450 if (panel == behaviourpanelstart) {
1451 /* The Behaviour panel. Accelerators used: [acgo] w4yltf */
1453 ctlposinit(&cp, hwnd, 80, 3, 13);
1454 bartitle(&cp, "Configure the behaviour of PuTTY's window",
1456 beginbox(&cp, NULL, IDC_BOX_BEHAVIOUR1);
1457 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
1458 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
1459 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
1460 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
1461 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
1462 checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
1466 if (panel == translationpanelstart) {
1467 /* The Translation panel. Accelerators used: [acgo] rxbepus */
1469 ctlposinit(&cp, hwnd, 80, 3, 13);
1470 bartitle(&cp, "Options controlling character set translation",
1471 IDC_TITLE_TRANSLATION);
1472 beginbox(&cp, "Character set translation on received data",
1473 IDC_BOX_TRANSLATION1);
1474 combobox(&cp, "&Received data assumed to be in which character set:",
1475 IDC_CODEPAGESTATIC, IDC_CODEPAGE);
1477 beginbox(&cp, "Enable character set translation on input data",
1478 IDC_BOX_TRANSLATION2);
1479 checkbox(&cp, "Cap&s Lock acts as Cyrillic switch",
1482 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1483 IDC_BOX_TRANSLATION3);
1485 "Handling of line drawing characters:", IDC_VTSTATIC,
1486 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1487 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1488 "Use font in O&EM mode only", IDC_VTOEMONLY,
1489 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1490 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1494 if (panel == selectionpanelstart) {
1495 /* The Selection panel. Accelerators used: [acgo] df wxp hst nr */
1497 ctlposinit(&cp, hwnd, 80, 3, 13);
1498 bartitle(&cp, "Options controlling copy and paste",
1499 IDC_TITLE_SELECTION);
1500 beginbox(&cp, "Translation of pasted characters",
1501 IDC_BOX_SELECTION1);
1503 "&Don't translate line drawing chars into +, - and |",
1506 "Paste to clipboard in RT&F as well as plain text",
1509 beginbox(&cp, "Control which mouse button does which thing",
1510 IDC_BOX_SELECTION2);
1511 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1512 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1513 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1516 "Shift overrides a&pplication's use of mouse",
1519 "Default selection mode (Alt+drag does the other one):",
1520 IDC_SELTYPESTATIC, 2,
1521 "&Normal", IDC_SELTYPELEX,
1522 "&Rectangular block", IDC_SELTYPERECT, NULL);
1524 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1525 IDC_BOX_SELECTION3);
1526 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1527 "&Set", IDC_CCSET, IDC_CCEDIT,
1528 "&to class", IDC_CCSTATIC2);
1532 if (panel == colourspanelstart) {
1533 /* The Colours panel. Accelerators used: [acgo] blum */
1535 ctlposinit(&cp, hwnd, 80, 3, 13);
1536 bartitle(&cp, "Options controlling use of colours",
1538 beginbox(&cp, "General options for colour usage",
1540 checkbox(&cp, "&Bolded text is a different colour",
1542 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1544 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1546 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1547 IDC_COLOURSTATIC, IDC_COLOURLIST,
1548 "&Modify...", IDC_CHANGE,
1549 "Red:", IDC_RSTATIC, IDC_RVALUE,
1550 "Green:", IDC_GSTATIC, IDC_GVALUE,
1551 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1555 if (panel == connectionpanelstart) {
1556 /* The Connection panel. Accelerators used: [acgo] tukn */
1558 ctlposinit(&cp, hwnd, 80, 3, 13);
1559 bartitle(&cp, "Options controlling the connection",
1560 IDC_TITLE_CONNECTION);
1562 beginbox(&cp, "Data to send to the server",
1563 IDC_BOX_CONNECTION1);
1564 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1566 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1570 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1571 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1575 beginbox(&cp, "Sending of null packets to keep session active",
1576 IDC_BOX_CONNECTION2);
1577 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1578 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1581 beginbox(&cp, "Low-level TCP connection options",
1582 IDC_BOX_CONNECTION3);
1583 checkbox(&cp, "Disable &Nagle's algorithm (TCP_NODELAY option)",
1589 if (panel == telnetpanelstart) {
1590 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1592 ctlposinit(&cp, hwnd, 80, 3, 13);
1594 bartitle(&cp, "Options controlling Telnet connections",
1596 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1597 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1599 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1600 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1601 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1602 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1604 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1605 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1606 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1607 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1608 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1609 "Passive", IDC_TPASSIVE, "Active",
1611 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1617 if (panel == rloginpanelstart) {
1618 /* The Rlogin panel. Accelerators used: [acgo] sl */
1620 ctlposinit(&cp, hwnd, 80, 3, 13);
1622 bartitle(&cp, "Options controlling Rlogin connections",
1624 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1625 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1627 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1628 IDC_RLLUSEREDIT, 50);
1633 if (panel == sshpanelstart) {
1634 /* The SSH panel. Accelerators used: [acgo] r pe12i sd */
1636 ctlposinit(&cp, hwnd, 80, 3, 13);
1638 bartitle(&cp, "Options controlling SSH connections",
1640 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1642 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1645 beginbox(&cp, "Protocol options", IDC_BOX_SSH2);
1646 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1647 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1648 radioline(&cp, "Preferred SSH protocol version:",
1649 IDC_SSHPROTSTATIC, 2,
1650 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1651 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1654 beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
1655 prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
1656 IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
1658 checkbox(&cp, "Enable non-standard use of single-&DES in SSH 2",
1664 if (panel == sshauthpanelstart) {
1665 /* The SSH authentication panel. Accelerators used: [acgo] m fkiw */
1667 ctlposinit(&cp, hwnd, 80, 3, 13);
1669 bartitle(&cp, "Options controlling SSH authentication",
1671 beginbox(&cp, "Authentication methods",
1673 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication (SSH1)",
1675 checkbox(&cp, "Attempt \"keyboard-&interactive\" authentication"
1676 " (SSH2)", IDC_AUTHKI);
1678 beginbox(&cp, "Authentication parameters",
1680 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1681 checkbox(&cp, "Allow attempted changes of &username in SSH2",
1683 editbutton(&cp, "Private &key file for authentication:",
1684 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1690 if (panel == tunnelspanelstart) {
1691 /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
1693 ctlposinit(&cp, hwnd, 80, 3, 13);
1695 bartitle(&cp, "Options controlling SSH tunnelling",
1697 beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
1698 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1699 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1700 IDC_X11_DISPLAY, 50, NULL);
1702 beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
1703 checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL);
1704 staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
1705 "&Remove", IDC_PFWDREMOVE);
1706 fwdsetter(&cp, IDC_PFWDLIST,
1707 "Add new forwarded port:", IDC_PFWDSTATIC2,
1708 "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
1709 "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
1710 "A&dd", IDC_PFWDADD);
1711 bareradioline(&cp, 2,
1712 "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL);
1720 * Helper function to load the session selected in SESSLIST
1721 * if any, as this is done in more than one place in
1722 * GenericMainDlgProc(). 0 => failure.
1724 static int load_selected_session(HWND hwnd)
1726 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1727 LB_GETCURSEL, 0, 0);
1733 isdef = !strcmp(sessions[n], "Default Settings");
1734 load_settings(sessions[n], !isdef, &cfg);
1735 init_dlg_ctrls(hwnd, TRUE);
1737 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1739 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1740 /* Restore the selection, which will have been clobbered by
1741 * SESSEDIT handling. */
1742 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1747 * This function is the configuration box.
1749 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1750 WPARAM wParam, LPARAM lParam, int dlgtype)
1753 struct treeview_faff tvfaff;
1756 char filename[sizeof(cfg.keyfile)];
1759 char fontstatic[256];
1761 struct servent *service;
1763 static UINT draglistmsg = WM_NULL;
1768 SetWindowLong(hwnd, GWL_USERDATA, 0);
1770 SetWindowLong(hwnd, GWL_EXSTYLE,
1771 GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
1773 HWND item = GetDlgItem(hwnd, IDC_HELPBTN);
1775 DestroyWindow(item);
1777 requested_help = FALSE;
1778 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1779 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1781 * Centre the window.
1783 { /* centre the window */
1786 hw = GetDesktopWindow();
1787 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1789 (rs.right + rs.left + rd.left - rd.right) / 2,
1790 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1791 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1795 * Create the tree view.
1803 r.right = r.left + 75;
1805 r.bottom = r.top + 10;
1806 MapDialogRect(hwnd, &r);
1807 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1808 WS_CHILD | WS_VISIBLE,
1810 r.right - r.left, r.bottom - r.top,
1811 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1813 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1814 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1817 r.right = r.left + 75;
1819 r.bottom = r.top + 219;
1820 MapDialogRect(hwnd, &r);
1821 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1822 WS_CHILD | WS_VISIBLE |
1823 WS_TABSTOP | TVS_HASLINES |
1824 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1826 TVS_SHOWSELALWAYS, r.left, r.top,
1827 r.right - r.left, r.bottom - r.top,
1828 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1830 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1831 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1832 tvfaff.treeview = treeview;
1833 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1837 * Set up the tree view contents.
1839 hsession = treeview_insert(&tvfaff, 0, "Session");
1840 treeview_insert(&tvfaff, 1, "Logging");
1841 treeview_insert(&tvfaff, 0, "Terminal");
1842 treeview_insert(&tvfaff, 1, "Keyboard");
1843 treeview_insert(&tvfaff, 1, "Bell");
1844 treeview_insert(&tvfaff, 0, "Window");
1845 treeview_insert(&tvfaff, 1, "Appearance");
1846 treeview_insert(&tvfaff, 1, "Behaviour");
1847 treeview_insert(&tvfaff, 1, "Translation");
1848 treeview_insert(&tvfaff, 1, "Selection");
1849 treeview_insert(&tvfaff, 1, "Colours");
1850 treeview_insert(&tvfaff, 0, "Connection");
1852 treeview_insert(&tvfaff, 1, "Telnet");
1853 treeview_insert(&tvfaff, 1, "Rlogin");
1854 if (backends[3].backend != NULL) {
1855 treeview_insert(&tvfaff, 1, "SSH");
1856 /* XXX long name is ugly */
1857 /* XXX make it closed by default? */
1858 treeview_insert(&tvfaff, 2, "Auth");
1859 treeview_insert(&tvfaff, 2, "Tunnels");
1864 * Put the treeview selection on to the Session panel. This
1865 * should also cause creation of the relevant controls.
1867 TreeView_SelectItem(treeview, hsession);
1870 * Set focus into the first available control.
1874 ctl = GetDlgItem(hwnd, IDC_HOST);
1876 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1880 SetWindowLong(hwnd, GWL_USERDATA, 1);
1881 sesslist_has_focus = 0;
1885 * Button release should trigger WM_OK if there was a
1886 * previous double click on the session list.
1890 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1893 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1894 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1896 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1901 SendMessage (hwnd, WM_SETREDRAW, FALSE, 0);
1904 item.pszText = buffer;
1905 item.cchTextMax = sizeof(buffer);
1906 item.mask = TVIF_TEXT;
1907 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1908 for (j = controlstartvalue; j < controlendvalue; j++) {
1909 HWND item = GetDlgItem(hwnd, j);
1911 DestroyWindow(item);
1913 if (!strcmp(buffer, "Session"))
1914 create_controls(hwnd, dlgtype, sessionpanelstart);
1915 if (!strcmp(buffer, "Logging"))
1916 create_controls(hwnd, dlgtype, loggingpanelstart);
1917 if (!strcmp(buffer, "Keyboard"))
1918 create_controls(hwnd, dlgtype, keyboardpanelstart);
1919 if (!strcmp(buffer, "Terminal"))
1920 create_controls(hwnd, dlgtype, terminalpanelstart);
1921 if (!strcmp(buffer, "Bell"))
1922 create_controls(hwnd, dlgtype, bellpanelstart);
1923 if (!strcmp(buffer, "Window"))
1924 create_controls(hwnd, dlgtype, windowpanelstart);
1925 if (!strcmp(buffer, "Appearance"))
1926 create_controls(hwnd, dlgtype, appearancepanelstart);
1927 if (!strcmp(buffer, "Behaviour"))
1928 create_controls(hwnd, dlgtype, behaviourpanelstart);
1929 if (!strcmp(buffer, "Tunnels"))
1930 create_controls(hwnd, dlgtype, tunnelspanelstart);
1931 if (!strcmp(buffer, "Connection"))
1932 create_controls(hwnd, dlgtype, connectionpanelstart);
1933 if (!strcmp(buffer, "Telnet"))
1934 create_controls(hwnd, dlgtype, telnetpanelstart);
1935 if (!strcmp(buffer, "Rlogin"))
1936 create_controls(hwnd, dlgtype, rloginpanelstart);
1937 if (!strcmp(buffer, "SSH"))
1938 create_controls(hwnd, dlgtype, sshpanelstart);
1939 if (!strcmp(buffer, "Auth"))
1940 create_controls(hwnd, dlgtype, sshauthpanelstart);
1941 if (!strcmp(buffer, "Selection"))
1942 create_controls(hwnd, dlgtype, selectionpanelstart);
1943 if (!strcmp(buffer, "Colours"))
1944 create_controls(hwnd, dlgtype, colourspanelstart);
1945 if (!strcmp(buffer, "Translation"))
1946 create_controls(hwnd, dlgtype, translationpanelstart);
1948 init_dlg_ctrls(hwnd, FALSE);
1950 SendMessage (hwnd, WM_SETREDRAW, TRUE, 0);
1951 InvalidateRect (hwnd, NULL, TRUE);
1953 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1959 * Only process WM_COMMAND once the dialog is fully formed.
1961 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1962 switch (LOWORD(wParam)) {
1964 /* Behaviour of the "Open" button is different if the
1965 * session list has focus, *unless* the user just
1966 * double-clicked... */
1967 if (sesslist_has_focus && !readytogo) {
1968 if (!load_selected_session(hwnd)) {
1973 /* If at this point we have a valid session, go! */
1975 if (requested_help) {
1976 WinHelp(hwnd, help_path, HELP_QUIT, 0);
1977 requested_help = FALSE;
1984 if (HIWORD(wParam) == BN_CLICKED ||
1985 HIWORD(wParam) == BN_DOUBLECLICKED) {
1987 WinHelp(hwnd, help_path,
1988 help_has_contents ? HELP_FINDER : HELP_CONTENTS,
1990 requested_help = TRUE;
1995 if (requested_help) {
1996 WinHelp(hwnd, help_path, HELP_QUIT, 0);
1997 requested_help = FALSE;
2001 case IDC_PROTTELNET:
2002 case IDC_PROTRLOGIN:
2005 if (HIWORD(wParam) == BN_CLICKED ||
2006 HIWORD(wParam) == BN_DOUBLECLICKED) {
2007 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
2008 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
2009 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
2011 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
2013 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
2014 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
2015 || (cfg.protocol == PROT_RLOGIN
2016 && cfg.port != 513)) {
2017 cfg.port = i ? 22 : j ? 23 : 513;
2018 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
2023 if (HIWORD(wParam) == EN_CHANGE)
2024 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
2025 sizeof(cfg.host) - 1);
2028 if (HIWORD(wParam) == EN_CHANGE) {
2029 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
2030 if (isdigit(portname[0]))
2031 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
2033 service = getservbyname(portname, NULL);
2035 cfg.port = ntohs(service->s_port);
2042 if (HIWORD(wParam) == EN_CHANGE) {
2043 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2045 GetDlgItemText(hwnd, IDC_SESSEDIT,
2046 savedsession, sizeof(savedsession) - 1);
2047 savedsession[sizeof(savedsession) - 1] = '\0';
2051 if (HIWORD(wParam) == BN_CLICKED ||
2052 HIWORD(wParam) == BN_DOUBLECLICKED) {
2057 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
2060 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2061 LB_GETCURSEL, 0, 0);
2066 strcpy(str, sessions[n]);
2068 save_settings(str, !!strcmp(str, "Default Settings"),
2070 get_sesslist(FALSE);
2072 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2074 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2076 for (i = 0; i < nsessions; i++)
2077 SendDlgItemMessage(hwnd, IDC_SESSLIST,
2079 (LPARAM) (sessions[i]));
2080 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2082 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2084 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2090 if (LOWORD(wParam) == IDC_SESSLIST) {
2091 if (HIWORD(wParam) == LBN_SETFOCUS)
2092 sesslist_has_focus = 1;
2093 else if (HIWORD(wParam) == LBN_KILLFOCUS)
2094 sesslist_has_focus = 0;
2096 if (LOWORD(wParam) == IDC_SESSLOAD &&
2097 HIWORD(wParam) != BN_CLICKED &&
2098 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2099 if (LOWORD(wParam) == IDC_SESSLIST &&
2100 HIWORD(wParam) != LBN_DBLCLK) break;
2101 /* Load the session selected in SESSLIST. */
2102 if (load_selected_session(hwnd) &&
2103 LOWORD(wParam) == IDC_SESSLIST) {
2105 * A double-click on a saved session should
2106 * actually start the session, not just load it.
2107 * Unless it's Default Settings or some other
2108 * host-less set of saved settings.
2117 if (HIWORD(wParam) == BN_CLICKED ||
2118 HIWORD(wParam) == BN_DOUBLECLICKED) {
2119 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2120 LB_GETCURSEL, 0, 0);
2121 if (n == LB_ERR || n == 0) {
2125 del_settings(sessions[n]);
2126 get_sesslist(FALSE);
2128 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2130 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2132 for (i = 0; i < nsessions; i++)
2133 SendDlgItemMessage(hwnd, IDC_SESSLIST,
2135 (LPARAM) (sessions[i]));
2136 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2138 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2140 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2144 if (HIWORD(wParam) == EN_CHANGE)
2145 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
2146 &cfg.ping_interval);
2149 if (HIWORD(wParam) == BN_CLICKED ||
2150 HIWORD(wParam) == BN_DOUBLECLICKED)
2152 IsDlgButtonChecked(hwnd, IDC_NODELAY);
2156 if (HIWORD(wParam) == BN_CLICKED ||
2157 HIWORD(wParam) == BN_DOUBLECLICKED)
2158 cfg.bksp_is_delete =
2159 IsDlgButtonChecked(hwnd, IDC_DEL127);
2163 if (HIWORD(wParam) == BN_CLICKED ||
2164 HIWORD(wParam) == BN_DOUBLECLICKED)
2166 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
2172 case IDC_FUNCVT100P:
2174 if (HIWORD(wParam) == BN_CLICKED ||
2175 HIWORD(wParam) == BN_DOUBLECLICKED)
2176 switch (LOWORD(wParam)) {
2189 case IDC_FUNCVT100P:
2199 if (HIWORD(wParam) == BN_CLICKED ||
2200 HIWORD(wParam) == BN_DOUBLECLICKED) {
2202 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
2203 cfg.nethack_keypad = FALSE;
2207 if (HIWORD(wParam) == BN_CLICKED ||
2208 HIWORD(wParam) == BN_DOUBLECLICKED) {
2209 cfg.app_keypad = FALSE;
2210 cfg.nethack_keypad = TRUE;
2215 if (HIWORD(wParam) == BN_CLICKED ||
2216 HIWORD(wParam) == BN_DOUBLECLICKED)
2218 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
2221 if (HIWORD(wParam) == BN_CLICKED ||
2222 HIWORD(wParam) == BN_DOUBLECLICKED)
2224 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
2227 if (HIWORD(wParam) == BN_CLICKED ||
2228 HIWORD(wParam) == BN_DOUBLECLICKED)
2230 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
2233 if (HIWORD(wParam) == BN_CLICKED ||
2234 HIWORD(wParam) == BN_DOUBLECLICKED)
2235 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
2238 if (HIWORD(wParam) == BN_CLICKED ||
2239 HIWORD(wParam) == BN_DOUBLECLICKED)
2241 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
2244 if (HIWORD(wParam) == BN_CLICKED ||
2245 HIWORD(wParam) == BN_DOUBLECLICKED)
2247 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
2249 case IDC_ECHOBACKEND:
2252 if (HIWORD(wParam) == BN_CLICKED ||
2253 HIWORD(wParam) == BN_DOUBLECLICKED) {
2254 if (LOWORD(wParam) == IDC_ECHOBACKEND)
2255 cfg.localecho = LD_BACKEND;
2256 if (LOWORD(wParam) == IDC_ECHOYES)
2257 cfg.localecho = LD_YES;
2258 if (LOWORD(wParam) == IDC_ECHONO)
2259 cfg.localecho = LD_NO;
2262 case IDC_EDITBACKEND:
2265 if (HIWORD(wParam) == BN_CLICKED ||
2266 HIWORD(wParam) == BN_DOUBLECLICKED) {
2267 if (LOWORD(wParam) == IDC_EDITBACKEND)
2268 cfg.localedit = LD_BACKEND;
2269 if (LOWORD(wParam) == IDC_EDITYES)
2270 cfg.localedit = LD_YES;
2271 if (LOWORD(wParam) == IDC_EDITNO)
2272 cfg.localedit = LD_NO;
2275 case IDC_ANSWEREDIT:
2276 if (HIWORD(wParam) == EN_CHANGE)
2277 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
2278 sizeof(cfg.answerback) - 1);
2280 case IDC_ALWAYSONTOP:
2281 if (HIWORD(wParam) == BN_CLICKED ||
2282 HIWORD(wParam) == BN_DOUBLECLICKED)
2284 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
2286 case IDC_FULLSCREENONALTENTER:
2287 if (HIWORD(wParam) == BN_CLICKED ||
2288 HIWORD(wParam) == BN_DOUBLECLICKED)
2289 cfg.fullscreenonaltenter =
2290 IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER);
2293 if (HIWORD(wParam) == BN_CLICKED ||
2294 HIWORD(wParam) == BN_DOUBLECLICKED)
2296 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
2298 case IDC_SCROLLDISP:
2299 if (HIWORD(wParam) == BN_CLICKED ||
2300 HIWORD(wParam) == BN_DOUBLECLICKED)
2301 cfg.scroll_on_disp =
2302 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
2304 case IDC_COMPOSEKEY:
2305 if (HIWORD(wParam) == BN_CLICKED ||
2306 HIWORD(wParam) == BN_DOUBLECLICKED)
2308 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
2310 case IDC_CTRLALTKEYS:
2311 if (HIWORD(wParam) == BN_CLICKED ||
2312 HIWORD(wParam) == BN_DOUBLECLICKED)
2314 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
2317 if (HIWORD(wParam) == BN_CLICKED ||
2318 HIWORD(wParam) == BN_DOUBLECLICKED)
2319 cfg.telnet_keyboard =
2320 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
2323 if (HIWORD(wParam) == BN_CLICKED ||
2324 HIWORD(wParam) == BN_DOUBLECLICKED)
2326 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
2329 if (HIWORD(wParam) == BN_CLICKED ||
2330 HIWORD(wParam) == BN_DOUBLECLICKED)
2331 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
2334 if (HIWORD(wParam) == BN_CLICKED ||
2335 HIWORD(wParam) == BN_DOUBLECLICKED)
2337 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
2340 if (HIWORD(wParam) == EN_CHANGE)
2341 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
2344 if (HIWORD(wParam) == EN_CHANGE)
2345 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
2348 if (HIWORD(wParam) == EN_CHANGE)
2349 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
2351 case IDC_CHOOSEFONT:
2354 lf.lfHeight = -MulDiv(cfg.fontheight,
2355 GetDeviceCaps(hdc, LOGPIXELSY),
2359 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
2360 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
2361 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
2362 lf.lfCharSet = cfg.fontcharset;
2363 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
2364 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
2365 lf.lfQuality = DEFAULT_QUALITY;
2366 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
2367 strncpy(lf.lfFaceName, cfg.font,
2368 sizeof(lf.lfFaceName) - 1);
2369 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
2371 cf.lStructSize = sizeof(cf);
2372 cf.hwndOwner = hwnd;
2374 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
2375 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
2377 if (ChooseFont(&cf)) {
2378 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
2379 cfg.font[sizeof(cfg.font) - 1] = '\0';
2380 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
2381 cfg.fontcharset = lf.lfCharSet;
2382 cfg.fontheight = cf.iPointSize / 10;
2383 fmtfont(fontstatic);
2384 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
2387 case IDC_BELL_DISABLED:
2388 case IDC_BELL_DEFAULT:
2389 case IDC_BELL_WAVEFILE:
2390 case IDC_BELL_VISUAL:
2391 if (HIWORD(wParam) == BN_CLICKED ||
2392 HIWORD(wParam) == BN_DOUBLECLICKED) {
2393 if (LOWORD(wParam) == IDC_BELL_DISABLED)
2394 cfg.beep = BELL_DISABLED;
2395 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
2396 cfg.beep = BELL_DEFAULT;
2397 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
2398 cfg.beep = BELL_WAVEFILE;
2399 if (LOWORD(wParam) == IDC_BELL_VISUAL)
2400 cfg.beep = BELL_VISUAL;
2403 case IDC_B_IND_DISABLED:
2404 case IDC_B_IND_FLASH:
2405 case IDC_B_IND_STEADY:
2406 if (HIWORD(wParam) == BN_CLICKED ||
2407 HIWORD(wParam) == BN_DOUBLECLICKED) {
2408 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
2409 cfg.beep_ind = B_IND_DISABLED;
2410 if (LOWORD(wParam) == IDC_B_IND_FLASH)
2411 cfg.beep_ind = B_IND_FLASH;
2412 if (LOWORD(wParam) == IDC_B_IND_STEADY)
2413 cfg.beep_ind = B_IND_STEADY;
2416 case IDC_BELL_WAVEBROWSE:
2417 memset(&of, 0, sizeof(of));
2418 #ifdef OPENFILENAME_SIZE_VERSION_400
2419 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2421 of.lStructSize = sizeof(of);
2423 of.hwndOwner = hwnd;
2424 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
2425 of.lpstrCustomFilter = NULL;
2426 of.nFilterIndex = 1;
2427 of.lpstrFile = filename;
2428 strcpy(filename, cfg.bell_wavefile);
2429 of.nMaxFile = sizeof(filename);
2430 of.lpstrFileTitle = NULL;
2431 of.lpstrInitialDir = NULL;
2432 of.lpstrTitle = "Select Bell Sound File";
2434 if (GetOpenFileName(&of)) {
2435 strcpy(cfg.bell_wavefile, filename);
2436 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2440 case IDC_BELL_WAVEEDIT:
2441 if (HIWORD(wParam) == EN_CHANGE)
2442 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2444 sizeof(cfg.bell_wavefile) - 1);
2447 if (HIWORD(wParam) == BN_CLICKED ||
2448 HIWORD(wParam) == BN_DOUBLECLICKED)
2450 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
2453 if (HIWORD(wParam) == EN_CHANGE)
2454 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2457 if (HIWORD(wParam) == EN_CHANGE)
2458 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2462 if (HIWORD(wParam) == EN_CHANGE)
2463 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2467 if (HIWORD(wParam) == BN_CLICKED ||
2468 HIWORD(wParam) == BN_DOUBLECLICKED)
2470 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2473 if (HIWORD(wParam) == BN_CLICKED ||
2474 HIWORD(wParam) == BN_DOUBLECLICKED)
2475 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2478 if (HIWORD(wParam) == BN_CLICKED ||
2479 HIWORD(wParam) == BN_DOUBLECLICKED)
2480 cfg.win_name_always =
2481 IsDlgButtonChecked(hwnd, IDC_WINNAME);
2484 if (HIWORD(wParam) == BN_CLICKED ||
2485 HIWORD(wParam) == BN_DOUBLECLICKED)
2487 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2489 case IDC_SUNKENEDGE:
2490 if (HIWORD(wParam) == BN_CLICKED ||
2491 HIWORD(wParam) == BN_DOUBLECLICKED)
2493 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2496 if (HIWORD(wParam) == EN_CHANGE)
2497 MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
2498 &cfg.window_border);
2499 if (cfg.window_border > 32)
2500 cfg.window_border = 32;
2503 if (HIWORD(wParam) == BN_CLICKED ||
2504 HIWORD(wParam) == BN_DOUBLECLICKED)
2505 cfg.cursor_type = 0;
2508 if (HIWORD(wParam) == BN_CLICKED ||
2509 HIWORD(wParam) == BN_DOUBLECLICKED)
2510 cfg.cursor_type = 1;
2513 if (HIWORD(wParam) == BN_CLICKED ||
2514 HIWORD(wParam) == BN_DOUBLECLICKED)
2515 cfg.cursor_type = 2;
2518 if (HIWORD(wParam) == BN_CLICKED ||
2519 HIWORD(wParam) == BN_DOUBLECLICKED)
2521 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2524 if (HIWORD(wParam) == BN_CLICKED ||
2525 HIWORD(wParam) == BN_DOUBLECLICKED)
2527 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2529 case IDC_SCROLLBARFULLSCREEN:
2530 if (HIWORD(wParam) == BN_CLICKED ||
2531 HIWORD(wParam) == BN_DOUBLECLICKED)
2532 cfg.scrollbar_in_fullscreen =
2533 IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN);
2535 case IDC_RESIZETERM:
2536 case IDC_RESIZEFONT:
2537 case IDC_RESIZENONE:
2538 case IDC_RESIZEEITHER:
2539 if (HIWORD(wParam) == BN_CLICKED ||
2540 HIWORD(wParam) == BN_DOUBLECLICKED) {
2542 IsDlgButtonChecked(hwnd,
2543 IDC_RESIZETERM) ? RESIZE_TERM :
2544 IsDlgButtonChecked(hwnd,
2545 IDC_RESIZEFONT) ? RESIZE_FONT :
2546 IsDlgButtonChecked(hwnd,
2547 IDC_RESIZEEITHER) ? RESIZE_EITHER :
2552 if (HIWORD(wParam) == EN_CHANGE)
2553 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2554 sizeof(cfg.wintitle) - 1);
2559 if (HIWORD(wParam) == BN_CLICKED ||
2560 HIWORD(wParam) == BN_DOUBLECLICKED) {
2562 IsDlgButtonChecked(hwnd,
2563 IDC_COEALWAYS) ? COE_ALWAYS :
2564 IsDlgButtonChecked(hwnd,
2565 IDC_COENEVER) ? COE_NEVER :
2570 if (HIWORD(wParam) == BN_CLICKED ||
2571 HIWORD(wParam) == BN_DOUBLECLICKED)
2573 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
2576 if (HIWORD(wParam) == EN_CHANGE)
2577 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
2578 sizeof(cfg.termtype) - 1);
2581 if (HIWORD(wParam) == EN_CHANGE)
2582 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
2583 sizeof(cfg.logfilename) - 1);
2586 memset(&of, 0, sizeof(of));
2587 #ifdef OPENFILENAME_SIZE_VERSION_400
2588 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2590 of.lStructSize = sizeof(of);
2592 of.hwndOwner = hwnd;
2593 of.lpstrFilter = "All Files\0*\0\0\0";
2594 of.lpstrCustomFilter = NULL;
2595 of.nFilterIndex = 1;
2596 of.lpstrFile = filename;
2597 strcpy(filename, cfg.logfilename);
2598 of.nMaxFile = sizeof(filename);
2599 of.lpstrFileTitle = NULL;
2600 of.lpstrInitialDir = NULL;
2601 of.lpstrTitle = "Select session log file";
2603 if (GetSaveFileName(&of)) {
2604 strcpy(cfg.logfilename, filename);
2605 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2609 case IDC_LSTATASCII:
2611 if (HIWORD(wParam) == BN_CLICKED ||
2612 HIWORD(wParam) == BN_DOUBLECLICKED) {
2613 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2615 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2617 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2624 if (HIWORD(wParam) == BN_CLICKED ||
2625 HIWORD(wParam) == BN_DOUBLECLICKED) {
2626 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2627 cfg.logxfovr = LGXF_ASK;
2628 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2629 cfg.logxfovr = LGXF_APN;
2630 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2631 cfg.logxfovr = LGXF_OVR;
2636 if (HIWORD(wParam) == EN_CHANGE)
2637 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2638 sizeof(cfg.termspeed) - 1);
2641 if (HIWORD(wParam) == EN_CHANGE)
2642 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2643 sizeof(cfg.username) - 1);
2645 case IDC_RLLUSEREDIT:
2646 if (HIWORD(wParam) == EN_CHANGE)
2647 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2649 sizeof(cfg.localusername) - 1);
2653 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2657 cfg.passive_telnet =
2658 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2661 if (HIWORD(wParam) == BN_CLICKED ||
2662 HIWORD(wParam) == BN_DOUBLECLICKED) {
2663 char str[sizeof(cfg.environmt)];
2665 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2671 p = str + strlen(str);
2673 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2674 sizeof(str) - 1 - (p - str));
2685 if ((p - cfg.environmt) + strlen(str) + 2 <
2686 sizeof(cfg.environmt)) {
2688 p[strlen(str) + 1] = '\0';
2689 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2691 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2692 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2694 MessageBox(hwnd, "Environment too big",
2695 "PuTTY Error", MB_OK | MB_ICONERROR);
2700 if (HIWORD(wParam) != BN_CLICKED &&
2701 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2703 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2710 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2737 if (HIWORD(wParam) == BN_CLICKED ||
2738 HIWORD(wParam) == BN_DOUBLECLICKED)
2739 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2742 if (HIWORD(wParam) == BN_CLICKED ||
2743 HIWORD(wParam) == BN_DOUBLECLICKED)
2745 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2748 if (HIWORD(wParam) == BN_CLICKED ||
2749 HIWORD(wParam) == BN_DOUBLECLICKED)
2751 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2754 if (HIWORD(wParam) == BN_CLICKED ||
2755 HIWORD(wParam) == BN_DOUBLECLICKED)
2757 IsDlgButtonChecked(hwnd, IDC_SSH2DES);
2760 if (HIWORD(wParam) == BN_CLICKED ||
2761 HIWORD(wParam) == BN_DOUBLECLICKED)
2763 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2765 case IDC_CHANGEUSER:
2766 if (HIWORD(wParam) == BN_CLICKED ||
2767 HIWORD(wParam) == BN_DOUBLECLICKED)
2768 cfg.change_username =
2769 IsDlgButtonChecked(hwnd, IDC_CHANGEUSER);
2771 case IDC_CIPHERLIST:
2774 handle_prefslist(&cipherlist,
2775 cfg.ssh_cipherlist, CIPHER_MAX,
2776 0, hwnd, wParam, lParam);
2780 if (HIWORD(wParam) == BN_CLICKED ||
2781 HIWORD(wParam) == BN_DOUBLECLICKED) {
2782 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2784 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2789 if (HIWORD(wParam) == BN_CLICKED ||
2790 HIWORD(wParam) == BN_DOUBLECLICKED)
2792 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2795 if (HIWORD(wParam) == BN_CLICKED ||
2796 HIWORD(wParam) == BN_DOUBLECLICKED)
2798 IsDlgButtonChecked(hwnd, IDC_AUTHKI);
2801 if (HIWORD(wParam) == EN_CHANGE)
2802 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2803 sizeof(cfg.keyfile) - 1);
2806 if (HIWORD(wParam) == EN_CHANGE)
2807 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2808 sizeof(cfg.remote_cmd) - 1);
2811 memset(&of, 0, sizeof(of));
2812 #ifdef OPENFILENAME_SIZE_VERSION_400
2813 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2815 of.lStructSize = sizeof(of);
2817 of.hwndOwner = hwnd;
2818 of.lpstrFilter = "All Files\0*\0\0\0";
2819 of.lpstrCustomFilter = NULL;
2820 of.nFilterIndex = 1;
2821 of.lpstrFile = filename;
2822 strcpy(filename, cfg.keyfile);
2823 of.nMaxFile = sizeof(filename);
2824 of.lpstrFileTitle = NULL;
2825 of.lpstrInitialDir = NULL;
2826 of.lpstrTitle = "Select Private Key File";
2828 if (GetOpenFileName(&of)) {
2829 strcpy(cfg.keyfile, filename);
2830 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2834 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2837 cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE);
2841 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2843 case IDC_SELTYPELEX:
2844 case IDC_SELTYPERECT:
2845 cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
2847 case IDC_MOUSEOVERRIDE:
2848 cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
2854 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2859 for (i = 0; i < 128; i++)
2860 if (SendDlgItemMessage
2861 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2863 cfg.wordness[i] = n;
2864 SendDlgItemMessage(hwnd, IDC_CCLIST,
2865 LB_DELETESTRING, i, 0);
2866 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2867 (i >= 0x21 && i != 0x7F) ? i : ' ',
2869 SendDlgItemMessage(hwnd, IDC_CCLIST,
2876 case IDC_BOLDCOLOUR:
2877 if (HIWORD(wParam) == BN_CLICKED ||
2878 HIWORD(wParam) == BN_DOUBLECLICKED) {
2881 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2882 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2885 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2887 if (n != 12 + 10 * cfg.bold_colour) {
2888 for (i = n; i-- > 0;)
2889 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2890 LB_DELETESTRING, i, 0);
2891 for (i = 0; i < 22; i++)
2892 if (cfg.bold_colour || permcolour[i])
2893 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2895 (LPARAM) colours[i]);
2897 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2899 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2904 if (HIWORD(wParam) == BN_CLICKED ||
2905 HIWORD(wParam) == BN_DOUBLECLICKED)
2907 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2909 case IDC_COLOURLIST:
2910 if (HIWORD(wParam) == LBN_DBLCLK ||
2911 HIWORD(wParam) == LBN_SELCHANGE) {
2913 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2916 if (!cfg.bold_colour)
2917 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2918 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2920 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2922 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2927 if (HIWORD(wParam) == BN_CLICKED ||
2928 HIWORD(wParam) == BN_DOUBLECLICKED) {
2929 static CHOOSECOLOR cc;
2930 static DWORD custom[16] = { 0 }; /* zero initialisers */
2932 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2935 if (!cfg.bold_colour)
2936 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2937 cc.lStructSize = sizeof(cc);
2938 cc.hwndOwner = hwnd;
2939 cc.hInstance = (HWND) hinst;
2940 cc.lpCustColors = custom;
2942 RGB(cfg.colours[i][0], cfg.colours[i][1],
2944 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2945 if (ChooseColor(&cc)) {
2947 (unsigned char) (cc.rgbResult & 0xFF);
2949 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2951 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2952 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2954 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2956 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2962 if (HIWORD(wParam) == CBN_SELCHANGE) {
2963 int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
2964 CB_GETCURSEL, 0, 0);
2965 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
2966 index, (LPARAM)cfg.line_codepage);
2967 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
2968 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2969 sizeof(cfg.line_codepage) - 1);
2970 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
2971 strcpy(cfg.line_codepage,
2972 cp_name(decode_codepage(cfg.line_codepage)));
2973 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2976 case IDC_CAPSLOCKCYR:
2977 if (HIWORD(wParam) == BN_CLICKED ||
2978 HIWORD(wParam) == BN_DOUBLECLICKED) {
2979 cfg.xlat_capslockcyr =
2980 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
2983 case IDC_VTXWINDOWS:
2989 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2990 : IsDlgButtonChecked(hwnd,
2991 IDC_VTOEMANSI) ? VT_OEMANSI :
2992 IsDlgButtonChecked(hwnd,
2993 IDC_VTOEMONLY) ? VT_OEMONLY :
2994 IsDlgButtonChecked(hwnd,
2995 IDC_VTUNICODE) ? VT_UNICODE :
2998 case IDC_X11_FORWARD:
2999 if (HIWORD(wParam) == BN_CLICKED ||
3000 HIWORD(wParam) == BN_DOUBLECLICKED)
3002 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
3005 if (HIWORD(wParam) == BN_CLICKED ||
3006 HIWORD(wParam) == BN_DOUBLECLICKED)
3007 cfg.lport_acceptall =
3008 IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
3010 case IDC_X11_DISPLAY:
3011 if (HIWORD(wParam) == EN_CHANGE)
3012 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
3013 sizeof(cfg.x11_display) - 1);
3016 if (HIWORD(wParam) == BN_CLICKED ||
3017 HIWORD(wParam) == BN_DOUBLECLICKED) {
3018 char str[sizeof(cfg.portfwd)];
3020 if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
3024 GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
3028 "You need to specify a source port number",
3029 "PuTTY Error", MB_OK | MB_ICONERROR);
3032 p = str + strlen(str);
3034 GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
3035 sizeof(str) - 1 - (p - str));
3036 if (!*p || !strchr(p, ':')) {
3038 "You need to specify a destination address\n"
3039 "in the form \"host.name:port\"",
3040 "PuTTY Error", MB_OK | MB_ICONERROR);
3049 if ((p - cfg.portfwd) + strlen(str) + 2 <
3050 sizeof(cfg.portfwd)) {
3052 p[strlen(str) + 1] = '\0';
3053 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
3055 SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
3056 SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
3058 MessageBox(hwnd, "Too many forwardings",
3059 "PuTTY Error", MB_OK | MB_ICONERROR);
3063 case IDC_PFWDREMOVE:
3064 if (HIWORD(wParam) != BN_CLICKED &&
3065 HIWORD(wParam) != BN_DOUBLECLICKED) break;
3066 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
3067 LB_GETCURSEL, 0, 0);
3073 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
3103 int id = ((LPHELPINFO)lParam)->iCtrlId;
3104 char *cmd = help_context_cmd(id);
3106 WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
3107 requested_help = TRUE;
3114 if (requested_help) {
3115 WinHelp(hwnd, help_path, HELP_QUIT, 0);
3116 requested_help = FALSE;
3121 /* Grrr Explorer will maximize Dialogs! */
3123 if (wParam == SIZE_MAXIMIZED)
3129 * Handle application-defined messages eg. DragListBox
3131 /* First find out what the number is (once). */
3132 if (draglistmsg == WM_NULL)
3133 draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
3135 if (msg == draglistmsg) {
3136 /* Only process once dialog is fully formed. */
3137 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
3138 case IDC_CIPHERLIST:
3139 return handle_prefslist(&cipherlist,
3140 cfg.ssh_cipherlist, CIPHER_MAX,
3141 1, hwnd, wParam, lParam);
3150 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
3151 WPARAM wParam, LPARAM lParam)
3153 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
3155 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
3156 EnableWindow(hwnd, 0);
3157 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3158 EnableWindow(hwnd, 1);
3159 SetActiveWindow(hwnd);
3161 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
3164 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
3165 WPARAM wParam, LPARAM lParam)
3167 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
3170 void defuse_showwindow(void)
3173 * Work around the fact that the app's first call to ShowWindow
3174 * will ignore the default in favour of the shell-provided
3179 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
3181 ShowWindow(hwnd, SW_HIDE);
3182 SetActiveWindow(hwnd);
3183 DestroyWindow(hwnd);
3192 savedsession[0] = '\0';
3194 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
3195 get_sesslist(FALSE);
3200 int do_reconfig(HWND hwnd)
3205 backup_cfg = cfg; /* structure copy */
3207 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
3209 cfg = backup_cfg; /* structure copy */
3214 void logevent(char *string)
3219 if (nevents >= negsize) {
3221 events = srealloc(events, negsize * sizeof(*events));
3225 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
3228 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
3229 strcpy(events[nevents], timebuf);
3230 strcat(events[nevents], string);
3233 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
3234 0, (LPARAM) events[nevents]);
3235 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
3236 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
3241 void showeventlog(HWND hwnd)
3244 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
3246 ShowWindow(logbox, SW_SHOWNORMAL);
3248 SetActiveWindow(logbox);
3251 void showabout(HWND hwnd)
3253 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3256 void verify_ssh_host_key(char *host, int port, char *keytype,
3257 char *keystr, char *fingerprint)
3261 static const char absentmsg[] =
3262 "The server's host key is not cached in the registry. You\n"
3263 "have no guarantee that the server is the computer you\n"
3265 "The server's key fingerprint is:\n"
3267 "If you trust this host, hit Yes to add the key to\n"
3268 "PuTTY's cache and carry on connecting.\n"
3269 "If you want to carry on connecting just once, without\n"
3270 "adding the key to the cache, hit No.\n"
3271 "If you do not trust this host, hit Cancel to abandon the\n"
3274 static const char wrongmsg[] =
3275 "WARNING - POTENTIAL SECURITY BREACH!\n"
3277 "The server's host key does not match the one PuTTY has\n"
3278 "cached in the registry. This means that either the\n"
3279 "server administrator has changed the host key, or you\n"
3280 "have actually connected to another computer pretending\n"
3281 "to be the server.\n"
3282 "The new key fingerprint is:\n"
3284 "If you were expecting this change and trust the new key,\n"
3285 "hit Yes to update PuTTY's cache and continue connecting.\n"
3286 "If you want to carry on connecting but without updating\n"
3287 "the cache, hit No.\n"
3288 "If you want to abandon the connection completely, hit\n"
3289 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
3291 static const char mbtitle[] = "PuTTY Security Alert";
3294 /* sensible fingerprint max size */
3295 (sizeof(absentmsg) > sizeof(wrongmsg) ?
3296 sizeof(absentmsg) : sizeof(wrongmsg))];
3299 * Verify the key against the registry.
3301 ret = verify_host_key(host, port, keytype, keystr);
3303 if (ret == 0) /* success - key matched OK */
3305 if (ret == 2) { /* key was different */
3307 sprintf(message, wrongmsg, fingerprint);
3308 mbret = MessageBox(NULL, message, mbtitle,
3309 MB_ICONWARNING | MB_YESNOCANCEL);
3311 store_host_key(host, port, keytype, keystr);
3312 if (mbret == IDCANCEL)
3315 if (ret == 1) { /* key was absent */
3317 sprintf(message, absentmsg, fingerprint);
3318 mbret = MessageBox(NULL, message, mbtitle,
3319 MB_ICONWARNING | MB_YESNOCANCEL);
3321 store_host_key(host, port, keytype, keystr);
3322 if (mbret == IDCANCEL)
3328 * Ask whether the selected cipher is acceptable (since it was
3329 * below the configured 'warn' threshold).
3330 * cs: 0 = both ways, 1 = client->server, 2 = server->client
3332 void askcipher(char *ciphername, int cs)
3334 static const char mbtitle[] = "PuTTY Security Alert";
3335 static const char msg[] =
3336 "The first %.35scipher supported by the server\n"
3337 "is %.64s, which is below the configured\n"
3338 "warning threshold.\n"
3339 "Do you want to continue with this connection?\n";
3340 /* guessed cipher name + type max length */
3341 char message[100 + sizeof(msg)];
3344 sprintf(message, msg,
3346 (cs == 1) ? "client-to-server " :
3347 "server-to-client ",
3349 mbret = MessageBox(NULL, message, mbtitle,
3350 MB_ICONWARNING | MB_YESNO);
3358 * Ask whether to wipe a session log file before writing to it.
3359 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
3361 int askappend(char *filename)
3363 static const char mbtitle[] = "PuTTY Log to File";
3364 static const char msgtemplate[] =
3365 "The session log file \"%.*s\" already exists.\n"
3366 "You can overwrite it with a new session log,\n"
3367 "append your session log to the end of it,\n"
3368 "or disable session logging for this session.\n"
3369 "Hit Yes to wipe the file, No to append to it,\n"
3370 "or Cancel to disable logging.";
3371 char message[sizeof(msgtemplate) + FILENAME_MAX];
3373 if (cfg.logxfovr != LGXF_ASK) {
3374 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
3376 sprintf(message, msgtemplate, FILENAME_MAX, filename);
3378 mbret = MessageBox(NULL, message, mbtitle,
3379 MB_ICONQUESTION | MB_YESNOCANCEL);
3382 else if (mbret == IDNO)
3389 * Warn about the obsolescent key file format.
3391 void old_keyfile_warning(void)
3393 static const char mbtitle[] = "PuTTY Key File Warning";
3394 static const char message[] =
3395 "You are loading an SSH 2 private key which has an\n"
3396 "old version of the file format. This means your key\n"
3397 "file is not fully tamperproof. Future versions of\n"
3398 "PuTTY may stop supporting this private key format,\n"
3399 "so we recommend you convert your key to the new\n"
3402 "You can perform this conversion by loading the key\n"
3403 "into PuTTYgen and then saving it again.";
3405 MessageBox(NULL, message, mbtitle, MB_OK);