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,
522 translationpanelstart,
523 IDC_TITLE_TRANSLATION,
524 IDC_BOX_TRANSLATION1,
525 IDC_BOX_TRANSLATION2,
526 IDC_BOX_TRANSLATION3,
563 static const char *const colours[] = {
564 "Default Foreground", "Default Bold Foreground",
565 "Default Background", "Default Bold Background",
566 "Cursor Text", "Cursor Colour",
567 "ANSI Black", "ANSI Black Bold",
568 "ANSI Red", "ANSI Red Bold",
569 "ANSI Green", "ANSI Green Bold",
570 "ANSI Yellow", "ANSI Yellow Bold",
571 "ANSI Blue", "ANSI Blue Bold",
572 "ANSI Magenta", "ANSI Magenta Bold",
573 "ANSI Cyan", "ANSI Cyan Bold",
574 "ANSI White", "ANSI White Bold"
576 static const int permcolour[] = {
577 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
578 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
579 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
582 static void fmtfont(char *buf)
584 sprintf(buf, "Font: %s, ", cfg.font);
586 strcat(buf, "bold, ");
587 if (cfg.fontheight == 0)
588 strcat(buf, "default height");
590 sprintf(buf + strlen(buf), "%d-point",
591 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
594 char *help_context_cmd(int id)
606 return "JI(`',`session.hostname')";
613 return "JI(`',`session.saved')";
618 return "JI(`',`session.coe')";
619 case IDC_LSTATSTATIC:
623 return "JI(`',`logging.main')";
628 return "JI(`',`logging.filename')";
633 return "JI(`',`logging.exists')";
638 return "JI(`',`keyboard.backspace')";
642 return "JI(`',`keyboard.homeend')";
650 return "JI(`',`keyboard.funkeys')";
655 return "JI(`',`keyboard.appkeypad')";
660 return "JI(`',`keyboard.appcursor')";
662 return "JI(`',`keyboard.nethack')";
664 return "JI(`',`keyboard.compose')";
665 case IDC_CTRLALTKEYS:
666 return "JI(`',`keyboard.ctrlalt')";
669 return "JI(`',`terminal.autowrap')";
671 return "JI(`',`terminal.decom')";
673 return "JI(`',`terminal.lfhascr')";
675 return "JI(`',`terminal.bce')";
677 return "JI(`',`terminal.blink')";
680 return "JI(`',`terminal.answerback')";
682 case IDC_ECHOBACKEND:
685 return "JI(`',`terminal.localecho')";
687 case IDC_EDITBACKEND:
690 return "JI(`',`terminal.localedit')";
693 case IDC_BELL_DISABLED:
694 case IDC_BELL_DEFAULT:
695 case IDC_BELL_WAVEFILE:
696 case IDC_BELL_VISUAL:
697 case IDC_BELL_WAVESTATIC:
698 case IDC_BELL_WAVEEDIT:
699 case IDC_BELL_WAVEBROWSE:
700 return "JI(`',`bell.style')";
701 case IDC_B_IND_STATIC:
702 case IDC_B_IND_DISABLED:
703 case IDC_B_IND_FLASH:
704 case IDC_B_IND_STEADY:
705 return "JI(`',`bell.taskbar')";
707 case IDC_BELLOVLNSTATIC:
709 case IDC_BELLOVLTSTATIC:
711 case IDC_BELLOVLEXPLAIN:
712 case IDC_BELLOVLSSTATIC:
714 return "JI(`',`bell.overload')";
720 return "JI(`',`window.size')";
721 case IDC_RESIZESTATIC:
725 case IDC_RESIZEEITHER:
726 return "JI(`',`window.resize')";
728 case IDC_SCROLLBARFULLSCREEN:
733 return "JI(`',`window.scrollback')";
736 return "JI(`',`behaviour.closewarn')";
738 return "JI(`',`behaviour.altf4')";
740 return "JI(`',`behaviour.altspace')";
742 return "JI(`',`behaviour.altonly')";
743 case IDC_ALWAYSONTOP:
744 return "JI(`',`behaviour.alwaysontop')";
745 case IDC_FULLSCREENONALTENTER:
746 return "JI(`',`behaviour.altenter')";
748 case IDC_CURSORSTATIC:
753 return "JI(`',`appearance.cursor')";
756 return "JI(`',`appearance.font')";
760 return "JI(`',`appearance.title')";
762 return "JI(`',`appearance.hidemouse')";
766 return "JI(`',`appearance.border')";
770 return "JI(`',`connection.termtype')";
773 return "JI(`',`connection.username')";
776 return "JI(`',`connection.keepalive')";
778 return "JI(`',`connection.nodelay')";
782 return "JI(`',`telnet.termspeed')";
791 return "JI(`',`telnet.environ')";
795 return "JI(`',`telnet.oldenviron')";
799 return "JI(`',`telnet.passive')";
801 return "JI(`',`telnet.specialkeys')";
805 return "JI(`',`rlogin.termspeed')";
806 case IDC_RLLUSERSTATIC:
807 case IDC_RLLUSEREDIT:
808 return "JI(`',`rlogin.localuser')";
811 return "JI(`',`ssh.nopty')";
812 case IDC_CIPHERSTATIC2:
817 return "JI(`',`ssh.ciphers')";
819 return "JI(`',`ssh.buggymac')";
820 case IDC_SSHPROTSTATIC:
823 return "JI(`',`ssh.protocol')";
826 return "JI(`',`ssh.command')";
828 return "JI(`',`ssh.compress')";
833 return "JI(`',`ssh.auth.privkey')";
835 return "JI(`',`ssh.auth.agentfwd')";
837 return "JI(`',`ssh.auth.tis')";
839 return "JI(`',`ssh.auth.ki')";
844 return "JI(`',`selection.buttons')";
845 case IDC_MOUSEOVERRIDE:
846 return "JI(`',`selection.shiftdrag')";
847 case IDC_SELTYPESTATIC:
849 case IDC_SELTYPERECT:
850 return "JI(`',`selection.rect')";
856 return "JI(`',`selection.charclasses')";
858 return "JI(`',`selection.linedraw')";
860 return "JI(`',`selection.rtf')";
863 return "JI(`',`colours.bold')";
865 return "JI(`',`colours.logpal')";
866 case IDC_COLOURSTATIC:
875 return "JI(`',`colours.config')";
877 case IDC_CODEPAGESTATIC:
879 return "JI(`',`translation.codepage')";
880 case IDC_CAPSLOCKCYR:
881 return "JI(`',`translation.cyrillic')";
888 return "JI(`',`translation.linedraw')";
890 case IDC_X11_FORWARD:
891 case IDC_X11_DISPSTATIC:
892 case IDC_X11_DISPLAY:
893 return "JI(`',`ssh.tunnels.x11')";
896 case IDC_PFWDSTATIC2:
900 case IDC_SPORTSTATIC:
902 case IDC_DPORTSTATIC:
906 return "JI(`',`ssh.tunnels.portfwd')";
913 /* 2nd arg: NZ => don't redraw session list (use when loading
915 static void init_dlg_ctrls(HWND hwnd, int keepsess)
918 char fontstatic[256];
920 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
921 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
924 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
925 for (i = n; i-- > 0;)
926 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
927 for (i = 0; i < nsessions; i++)
928 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
929 0, (LPARAM) (sessions[i]));
931 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
932 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
933 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
934 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
936 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
937 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
938 CheckDlgButton(hwnd, IDC_NODELAY, cfg.tcp_nodelay);
940 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
941 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
942 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
943 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
944 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
945 cfg.funky_type == 0 ? IDC_FUNCTILDE :
946 cfg.funky_type == 1 ? IDC_FUNCLINUX :
947 cfg.funky_type == 2 ? IDC_FUNCXTERM :
948 cfg.funky_type == 3 ? IDC_FUNCVT400 :
949 cfg.funky_type == 4 ? IDC_FUNCVT100P :
950 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
951 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
952 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
953 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
954 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
955 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
956 cfg.nethack_keypad ? IDC_KPNH :
957 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
958 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
959 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
960 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
961 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
962 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
963 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
964 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
965 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
966 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
967 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
968 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
969 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
970 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
971 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
972 CheckDlgButton(hwnd, IDC_FULLSCREENONALTENTER, cfg.fullscreenonaltenter);
973 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
974 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
976 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
977 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
978 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
979 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
980 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
981 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
983 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
984 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
985 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
986 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
987 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
989 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
990 CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
992 B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
993 B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
994 B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
995 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
996 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
997 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
998 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
999 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
1001 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
1002 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
1004 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
1005 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
1006 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
1007 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
1008 SetDlgItemInt(hwnd, IDC_WINBEDIT, cfg.window_border, FALSE);
1009 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
1010 cfg.cursor_type == 0 ? IDC_CURBLOCK :
1011 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
1012 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
1013 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
1014 CheckDlgButton(hwnd, IDC_SCROLLBARFULLSCREEN, cfg.scrollbar_in_fullscreen);
1015 CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZEEITHER,
1016 cfg.resize_action == RESIZE_TERM ? IDC_RESIZETERM :
1017 cfg.resize_action == RESIZE_FONT ? IDC_RESIZEFONT :
1018 cfg.resize_action == RESIZE_EITHER ? IDC_RESIZEEITHER :
1020 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
1021 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
1022 cfg.close_on_exit ==
1023 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
1024 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
1026 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
1027 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
1028 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
1029 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
1030 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
1031 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
1032 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
1033 cfg.logtype == 0 ? IDC_LSTATOFF :
1034 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
1035 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
1036 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
1037 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
1040 char *p = cfg.environmt;
1041 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
1043 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
1049 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
1054 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
1055 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
1056 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
1057 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
1059 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
1060 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
1061 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
1062 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
1063 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
1064 CheckDlgButton(hwnd, IDC_SSH2DES, cfg.ssh2_des_cbc);
1065 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
1066 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
1067 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
1068 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
1069 CheckDlgButton(hwnd, IDC_AUTHKI, cfg.try_ki_auth);
1070 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
1071 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
1075 static const struct { char *s; int c; } ciphers[] = {
1076 { "3DES", CIPHER_3DES },
1077 { "Blowfish", CIPHER_BLOWFISH },
1078 { "DES", CIPHER_DES },
1079 { "AES (SSH 2 only)", CIPHER_AES },
1080 { "-- warn below here --", CIPHER_WARN }
1083 /* Set up the "selected ciphers" box. */
1084 /* (cipherlist assumed to contain all ciphers) */
1085 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0);
1086 for (i = 0; i < CIPHER_MAX; i++) {
1087 int c = cfg.ssh_cipherlist[i];
1090 for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
1091 if (ciphers[j].c == c) {
1092 cstr = ciphers[j].s;
1096 pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING,
1098 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA,
1104 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
1105 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
1106 CheckRadioButton(hwnd, IDC_SELTYPELEX, IDC_SELTYPERECT,
1107 cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT);
1108 CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
1109 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
1110 CheckDlgButton(hwnd, IDC_RTFPASTE, cfg.rtf_paste);
1112 static int tabs[4] = { 25, 61, 96, 128 };
1113 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
1116 for (i = 0; i < 128; i++) {
1118 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1119 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
1120 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
1124 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
1125 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
1128 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1129 for (i = n; i-- > 0;)
1130 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
1131 LB_DELETESTRING, i, 0);
1132 for (i = 0; i < 22; i++)
1133 if (cfg.bold_colour || permcolour[i])
1134 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
1135 (LPARAM) colours[i]);
1137 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
1138 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
1139 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
1140 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
1145 strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
1146 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
1147 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1148 for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
1149 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
1152 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
1155 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
1156 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
1157 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
1158 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
1159 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
1162 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
1163 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
1165 CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
1166 CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
1169 struct treeview_faff {
1171 HTREEITEM lastat[4];
1174 static HTREEITEM treeview_insert(struct treeview_faff *faff,
1175 int level, char *text)
1180 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
1181 ins.hInsertAfter = faff->lastat[level];
1182 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
1183 #define INSITEM DUMMYUNIONNAME.item
1185 #define INSITEM item
1187 ins.INSITEM.mask = TVIF_TEXT;
1188 ins.INSITEM.pszText = text;
1189 newitem = TreeView_InsertItem(faff->treeview, &ins);
1191 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
1193 faff->lastat[level] = newitem;
1194 for (i = level + 1; i < 4; i++)
1195 faff->lastat[i] = NULL;
1200 * Create the panelfuls of controls in the configuration box.
1202 static void create_controls(HWND hwnd, int dlgtype, int panel)
1204 if (panel == sessionpanelstart) {
1205 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
1207 ctlposinit(&cp, hwnd, 80, 3, 13);
1208 bartitle(&cp, "Basic options for your PuTTY session",
1211 beginbox(&cp, "Specify your connection by host name or IP address",
1214 "Host &Name (or IP address)",
1215 IDC_HOSTSTATIC, IDC_HOST, 75,
1216 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
1217 if (backends[3].backend == NULL) {
1218 /* this is PuTTYtel, so only three protocols available */
1219 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
1220 "&Raw", IDC_PROTRAW,
1221 "&Telnet", IDC_PROTTELNET,
1222 "Rlog&in", IDC_PROTRLOGIN, NULL);
1224 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
1225 "&Raw", IDC_PROTRAW,
1226 "&Telnet", IDC_PROTTELNET,
1227 "Rlog&in", IDC_PROTRLOGIN,
1236 beginbox(&cp, "Load, save or delete a stored session",
1238 sesssaver(&cp, "Sav&ed Sessions",
1239 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
1240 "&Load", IDC_SESSLOAD,
1241 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
1244 beginbox(&cp, NULL, IDC_BOX_SESSION3);
1245 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
1246 "Always", IDC_COEALWAYS,
1247 "Never", IDC_COENEVER,
1248 "Only on clean exit", IDC_COENORMAL, NULL);
1252 if (panel == loggingpanelstart) {
1253 /* The Logging panel. Accelerators used: [acgo] tplfwe */
1255 ctlposinit(&cp, hwnd, 80, 3, 13);
1256 bartitle(&cp, "Options controlling session logging",
1258 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
1260 "Session logging:", IDC_LSTATSTATIC,
1261 "Logging &turned off completely", IDC_LSTATOFF,
1262 "Log &printable output only", IDC_LSTATASCII,
1263 "&Log all session output", IDC_LSTATRAW, NULL);
1264 editbutton(&cp, "Log &file name:",
1265 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
1267 statictext(&cp, "(Log file name can contain &&Y, &&M, &&D for date,"
1268 " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN);
1270 "What to do if the log file already &exists:",
1271 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
1272 "Always append to the end of it", IDC_LSTATXAPN,
1273 "Ask the user every time", IDC_LSTATXASK, NULL);
1277 if (panel == terminalpanelstart) {
1278 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
1280 ctlposinit(&cp, hwnd, 80, 3, 13);
1281 bartitle(&cp, "Options controlling the terminal emulation",
1282 IDC_TITLE_TERMINAL);
1283 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
1284 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
1285 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
1286 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
1287 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
1288 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
1290 "An&swerback to ^E:", IDC_ANSWERBACK,
1291 IDC_ANSWEREDIT, 100, NULL);
1294 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
1295 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
1296 "Auto", IDC_ECHOBACKEND,
1297 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
1298 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
1299 "Auto", IDC_EDITBACKEND,
1300 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
1304 if (panel == bellpanelstart) {
1305 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
1307 ctlposinit(&cp, hwnd, 80, 3, 13);
1308 bartitle(&cp, "Options controlling the terminal bell",
1310 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
1312 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
1313 "None (bell disabled)", IDC_BELL_DISABLED,
1314 "Play Windows Default Sound", IDC_BELL_DEFAULT,
1315 "Play a custom sound file", IDC_BELL_WAVEFILE,
1316 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
1317 editbutton(&cp, "Custom sound file to play as a bell:",
1318 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
1319 "Bro&wse...", IDC_BELL_WAVEBROWSE);
1320 radioline(&cp, "Taskbar/caption &indication on bell:",
1321 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
1322 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
1325 beginbox(&cp, "Control the bell overload behaviour",
1327 checkbox(&cp, "Bell is temporarily &disabled when over-used",
1329 staticedit(&cp, "Over-use means this &many bells...",
1330 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
1331 staticedit(&cp, "... in &this many seconds",
1332 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
1334 "The bell is re-enabled after a few seconds of silence.",
1335 1, IDC_BELLOVLEXPLAIN);
1336 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
1341 if (panel == keyboardpanelstart) {
1342 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
1344 ctlposinit(&cp, hwnd, 80, 3, 13);
1345 bartitle(&cp, "Options controlling the effects of keys",
1346 IDC_TITLE_KEYBOARD);
1347 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
1348 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
1349 "Control-H", IDC_DEL008,
1350 "Control-? (127)", IDC_DEL127, NULL);
1351 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
1352 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
1353 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
1354 "ESC[n~", IDC_FUNCTILDE,
1355 "Linux", IDC_FUNCLINUX,
1356 "Xterm R6", IDC_FUNCXTERM,
1357 "VT400", IDC_FUNCVT400,
1358 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
1360 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
1362 "Application c&ursor keys totally disabled",
1364 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
1365 "Normal", IDC_CURNORMAL,
1366 "Application", IDC_CURAPPLIC, NULL);
1368 "Application ke&ypad keys totally disabled",
1370 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
1371 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
1372 "NetHack", IDC_KPNH, NULL);
1374 beginbox(&cp, "Enable extra keyboard features:",
1376 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
1377 checkbox(&cp, "Control-Alt is &different from AltGr",
1382 if (panel == windowpanelstart) {
1383 /* The Window panel. Accelerators used: [acgo] rmz sdikp */
1385 ctlposinit(&cp, hwnd, 80, 3, 13);
1386 bartitle(&cp, "Options controlling PuTTY's window",
1388 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
1390 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
1391 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
1392 radiobig(&cp, "When window is resi&zed:", IDC_RESIZESTATIC,
1393 "Change the number of rows and columns", IDC_RESIZETERM,
1394 "Change the size of the font", IDC_RESIZEFONT,
1395 "Change font size only when maximised", IDC_RESIZEEITHER,
1396 "Forbid resizing completely", IDC_RESIZENONE, NULL);
1398 beginbox(&cp, "Control the scrollback in the window",
1400 staticedit(&cp, "Lines of &scrollback",
1401 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
1402 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
1403 checkbox(&cp, "D&isplay scrollbar in full screen mode", IDC_SCROLLBARFULLSCREEN);
1404 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
1405 checkbox(&cp, "Reset scrollback on dis&play activity",
1410 if (panel == appearancepanelstart) {
1411 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
1413 ctlposinit(&cp, hwnd, 80, 3, 13);
1414 bartitle(&cp, "Configure the appearance of PuTTY's window",
1415 IDC_TITLE_APPEARANCE);
1416 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
1417 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
1418 "B&lock", IDC_CURBLOCK,
1419 "&Underline", IDC_CURUNDER,
1420 "&Vertical line", IDC_CURVERT, NULL);
1421 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
1423 beginbox(&cp, "Set the font used in the terminal window",
1424 IDC_BOX_APPEARANCE2);
1425 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
1427 beginbox(&cp, "Adjust the use of the window title",
1428 IDC_BOX_APPEARANCE3);
1430 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1431 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1433 beginbox(&cp, "Adjust the use of the mouse pointer",
1434 IDC_BOX_APPEARANCE4);
1435 checkbox(&cp, "Hide mouse &pointer when typing in window",
1438 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1439 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1441 staticedit(&cp, "Gap between text and window edge",
1442 IDC_WINBSTATIC, IDC_WINBEDIT, 20);
1446 if (panel == behaviourpanelstart) {
1447 /* The Behaviour panel. Accelerators used: [acgo] w4yltf */
1449 ctlposinit(&cp, hwnd, 80, 3, 13);
1450 bartitle(&cp, "Configure the behaviour of PuTTY's window",
1452 beginbox(&cp, NULL, IDC_BOX_BEHAVIOUR1);
1453 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
1454 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
1455 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
1456 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
1457 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
1458 checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
1462 if (panel == translationpanelstart) {
1463 /* The Translation panel. Accelerators used: [acgo] rxbepus */
1465 ctlposinit(&cp, hwnd, 80, 3, 13);
1466 bartitle(&cp, "Options controlling character set translation",
1467 IDC_TITLE_TRANSLATION);
1468 beginbox(&cp, "Character set translation on received data",
1469 IDC_BOX_TRANSLATION1);
1470 combobox(&cp, "&Received data assumed to be in which character set:",
1471 IDC_CODEPAGESTATIC, IDC_CODEPAGE);
1473 beginbox(&cp, "Enable character set translation on input data",
1474 IDC_BOX_TRANSLATION2);
1475 checkbox(&cp, "Cap&s Lock acts as Cyrillic switch",
1478 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1479 IDC_BOX_TRANSLATION3);
1481 "Handling of line drawing characters:", IDC_VTSTATIC,
1482 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1483 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1484 "Use font in O&EM mode only", IDC_VTOEMONLY,
1485 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1486 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1490 if (panel == selectionpanelstart) {
1491 /* The Selection panel. Accelerators used: [acgo] df wxp hst nr */
1493 ctlposinit(&cp, hwnd, 80, 3, 13);
1494 bartitle(&cp, "Options controlling copy and paste",
1495 IDC_TITLE_SELECTION);
1496 beginbox(&cp, "Translation of pasted characters",
1497 IDC_BOX_SELECTION1);
1499 "&Don't translate line drawing chars into +, - and |",
1502 "Paste to clipboard in RT&F as well as plain text",
1505 beginbox(&cp, "Control which mouse button does which thing",
1506 IDC_BOX_SELECTION2);
1507 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1508 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1509 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1512 "Shift overrides a&pplication's use of mouse",
1515 "Default selection mode (Alt+drag does the other one):",
1516 IDC_SELTYPESTATIC, 2,
1517 "&Normal", IDC_SELTYPELEX,
1518 "&Rectangular block", IDC_SELTYPERECT, NULL);
1520 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1521 IDC_BOX_SELECTION3);
1522 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1523 "&Set", IDC_CCSET, IDC_CCEDIT,
1524 "&to class", IDC_CCSTATIC2);
1528 if (panel == colourspanelstart) {
1529 /* The Colours panel. Accelerators used: [acgo] blum */
1531 ctlposinit(&cp, hwnd, 80, 3, 13);
1532 bartitle(&cp, "Options controlling use of colours",
1534 beginbox(&cp, "General options for colour usage",
1536 checkbox(&cp, "&Bolded text is a different colour",
1538 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1540 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1542 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1543 IDC_COLOURSTATIC, IDC_COLOURLIST,
1544 "&Modify...", IDC_CHANGE,
1545 "Red:", IDC_RSTATIC, IDC_RVALUE,
1546 "Green:", IDC_GSTATIC, IDC_GVALUE,
1547 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1551 if (panel == connectionpanelstart) {
1552 /* The Connection panel. Accelerators used: [acgo] tukn */
1554 ctlposinit(&cp, hwnd, 80, 3, 13);
1555 bartitle(&cp, "Options controlling the connection",
1556 IDC_TITLE_CONNECTION);
1558 beginbox(&cp, "Data to send to the server",
1559 IDC_BOX_CONNECTION1);
1560 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1562 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1566 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1567 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1571 beginbox(&cp, "Sending of null packets to keep session active",
1572 IDC_BOX_CONNECTION2);
1573 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1574 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1577 beginbox(&cp, "Low-level TCP connection options",
1578 IDC_BOX_CONNECTION3);
1579 checkbox(&cp, "Disable &Nagle's algorithm (TCP_NODELAY option)",
1585 if (panel == telnetpanelstart) {
1586 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1588 ctlposinit(&cp, hwnd, 80, 3, 13);
1590 bartitle(&cp, "Options controlling Telnet connections",
1592 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1593 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1595 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1596 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1597 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1598 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1600 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1601 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1602 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1603 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1604 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1605 "Passive", IDC_TPASSIVE, "Active",
1607 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1613 if (panel == rloginpanelstart) {
1614 /* The Rlogin panel. Accelerators used: [acgo] sl */
1616 ctlposinit(&cp, hwnd, 80, 3, 13);
1618 bartitle(&cp, "Options controlling Rlogin connections",
1620 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1621 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1623 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1624 IDC_RLLUSEREDIT, 50);
1629 if (panel == sshpanelstart) {
1630 /* The SSH panel. Accelerators used: [acgo] r pe12i sd */
1632 ctlposinit(&cp, hwnd, 80, 3, 13);
1634 bartitle(&cp, "Options controlling SSH connections",
1636 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1638 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1641 beginbox(&cp, "Protocol options", IDC_BOX_SSH2);
1642 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1643 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1644 radioline(&cp, "Preferred SSH protocol version:",
1645 IDC_SSHPROTSTATIC, 2,
1646 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1647 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1650 beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
1651 prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
1652 IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
1654 checkbox(&cp, "Enable non-standard use of single-&DES in SSH 2",
1660 if (panel == sshauthpanelstart) {
1661 /* The SSH authentication panel. Accelerators used: [acgo] m fkiw */
1663 ctlposinit(&cp, hwnd, 80, 3, 13);
1665 bartitle(&cp, "Options controlling SSH authentication",
1667 beginbox(&cp, "Authentication methods",
1669 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication (SSH1)",
1671 checkbox(&cp, "Attempt \"keyboard-&interactive\" authentication"
1672 " (SSH2)", IDC_AUTHKI);
1674 beginbox(&cp, "Authentication parameters",
1676 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1677 editbutton(&cp, "Private &key file for authentication:",
1678 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1684 if (panel == tunnelspanelstart) {
1685 /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
1687 ctlposinit(&cp, hwnd, 80, 3, 13);
1689 bartitle(&cp, "Options controlling SSH tunnelling",
1691 beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
1692 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1693 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1694 IDC_X11_DISPLAY, 50, NULL);
1696 beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
1697 checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL);
1698 staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
1699 "&Remove", IDC_PFWDREMOVE);
1700 fwdsetter(&cp, IDC_PFWDLIST,
1701 "Add new forwarded port:", IDC_PFWDSTATIC2,
1702 "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
1703 "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
1704 "A&dd", IDC_PFWDADD);
1705 bareradioline(&cp, 2,
1706 "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL);
1714 * Helper function to load the session selected in SESSLIST
1715 * if any, as this is done in more than one place in
1716 * GenericMainDlgProc(). 0 => failure.
1718 static int load_selected_session(HWND hwnd)
1720 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1721 LB_GETCURSEL, 0, 0);
1727 isdef = !strcmp(sessions[n], "Default Settings");
1728 load_settings(sessions[n], !isdef, &cfg);
1729 init_dlg_ctrls(hwnd, TRUE);
1731 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1733 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1734 /* Restore the selection, which will have been clobbered by
1735 * SESSEDIT handling. */
1736 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1741 * This function is the configuration box.
1743 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1744 WPARAM wParam, LPARAM lParam, int dlgtype)
1747 struct treeview_faff tvfaff;
1750 char filename[sizeof(cfg.keyfile)];
1753 char fontstatic[256];
1755 struct servent *service;
1757 static UINT draglistmsg = WM_NULL;
1762 SetWindowLong(hwnd, GWL_USERDATA, 0);
1764 SetWindowLong(hwnd, GWL_EXSTYLE,
1765 GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
1767 HWND item = GetDlgItem(hwnd, IDC_HELPBTN);
1769 DestroyWindow(item);
1771 requested_help = FALSE;
1772 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1773 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1775 * Centre the window.
1777 { /* centre the window */
1780 hw = GetDesktopWindow();
1781 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1783 (rs.right + rs.left + rd.left - rd.right) / 2,
1784 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1785 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1789 * Create the tree view.
1797 r.right = r.left + 75;
1799 r.bottom = r.top + 10;
1800 MapDialogRect(hwnd, &r);
1801 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1802 WS_CHILD | WS_VISIBLE,
1804 r.right - r.left, r.bottom - r.top,
1805 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1807 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1808 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1811 r.right = r.left + 75;
1813 r.bottom = r.top + 219;
1814 MapDialogRect(hwnd, &r);
1815 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1816 WS_CHILD | WS_VISIBLE |
1817 WS_TABSTOP | TVS_HASLINES |
1818 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1820 TVS_SHOWSELALWAYS, r.left, r.top,
1821 r.right - r.left, r.bottom - r.top,
1822 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1824 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1825 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1826 tvfaff.treeview = treeview;
1827 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1831 * Set up the tree view contents.
1833 hsession = treeview_insert(&tvfaff, 0, "Session");
1834 treeview_insert(&tvfaff, 1, "Logging");
1835 treeview_insert(&tvfaff, 0, "Terminal");
1836 treeview_insert(&tvfaff, 1, "Keyboard");
1837 treeview_insert(&tvfaff, 1, "Bell");
1838 treeview_insert(&tvfaff, 0, "Window");
1839 treeview_insert(&tvfaff, 1, "Appearance");
1840 treeview_insert(&tvfaff, 1, "Behaviour");
1841 treeview_insert(&tvfaff, 1, "Translation");
1842 treeview_insert(&tvfaff, 1, "Selection");
1843 treeview_insert(&tvfaff, 1, "Colours");
1844 treeview_insert(&tvfaff, 0, "Connection");
1846 treeview_insert(&tvfaff, 1, "Telnet");
1847 treeview_insert(&tvfaff, 1, "Rlogin");
1848 if (backends[3].backend != NULL) {
1849 treeview_insert(&tvfaff, 1, "SSH");
1850 /* XXX long name is ugly */
1851 /* XXX make it closed by default? */
1852 treeview_insert(&tvfaff, 2, "Auth");
1853 treeview_insert(&tvfaff, 2, "Tunnels");
1858 * Put the treeview selection on to the Session panel. This
1859 * should also cause creation of the relevant controls.
1861 TreeView_SelectItem(treeview, hsession);
1864 * Set focus into the first available control.
1868 ctl = GetDlgItem(hwnd, IDC_HOST);
1870 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1874 SetWindowLong(hwnd, GWL_USERDATA, 1);
1875 sesslist_has_focus = 0;
1879 * Button release should trigger WM_OK if there was a
1880 * previous double click on the session list.
1884 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1887 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1888 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1890 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1895 SendMessage (hwnd, WM_SETREDRAW, FALSE, 0);
1898 item.pszText = buffer;
1899 item.cchTextMax = sizeof(buffer);
1900 item.mask = TVIF_TEXT;
1901 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1902 for (j = controlstartvalue; j < controlendvalue; j++) {
1903 HWND item = GetDlgItem(hwnd, j);
1905 DestroyWindow(item);
1907 if (!strcmp(buffer, "Session"))
1908 create_controls(hwnd, dlgtype, sessionpanelstart);
1909 if (!strcmp(buffer, "Logging"))
1910 create_controls(hwnd, dlgtype, loggingpanelstart);
1911 if (!strcmp(buffer, "Keyboard"))
1912 create_controls(hwnd, dlgtype, keyboardpanelstart);
1913 if (!strcmp(buffer, "Terminal"))
1914 create_controls(hwnd, dlgtype, terminalpanelstart);
1915 if (!strcmp(buffer, "Bell"))
1916 create_controls(hwnd, dlgtype, bellpanelstart);
1917 if (!strcmp(buffer, "Window"))
1918 create_controls(hwnd, dlgtype, windowpanelstart);
1919 if (!strcmp(buffer, "Appearance"))
1920 create_controls(hwnd, dlgtype, appearancepanelstart);
1921 if (!strcmp(buffer, "Behaviour"))
1922 create_controls(hwnd, dlgtype, behaviourpanelstart);
1923 if (!strcmp(buffer, "Tunnels"))
1924 create_controls(hwnd, dlgtype, tunnelspanelstart);
1925 if (!strcmp(buffer, "Connection"))
1926 create_controls(hwnd, dlgtype, connectionpanelstart);
1927 if (!strcmp(buffer, "Telnet"))
1928 create_controls(hwnd, dlgtype, telnetpanelstart);
1929 if (!strcmp(buffer, "Rlogin"))
1930 create_controls(hwnd, dlgtype, rloginpanelstart);
1931 if (!strcmp(buffer, "SSH"))
1932 create_controls(hwnd, dlgtype, sshpanelstart);
1933 if (!strcmp(buffer, "Auth"))
1934 create_controls(hwnd, dlgtype, sshauthpanelstart);
1935 if (!strcmp(buffer, "Selection"))
1936 create_controls(hwnd, dlgtype, selectionpanelstart);
1937 if (!strcmp(buffer, "Colours"))
1938 create_controls(hwnd, dlgtype, colourspanelstart);
1939 if (!strcmp(buffer, "Translation"))
1940 create_controls(hwnd, dlgtype, translationpanelstart);
1942 init_dlg_ctrls(hwnd, FALSE);
1944 SendMessage (hwnd, WM_SETREDRAW, TRUE, 0);
1945 InvalidateRect (hwnd, NULL, TRUE);
1947 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1953 * Only process WM_COMMAND once the dialog is fully formed.
1955 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1956 switch (LOWORD(wParam)) {
1958 /* Behaviour of the "Open" button is different if the
1959 * session list has focus, *unless* the user just
1960 * double-clicked... */
1961 if (sesslist_has_focus && !readytogo) {
1962 if (!load_selected_session(hwnd)) {
1967 /* If at this point we have a valid session, go! */
1969 if (requested_help) {
1970 WinHelp(hwnd, help_path, HELP_QUIT, 0);
1971 requested_help = FALSE;
1978 if (HIWORD(wParam) == BN_CLICKED ||
1979 HIWORD(wParam) == BN_DOUBLECLICKED) {
1981 WinHelp(hwnd, help_path,
1982 help_has_contents ? HELP_FINDER : HELP_CONTENTS,
1984 requested_help = TRUE;
1989 if (requested_help) {
1990 WinHelp(hwnd, help_path, HELP_QUIT, 0);
1991 requested_help = FALSE;
1995 case IDC_PROTTELNET:
1996 case IDC_PROTRLOGIN:
1999 if (HIWORD(wParam) == BN_CLICKED ||
2000 HIWORD(wParam) == BN_DOUBLECLICKED) {
2001 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
2002 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
2003 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
2005 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
2007 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
2008 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
2009 || (cfg.protocol == PROT_RLOGIN
2010 && cfg.port != 513)) {
2011 cfg.port = i ? 22 : j ? 23 : 513;
2012 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
2017 if (HIWORD(wParam) == EN_CHANGE)
2018 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
2019 sizeof(cfg.host) - 1);
2022 if (HIWORD(wParam) == EN_CHANGE) {
2023 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
2024 if (isdigit(portname[0]))
2025 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
2027 service = getservbyname(portname, NULL);
2029 cfg.port = ntohs(service->s_port);
2036 if (HIWORD(wParam) == EN_CHANGE) {
2037 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2039 GetDlgItemText(hwnd, IDC_SESSEDIT,
2040 savedsession, sizeof(savedsession) - 1);
2041 savedsession[sizeof(savedsession) - 1] = '\0';
2045 if (HIWORD(wParam) == BN_CLICKED ||
2046 HIWORD(wParam) == BN_DOUBLECLICKED) {
2051 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
2054 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2055 LB_GETCURSEL, 0, 0);
2060 strcpy(str, sessions[n]);
2062 save_settings(str, !!strcmp(str, "Default Settings"),
2064 get_sesslist(FALSE);
2066 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2068 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2070 for (i = 0; i < nsessions; i++)
2071 SendDlgItemMessage(hwnd, IDC_SESSLIST,
2073 (LPARAM) (sessions[i]));
2074 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2076 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2078 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2084 if (LOWORD(wParam) == IDC_SESSLIST) {
2085 if (HIWORD(wParam) == LBN_SETFOCUS)
2086 sesslist_has_focus = 1;
2087 else if (HIWORD(wParam) == LBN_KILLFOCUS)
2088 sesslist_has_focus = 0;
2090 if (LOWORD(wParam) == IDC_SESSLOAD &&
2091 HIWORD(wParam) != BN_CLICKED &&
2092 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2093 if (LOWORD(wParam) == IDC_SESSLIST &&
2094 HIWORD(wParam) != LBN_DBLCLK) break;
2095 /* Load the session selected in SESSLIST. */
2096 if (load_selected_session(hwnd) &&
2097 LOWORD(wParam) == IDC_SESSLIST) {
2099 * A double-click on a saved session should
2100 * actually start the session, not just load it.
2101 * Unless it's Default Settings or some other
2102 * host-less set of saved settings.
2111 if (HIWORD(wParam) == BN_CLICKED ||
2112 HIWORD(wParam) == BN_DOUBLECLICKED) {
2113 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
2114 LB_GETCURSEL, 0, 0);
2115 if (n == LB_ERR || n == 0) {
2119 del_settings(sessions[n]);
2120 get_sesslist(FALSE);
2122 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2124 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
2126 for (i = 0; i < nsessions; i++)
2127 SendDlgItemMessage(hwnd, IDC_SESSLIST,
2129 (LPARAM) (sessions[i]));
2130 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
2132 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
2134 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
2138 if (HIWORD(wParam) == EN_CHANGE)
2139 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
2140 &cfg.ping_interval);
2143 if (HIWORD(wParam) == BN_CLICKED ||
2144 HIWORD(wParam) == BN_DOUBLECLICKED)
2146 IsDlgButtonChecked(hwnd, IDC_NODELAY);
2150 if (HIWORD(wParam) == BN_CLICKED ||
2151 HIWORD(wParam) == BN_DOUBLECLICKED)
2152 cfg.bksp_is_delete =
2153 IsDlgButtonChecked(hwnd, IDC_DEL127);
2157 if (HIWORD(wParam) == BN_CLICKED ||
2158 HIWORD(wParam) == BN_DOUBLECLICKED)
2160 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
2166 case IDC_FUNCVT100P:
2168 if (HIWORD(wParam) == BN_CLICKED ||
2169 HIWORD(wParam) == BN_DOUBLECLICKED)
2170 switch (LOWORD(wParam)) {
2183 case IDC_FUNCVT100P:
2193 if (HIWORD(wParam) == BN_CLICKED ||
2194 HIWORD(wParam) == BN_DOUBLECLICKED) {
2196 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
2197 cfg.nethack_keypad = FALSE;
2201 if (HIWORD(wParam) == BN_CLICKED ||
2202 HIWORD(wParam) == BN_DOUBLECLICKED) {
2203 cfg.app_keypad = FALSE;
2204 cfg.nethack_keypad = TRUE;
2209 if (HIWORD(wParam) == BN_CLICKED ||
2210 HIWORD(wParam) == BN_DOUBLECLICKED)
2212 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
2215 if (HIWORD(wParam) == BN_CLICKED ||
2216 HIWORD(wParam) == BN_DOUBLECLICKED)
2218 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
2221 if (HIWORD(wParam) == BN_CLICKED ||
2222 HIWORD(wParam) == BN_DOUBLECLICKED)
2224 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
2227 if (HIWORD(wParam) == BN_CLICKED ||
2228 HIWORD(wParam) == BN_DOUBLECLICKED)
2229 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
2232 if (HIWORD(wParam) == BN_CLICKED ||
2233 HIWORD(wParam) == BN_DOUBLECLICKED)
2235 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
2238 if (HIWORD(wParam) == BN_CLICKED ||
2239 HIWORD(wParam) == BN_DOUBLECLICKED)
2241 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
2243 case IDC_ECHOBACKEND:
2246 if (HIWORD(wParam) == BN_CLICKED ||
2247 HIWORD(wParam) == BN_DOUBLECLICKED) {
2248 if (LOWORD(wParam) == IDC_ECHOBACKEND)
2249 cfg.localecho = LD_BACKEND;
2250 if (LOWORD(wParam) == IDC_ECHOYES)
2251 cfg.localecho = LD_YES;
2252 if (LOWORD(wParam) == IDC_ECHONO)
2253 cfg.localecho = LD_NO;
2256 case IDC_EDITBACKEND:
2259 if (HIWORD(wParam) == BN_CLICKED ||
2260 HIWORD(wParam) == BN_DOUBLECLICKED) {
2261 if (LOWORD(wParam) == IDC_EDITBACKEND)
2262 cfg.localedit = LD_BACKEND;
2263 if (LOWORD(wParam) == IDC_EDITYES)
2264 cfg.localedit = LD_YES;
2265 if (LOWORD(wParam) == IDC_EDITNO)
2266 cfg.localedit = LD_NO;
2269 case IDC_ANSWEREDIT:
2270 if (HIWORD(wParam) == EN_CHANGE)
2271 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
2272 sizeof(cfg.answerback) - 1);
2274 case IDC_ALWAYSONTOP:
2275 if (HIWORD(wParam) == BN_CLICKED ||
2276 HIWORD(wParam) == BN_DOUBLECLICKED)
2278 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
2280 case IDC_FULLSCREENONALTENTER:
2281 if (HIWORD(wParam) == BN_CLICKED ||
2282 HIWORD(wParam) == BN_DOUBLECLICKED)
2283 cfg.fullscreenonaltenter =
2284 IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER);
2287 if (HIWORD(wParam) == BN_CLICKED ||
2288 HIWORD(wParam) == BN_DOUBLECLICKED)
2290 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
2292 case IDC_SCROLLDISP:
2293 if (HIWORD(wParam) == BN_CLICKED ||
2294 HIWORD(wParam) == BN_DOUBLECLICKED)
2295 cfg.scroll_on_disp =
2296 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
2298 case IDC_COMPOSEKEY:
2299 if (HIWORD(wParam) == BN_CLICKED ||
2300 HIWORD(wParam) == BN_DOUBLECLICKED)
2302 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
2304 case IDC_CTRLALTKEYS:
2305 if (HIWORD(wParam) == BN_CLICKED ||
2306 HIWORD(wParam) == BN_DOUBLECLICKED)
2308 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
2311 if (HIWORD(wParam) == BN_CLICKED ||
2312 HIWORD(wParam) == BN_DOUBLECLICKED)
2313 cfg.telnet_keyboard =
2314 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
2317 if (HIWORD(wParam) == BN_CLICKED ||
2318 HIWORD(wParam) == BN_DOUBLECLICKED)
2320 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
2323 if (HIWORD(wParam) == BN_CLICKED ||
2324 HIWORD(wParam) == BN_DOUBLECLICKED)
2325 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
2328 if (HIWORD(wParam) == BN_CLICKED ||
2329 HIWORD(wParam) == BN_DOUBLECLICKED)
2331 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
2334 if (HIWORD(wParam) == EN_CHANGE)
2335 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
2338 if (HIWORD(wParam) == EN_CHANGE)
2339 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
2342 if (HIWORD(wParam) == EN_CHANGE)
2343 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
2345 case IDC_CHOOSEFONT:
2348 lf.lfHeight = -MulDiv(cfg.fontheight,
2349 GetDeviceCaps(hdc, LOGPIXELSY),
2353 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
2354 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
2355 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
2356 lf.lfCharSet = cfg.fontcharset;
2357 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
2358 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
2359 lf.lfQuality = DEFAULT_QUALITY;
2360 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
2361 strncpy(lf.lfFaceName, cfg.font,
2362 sizeof(lf.lfFaceName) - 1);
2363 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
2365 cf.lStructSize = sizeof(cf);
2366 cf.hwndOwner = hwnd;
2368 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
2369 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
2371 if (ChooseFont(&cf)) {
2372 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
2373 cfg.font[sizeof(cfg.font) - 1] = '\0';
2374 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
2375 cfg.fontcharset = lf.lfCharSet;
2376 cfg.fontheight = cf.iPointSize / 10;
2377 fmtfont(fontstatic);
2378 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
2381 case IDC_BELL_DISABLED:
2382 case IDC_BELL_DEFAULT:
2383 case IDC_BELL_WAVEFILE:
2384 case IDC_BELL_VISUAL:
2385 if (HIWORD(wParam) == BN_CLICKED ||
2386 HIWORD(wParam) == BN_DOUBLECLICKED) {
2387 if (LOWORD(wParam) == IDC_BELL_DISABLED)
2388 cfg.beep = BELL_DISABLED;
2389 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
2390 cfg.beep = BELL_DEFAULT;
2391 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
2392 cfg.beep = BELL_WAVEFILE;
2393 if (LOWORD(wParam) == IDC_BELL_VISUAL)
2394 cfg.beep = BELL_VISUAL;
2397 case IDC_B_IND_DISABLED:
2398 case IDC_B_IND_FLASH:
2399 case IDC_B_IND_STEADY:
2400 if (HIWORD(wParam) == BN_CLICKED ||
2401 HIWORD(wParam) == BN_DOUBLECLICKED) {
2402 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
2403 cfg.beep_ind = B_IND_DISABLED;
2404 if (LOWORD(wParam) == IDC_B_IND_FLASH)
2405 cfg.beep_ind = B_IND_FLASH;
2406 if (LOWORD(wParam) == IDC_B_IND_STEADY)
2407 cfg.beep_ind = B_IND_STEADY;
2410 case IDC_BELL_WAVEBROWSE:
2411 memset(&of, 0, sizeof(of));
2412 #ifdef OPENFILENAME_SIZE_VERSION_400
2413 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2415 of.lStructSize = sizeof(of);
2417 of.hwndOwner = hwnd;
2418 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
2419 of.lpstrCustomFilter = NULL;
2420 of.nFilterIndex = 1;
2421 of.lpstrFile = filename;
2422 strcpy(filename, cfg.bell_wavefile);
2423 of.nMaxFile = sizeof(filename);
2424 of.lpstrFileTitle = NULL;
2425 of.lpstrInitialDir = NULL;
2426 of.lpstrTitle = "Select Bell Sound File";
2428 if (GetOpenFileName(&of)) {
2429 strcpy(cfg.bell_wavefile, filename);
2430 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2434 case IDC_BELL_WAVEEDIT:
2435 if (HIWORD(wParam) == EN_CHANGE)
2436 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2438 sizeof(cfg.bell_wavefile) - 1);
2441 if (HIWORD(wParam) == BN_CLICKED ||
2442 HIWORD(wParam) == BN_DOUBLECLICKED)
2444 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
2447 if (HIWORD(wParam) == EN_CHANGE)
2448 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2451 if (HIWORD(wParam) == EN_CHANGE)
2452 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2456 if (HIWORD(wParam) == EN_CHANGE)
2457 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2461 if (HIWORD(wParam) == BN_CLICKED ||
2462 HIWORD(wParam) == BN_DOUBLECLICKED)
2464 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2467 if (HIWORD(wParam) == BN_CLICKED ||
2468 HIWORD(wParam) == BN_DOUBLECLICKED)
2469 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2472 if (HIWORD(wParam) == BN_CLICKED ||
2473 HIWORD(wParam) == BN_DOUBLECLICKED)
2474 cfg.win_name_always =
2475 IsDlgButtonChecked(hwnd, IDC_WINNAME);
2478 if (HIWORD(wParam) == BN_CLICKED ||
2479 HIWORD(wParam) == BN_DOUBLECLICKED)
2481 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2483 case IDC_SUNKENEDGE:
2484 if (HIWORD(wParam) == BN_CLICKED ||
2485 HIWORD(wParam) == BN_DOUBLECLICKED)
2487 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2490 if (HIWORD(wParam) == EN_CHANGE)
2491 MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
2492 &cfg.window_border);
2493 if (cfg.window_border > 32)
2494 cfg.window_border = 32;
2497 if (HIWORD(wParam) == BN_CLICKED ||
2498 HIWORD(wParam) == BN_DOUBLECLICKED)
2499 cfg.cursor_type = 0;
2502 if (HIWORD(wParam) == BN_CLICKED ||
2503 HIWORD(wParam) == BN_DOUBLECLICKED)
2504 cfg.cursor_type = 1;
2507 if (HIWORD(wParam) == BN_CLICKED ||
2508 HIWORD(wParam) == BN_DOUBLECLICKED)
2509 cfg.cursor_type = 2;
2512 if (HIWORD(wParam) == BN_CLICKED ||
2513 HIWORD(wParam) == BN_DOUBLECLICKED)
2515 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2518 if (HIWORD(wParam) == BN_CLICKED ||
2519 HIWORD(wParam) == BN_DOUBLECLICKED)
2521 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2523 case IDC_SCROLLBARFULLSCREEN:
2524 if (HIWORD(wParam) == BN_CLICKED ||
2525 HIWORD(wParam) == BN_DOUBLECLICKED)
2526 cfg.scrollbar_in_fullscreen =
2527 IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN);
2529 case IDC_RESIZETERM:
2530 case IDC_RESIZEFONT:
2531 case IDC_RESIZENONE:
2532 case IDC_RESIZEEITHER:
2533 if (HIWORD(wParam) == BN_CLICKED ||
2534 HIWORD(wParam) == BN_DOUBLECLICKED) {
2536 IsDlgButtonChecked(hwnd,
2537 IDC_RESIZETERM) ? RESIZE_TERM :
2538 IsDlgButtonChecked(hwnd,
2539 IDC_RESIZEFONT) ? RESIZE_FONT :
2540 IsDlgButtonChecked(hwnd,
2541 IDC_RESIZEEITHER) ? RESIZE_EITHER :
2546 if (HIWORD(wParam) == EN_CHANGE)
2547 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2548 sizeof(cfg.wintitle) - 1);
2553 if (HIWORD(wParam) == BN_CLICKED ||
2554 HIWORD(wParam) == BN_DOUBLECLICKED) {
2556 IsDlgButtonChecked(hwnd,
2557 IDC_COEALWAYS) ? COE_ALWAYS :
2558 IsDlgButtonChecked(hwnd,
2559 IDC_COENEVER) ? COE_NEVER :
2564 if (HIWORD(wParam) == BN_CLICKED ||
2565 HIWORD(wParam) == BN_DOUBLECLICKED)
2567 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
2570 if (HIWORD(wParam) == EN_CHANGE)
2571 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
2572 sizeof(cfg.termtype) - 1);
2575 if (HIWORD(wParam) == EN_CHANGE)
2576 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
2577 sizeof(cfg.logfilename) - 1);
2580 memset(&of, 0, sizeof(of));
2581 #ifdef OPENFILENAME_SIZE_VERSION_400
2582 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2584 of.lStructSize = sizeof(of);
2586 of.hwndOwner = hwnd;
2587 of.lpstrFilter = "All Files\0*\0\0\0";
2588 of.lpstrCustomFilter = NULL;
2589 of.nFilterIndex = 1;
2590 of.lpstrFile = filename;
2591 strcpy(filename, cfg.logfilename);
2592 of.nMaxFile = sizeof(filename);
2593 of.lpstrFileTitle = NULL;
2594 of.lpstrInitialDir = NULL;
2595 of.lpstrTitle = "Select session log file";
2597 if (GetSaveFileName(&of)) {
2598 strcpy(cfg.logfilename, filename);
2599 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2603 case IDC_LSTATASCII:
2605 if (HIWORD(wParam) == BN_CLICKED ||
2606 HIWORD(wParam) == BN_DOUBLECLICKED) {
2607 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2609 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2611 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2618 if (HIWORD(wParam) == BN_CLICKED ||
2619 HIWORD(wParam) == BN_DOUBLECLICKED) {
2620 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2621 cfg.logxfovr = LGXF_ASK;
2622 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2623 cfg.logxfovr = LGXF_APN;
2624 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2625 cfg.logxfovr = LGXF_OVR;
2630 if (HIWORD(wParam) == EN_CHANGE)
2631 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2632 sizeof(cfg.termspeed) - 1);
2635 if (HIWORD(wParam) == EN_CHANGE)
2636 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2637 sizeof(cfg.username) - 1);
2639 case IDC_RLLUSEREDIT:
2640 if (HIWORD(wParam) == EN_CHANGE)
2641 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2643 sizeof(cfg.localusername) - 1);
2647 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2651 cfg.passive_telnet =
2652 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2655 if (HIWORD(wParam) == BN_CLICKED ||
2656 HIWORD(wParam) == BN_DOUBLECLICKED) {
2657 char str[sizeof(cfg.environmt)];
2659 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2665 p = str + strlen(str);
2667 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2668 sizeof(str) - 1 - (p - str));
2679 if ((p - cfg.environmt) + strlen(str) + 2 <
2680 sizeof(cfg.environmt)) {
2682 p[strlen(str) + 1] = '\0';
2683 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2685 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2686 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2688 MessageBox(hwnd, "Environment too big",
2689 "PuTTY Error", MB_OK | MB_ICONERROR);
2694 if (HIWORD(wParam) != BN_CLICKED &&
2695 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2697 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2704 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2731 if (HIWORD(wParam) == BN_CLICKED ||
2732 HIWORD(wParam) == BN_DOUBLECLICKED)
2733 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2736 if (HIWORD(wParam) == BN_CLICKED ||
2737 HIWORD(wParam) == BN_DOUBLECLICKED)
2739 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2742 if (HIWORD(wParam) == BN_CLICKED ||
2743 HIWORD(wParam) == BN_DOUBLECLICKED)
2745 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2748 if (HIWORD(wParam) == BN_CLICKED ||
2749 HIWORD(wParam) == BN_DOUBLECLICKED)
2751 IsDlgButtonChecked(hwnd, IDC_SSH2DES);
2754 if (HIWORD(wParam) == BN_CLICKED ||
2755 HIWORD(wParam) == BN_DOUBLECLICKED)
2757 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2759 case IDC_CIPHERLIST:
2762 handle_prefslist(&cipherlist,
2763 cfg.ssh_cipherlist, CIPHER_MAX,
2764 0, hwnd, wParam, lParam);
2768 if (HIWORD(wParam) == BN_CLICKED ||
2769 HIWORD(wParam) == BN_DOUBLECLICKED) {
2770 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2772 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2777 if (HIWORD(wParam) == BN_CLICKED ||
2778 HIWORD(wParam) == BN_DOUBLECLICKED)
2780 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2783 if (HIWORD(wParam) == BN_CLICKED ||
2784 HIWORD(wParam) == BN_DOUBLECLICKED)
2786 IsDlgButtonChecked(hwnd, IDC_AUTHKI);
2789 if (HIWORD(wParam) == EN_CHANGE)
2790 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2791 sizeof(cfg.keyfile) - 1);
2794 if (HIWORD(wParam) == EN_CHANGE)
2795 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2796 sizeof(cfg.remote_cmd) - 1);
2799 memset(&of, 0, sizeof(of));
2800 #ifdef OPENFILENAME_SIZE_VERSION_400
2801 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2803 of.lStructSize = sizeof(of);
2805 of.hwndOwner = hwnd;
2806 of.lpstrFilter = "All Files\0*\0\0\0";
2807 of.lpstrCustomFilter = NULL;
2808 of.nFilterIndex = 1;
2809 of.lpstrFile = filename;
2810 strcpy(filename, cfg.keyfile);
2811 of.nMaxFile = sizeof(filename);
2812 of.lpstrFileTitle = NULL;
2813 of.lpstrInitialDir = NULL;
2814 of.lpstrTitle = "Select Private Key File";
2816 if (GetOpenFileName(&of)) {
2817 strcpy(cfg.keyfile, filename);
2818 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2822 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2825 cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE);
2829 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2831 case IDC_SELTYPELEX:
2832 case IDC_SELTYPERECT:
2833 cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
2835 case IDC_MOUSEOVERRIDE:
2836 cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
2842 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2847 for (i = 0; i < 128; i++)
2848 if (SendDlgItemMessage
2849 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2851 cfg.wordness[i] = n;
2852 SendDlgItemMessage(hwnd, IDC_CCLIST,
2853 LB_DELETESTRING, i, 0);
2854 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2855 (i >= 0x21 && i != 0x7F) ? i : ' ',
2857 SendDlgItemMessage(hwnd, IDC_CCLIST,
2864 case IDC_BOLDCOLOUR:
2865 if (HIWORD(wParam) == BN_CLICKED ||
2866 HIWORD(wParam) == BN_DOUBLECLICKED) {
2869 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2870 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2873 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2875 if (n != 12 + 10 * cfg.bold_colour) {
2876 for (i = n; i-- > 0;)
2877 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2878 LB_DELETESTRING, i, 0);
2879 for (i = 0; i < 22; i++)
2880 if (cfg.bold_colour || permcolour[i])
2881 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2883 (LPARAM) colours[i]);
2885 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2887 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2892 if (HIWORD(wParam) == BN_CLICKED ||
2893 HIWORD(wParam) == BN_DOUBLECLICKED)
2895 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2897 case IDC_COLOURLIST:
2898 if (HIWORD(wParam) == LBN_DBLCLK ||
2899 HIWORD(wParam) == LBN_SELCHANGE) {
2901 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2904 if (!cfg.bold_colour)
2905 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2906 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2908 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2910 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2915 if (HIWORD(wParam) == BN_CLICKED ||
2916 HIWORD(wParam) == BN_DOUBLECLICKED) {
2917 static CHOOSECOLOR cc;
2918 static DWORD custom[16] = { 0 }; /* zero initialisers */
2920 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2923 if (!cfg.bold_colour)
2924 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2925 cc.lStructSize = sizeof(cc);
2926 cc.hwndOwner = hwnd;
2927 cc.hInstance = (HWND) hinst;
2928 cc.lpCustColors = custom;
2930 RGB(cfg.colours[i][0], cfg.colours[i][1],
2932 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2933 if (ChooseColor(&cc)) {
2935 (unsigned char) (cc.rgbResult & 0xFF);
2937 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2939 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2940 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2942 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2944 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2950 if (HIWORD(wParam) == CBN_SELCHANGE) {
2951 int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
2952 CB_GETCURSEL, 0, 0);
2953 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
2954 index, (LPARAM)cfg.line_codepage);
2955 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
2956 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2957 sizeof(cfg.line_codepage) - 1);
2958 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
2959 strcpy(cfg.line_codepage,
2960 cp_name(decode_codepage(cfg.line_codepage)));
2961 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2964 case IDC_CAPSLOCKCYR:
2965 if (HIWORD(wParam) == BN_CLICKED ||
2966 HIWORD(wParam) == BN_DOUBLECLICKED) {
2967 cfg.xlat_capslockcyr =
2968 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
2971 case IDC_VTXWINDOWS:
2977 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2978 : IsDlgButtonChecked(hwnd,
2979 IDC_VTOEMANSI) ? VT_OEMANSI :
2980 IsDlgButtonChecked(hwnd,
2981 IDC_VTOEMONLY) ? VT_OEMONLY :
2982 IsDlgButtonChecked(hwnd,
2983 IDC_VTUNICODE) ? VT_UNICODE :
2986 case IDC_X11_FORWARD:
2987 if (HIWORD(wParam) == BN_CLICKED ||
2988 HIWORD(wParam) == BN_DOUBLECLICKED)
2990 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2993 if (HIWORD(wParam) == BN_CLICKED ||
2994 HIWORD(wParam) == BN_DOUBLECLICKED)
2995 cfg.lport_acceptall =
2996 IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
2998 case IDC_X11_DISPLAY:
2999 if (HIWORD(wParam) == EN_CHANGE)
3000 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
3001 sizeof(cfg.x11_display) - 1);
3004 if (HIWORD(wParam) == BN_CLICKED ||
3005 HIWORD(wParam) == BN_DOUBLECLICKED) {
3006 char str[sizeof(cfg.portfwd)];
3008 if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
3012 GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
3016 "You need to specify a source port number",
3017 "PuTTY Error", MB_OK | MB_ICONERROR);
3020 p = str + strlen(str);
3022 GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
3023 sizeof(str) - 1 - (p - str));
3024 if (!*p || !strchr(p, ':')) {
3026 "You need to specify a destination address\n"
3027 "in the form \"host.name:port\"",
3028 "PuTTY Error", MB_OK | MB_ICONERROR);
3037 if ((p - cfg.portfwd) + strlen(str) + 2 <
3038 sizeof(cfg.portfwd)) {
3040 p[strlen(str) + 1] = '\0';
3041 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
3043 SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
3044 SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
3046 MessageBox(hwnd, "Too many forwardings",
3047 "PuTTY Error", MB_OK | MB_ICONERROR);
3051 case IDC_PFWDREMOVE:
3052 if (HIWORD(wParam) != BN_CLICKED &&
3053 HIWORD(wParam) != BN_DOUBLECLICKED) break;
3054 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
3055 LB_GETCURSEL, 0, 0);
3061 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
3091 int id = ((LPHELPINFO)lParam)->iCtrlId;
3092 char *cmd = help_context_cmd(id);
3094 WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
3095 requested_help = TRUE;
3102 if (requested_help) {
3103 WinHelp(hwnd, help_path, HELP_QUIT, 0);
3104 requested_help = FALSE;
3109 /* Grrr Explorer will maximize Dialogs! */
3111 if (wParam == SIZE_MAXIMIZED)
3117 * Handle application-defined messages eg. DragListBox
3119 /* First find out what the number is (once). */
3120 if (draglistmsg == WM_NULL)
3121 draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
3123 if (msg == draglistmsg) {
3124 /* Only process once dialog is fully formed. */
3125 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
3126 case IDC_CIPHERLIST:
3127 return handle_prefslist(&cipherlist,
3128 cfg.ssh_cipherlist, CIPHER_MAX,
3129 1, hwnd, wParam, lParam);
3138 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
3139 WPARAM wParam, LPARAM lParam)
3141 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
3143 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
3144 EnableWindow(hwnd, 0);
3145 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3146 EnableWindow(hwnd, 1);
3147 SetActiveWindow(hwnd);
3149 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
3152 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
3153 WPARAM wParam, LPARAM lParam)
3155 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
3158 void defuse_showwindow(void)
3161 * Work around the fact that the app's first call to ShowWindow
3162 * will ignore the default in favour of the shell-provided
3167 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
3169 ShowWindow(hwnd, SW_HIDE);
3170 SetActiveWindow(hwnd);
3171 DestroyWindow(hwnd);
3180 savedsession[0] = '\0';
3182 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
3183 get_sesslist(FALSE);
3188 int do_reconfig(HWND hwnd)
3193 backup_cfg = cfg; /* structure copy */
3195 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
3197 cfg = backup_cfg; /* structure copy */
3202 void logevent(char *string)
3207 if (nevents >= negsize) {
3209 events = srealloc(events, negsize * sizeof(*events));
3213 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
3216 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
3217 strcpy(events[nevents], timebuf);
3218 strcat(events[nevents], string);
3221 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
3222 0, (LPARAM) events[nevents]);
3223 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
3224 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
3229 void showeventlog(HWND hwnd)
3232 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
3234 ShowWindow(logbox, SW_SHOWNORMAL);
3236 SetActiveWindow(logbox);
3239 void showabout(HWND hwnd)
3241 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
3244 void verify_ssh_host_key(char *host, int port, char *keytype,
3245 char *keystr, char *fingerprint)
3249 static const char absentmsg[] =
3250 "The server's host key is not cached in the registry. You\n"
3251 "have no guarantee that the server is the computer you\n"
3253 "The server's key fingerprint is:\n"
3255 "If you trust this host, hit Yes to add the key to\n"
3256 "PuTTY's cache and carry on connecting.\n"
3257 "If you want to carry on connecting just once, without\n"
3258 "adding the key to the cache, hit No.\n"
3259 "If you do not trust this host, hit Cancel to abandon the\n"
3262 static const char wrongmsg[] =
3263 "WARNING - POTENTIAL SECURITY BREACH!\n"
3265 "The server's host key does not match the one PuTTY has\n"
3266 "cached in the registry. This means that either the\n"
3267 "server administrator has changed the host key, or you\n"
3268 "have actually connected to another computer pretending\n"
3269 "to be the server.\n"
3270 "The new key fingerprint is:\n"
3272 "If you were expecting this change and trust the new key,\n"
3273 "hit Yes to update PuTTY's cache and continue connecting.\n"
3274 "If you want to carry on connecting but without updating\n"
3275 "the cache, hit No.\n"
3276 "If you want to abandon the connection completely, hit\n"
3277 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
3279 static const char mbtitle[] = "PuTTY Security Alert";
3282 /* sensible fingerprint max size */
3283 (sizeof(absentmsg) > sizeof(wrongmsg) ?
3284 sizeof(absentmsg) : sizeof(wrongmsg))];
3287 * Verify the key against the registry.
3289 ret = verify_host_key(host, port, keytype, keystr);
3291 if (ret == 0) /* success - key matched OK */
3293 if (ret == 2) { /* key was different */
3295 sprintf(message, wrongmsg, fingerprint);
3296 mbret = MessageBox(NULL, message, mbtitle,
3297 MB_ICONWARNING | MB_YESNOCANCEL);
3299 store_host_key(host, port, keytype, keystr);
3300 if (mbret == IDCANCEL)
3303 if (ret == 1) { /* key was absent */
3305 sprintf(message, absentmsg, fingerprint);
3306 mbret = MessageBox(NULL, message, mbtitle,
3307 MB_ICONWARNING | MB_YESNOCANCEL);
3309 store_host_key(host, port, keytype, keystr);
3310 if (mbret == IDCANCEL)
3316 * Ask whether the selected cipher is acceptable (since it was
3317 * below the configured 'warn' threshold).
3318 * cs: 0 = both ways, 1 = client->server, 2 = server->client
3320 void askcipher(char *ciphername, int cs)
3322 static const char mbtitle[] = "PuTTY Security Alert";
3323 static const char msg[] =
3324 "The first %.35scipher supported by the server\n"
3325 "is %.64s, which is below the configured\n"
3326 "warning threshold.\n"
3327 "Do you want to continue with this connection?\n";
3328 /* guessed cipher name + type max length */
3329 char message[100 + sizeof(msg)];
3332 sprintf(message, msg,
3334 (cs == 1) ? "client-to-server " :
3335 "server-to-client ",
3337 mbret = MessageBox(NULL, message, mbtitle,
3338 MB_ICONWARNING | MB_YESNO);
3346 * Ask whether to wipe a session log file before writing to it.
3347 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
3349 int askappend(char *filename)
3351 static const char mbtitle[] = "PuTTY Log to File";
3352 static const char msgtemplate[] =
3353 "The session log file \"%.*s\" already exists.\n"
3354 "You can overwrite it with a new session log,\n"
3355 "append your session log to the end of it,\n"
3356 "or disable session logging for this session.\n"
3357 "Hit Yes to wipe the file, No to append to it,\n"
3358 "or Cancel to disable logging.";
3359 char message[sizeof(msgtemplate) + FILENAME_MAX];
3361 if (cfg.logxfovr != LGXF_ASK) {
3362 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
3364 sprintf(message, msgtemplate, FILENAME_MAX, filename);
3366 mbret = MessageBox(NULL, message, mbtitle,
3367 MB_ICONQUESTION | MB_YESNOCANCEL);
3370 else if (mbret == IDNO)
3377 * Warn about the obsolescent key file format.
3379 void old_keyfile_warning(void)
3381 static const char mbtitle[] = "PuTTY Key File Warning";
3382 static const char message[] =
3383 "You are loading an SSH 2 private key which has an\n"
3384 "old version of the file format. This means your key\n"
3385 "file is not fully tamperproof. Future versions of\n"
3386 "PuTTY may stop supporting this private key format,\n"
3387 "so we recommend you convert your key to the new\n"
3390 "You can perform this conversion by loading the key\n"
3391 "into PuTTYgen and then saving it again.";
3393 MessageBox(NULL, message, mbtitle, MB_OK);