X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/32874aeac8dacbca26663777b39a79efc5d8dc4b..d0718310cebfcc7b26136d53cc63e1cca2060e5c:/windlg.c diff --git a/windlg.c b/windlg.c index 76f1ecae..8ad85bbe 100644 --- a/windlg.c +++ b/windlg.c @@ -16,6 +16,7 @@ static char **events = NULL; static int nevents = 0, negsize = 0; static int readytogo; +static int sesslist_has_focus; void force_normal(HWND hwnd) { @@ -128,7 +129,7 @@ static int CALLBACK LogProc(HWND hwnd, UINT msg, memcpy(p, sel_nl, sizeof(sel_nl)); p += sizeof(sel_nl); } - write_clip(clipdata, size, TRUE); + write_aclip(clipdata, size, TRUE); sfree(clipdata); } sfree(selitems); @@ -291,6 +292,7 @@ enum { IDCX_ABOUT = IDC_CURAPPLIC, IDC_COMPOSEKEY, IDC_CTRLALTKEYS, + IDC_TELNETKEY, keyboardpanelend, terminalpanelstart, @@ -408,6 +410,9 @@ enum { IDCX_ABOUT = IDC_EMSTATIC, IDC_EMBSD, IDC_EMRFC, + IDC_ACTSTATIC, + IDC_TPASSIVE, + IDC_TACTIVE, telnetpanelend, rloginpanelstart, @@ -482,18 +487,14 @@ enum { IDCX_ABOUT = IDC_TITLE_TRANSLATION, IDC_BOX_TRANSLATION1, IDC_BOX_TRANSLATION2, - IDC_BOX_TRANSLATION3, - IDC_XLATSTATIC, - IDC_NOXLAT, - IDC_KOI8WIN1251, - IDC_88592WIN1250, - IDC_88592CP852, - IDC_CAPSLOCKCYR, + IDC_CODEPAGESTATIC, + IDC_CODEPAGE, IDC_VTSTATIC, IDC_VTXWINDOWS, IDC_VTOEMANSI, IDC_VTOEMONLY, IDC_VTPOORMAN, + IDC_VTUNICODE, translationpanelend, tunnelspanelstart, @@ -538,14 +539,16 @@ static void fmtfont(char *buf) (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight)); } -static void init_dlg_ctrls(HWND hwnd) +/* 2nd arg: NZ => don't redraw session list (use when loading + * a new session) */ +static void init_dlg_ctrls(HWND hwnd, int keepsess) { int i; char fontstatic[256]; SetDlgItemText(hwnd, IDC_HOST, cfg.host); SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession); - { + if (!keepsess) { int i, n; n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0); for (i = n; i-- > 0;) @@ -585,6 +588,7 @@ static void init_dlg_ctrls(HWND hwnd) CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only); CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key); CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys); + CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard); CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO, cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND : cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO); @@ -658,6 +662,8 @@ static void init_dlg_ctrls(HWND hwnd) } CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC, cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD); + CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE, + cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE); SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype); SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username); @@ -684,7 +690,7 @@ static void init_dlg_ctrls(HWND hwnd) SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4, (LPARAM) tabs); } - for (i = 0; i < 256; i++) { + for (i = 0; i < 128; i++) { char str[100]; sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i, (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]); @@ -710,15 +716,12 @@ static void init_dlg_ctrls(HWND hwnd) SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE); SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE); - CheckRadioButton(hwnd, IDC_NOXLAT, IDC_88592CP852, - cfg.xlat_88592w1250 ? IDC_88592WIN1250 : - cfg.xlat_88592cp852 ? IDC_88592CP852 : - cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 : IDC_NOXLAT); - CheckDlgButton(hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr); - CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN, + SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage); + CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE, cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS : cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI : cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY : + cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE : IDC_VTPOORMAN); CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward); @@ -774,7 +777,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL); if (backends[3].backend == NULL) { /* this is PuTTYtel, so only three protocols available */ - radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4, + radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3, "&Raw", IDC_PROTRAW, "&Telnet", IDC_PROTTELNET, "Rlog&in", IDC_PROTRLOGIN, NULL); @@ -1011,21 +1014,12 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI, "Use font in O&EM mode only", IDC_VTOEMONLY, "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")", - IDC_VTPOORMAN, NULL); + IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL); endbox(&cp); beginbox(&cp, "Enable character set translation on received data", IDC_BOX_TRANSLATION2); - radiobig(&cp, - "Character set &translation:", IDC_XLATSTATIC, - "None", IDC_NOXLAT, - "KOI8 / Win-1251", IDC_KOI8WIN1251, - "ISO-8859-2 / Win-1250", IDC_88592WIN1250, - "ISO-8859-2 / CP852", IDC_88592CP852, NULL); - endbox(&cp); - beginbox(&cp, "Enable character set translation on input data", - IDC_BOX_TRANSLATION3); - checkbox(&cp, "CAP&S LOCK acts as cyrillic switch", - IDC_CAPSLOCKCYR); + multiedit(&cp, "Line codepage:", IDC_CODEPAGESTATIC, + IDC_CODEPAGE, 100, NULL); endbox(&cp); } @@ -1093,6 +1087,11 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50); endbox(&cp); + } else { + beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1); + checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt", + IDC_TELNETKEY); + endbox(&cp); } beginbox(&cp, "Sending of null packets to keep session active", IDC_BOX_CONNECTION2); @@ -1102,7 +1101,7 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) } if (panel == telnetpanelstart) { - /* The Telnet panel. Accelerators used: [acgo] svldr bf */ + /* The Telnet panel. Accelerators used: [acgo] svldr bftk */ struct ctlpos cp; ctlposinit(&cp, hwnd, 80, 3, 13); if (dlgtype == 0) { @@ -1120,6 +1119,11 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD, "R&FC 1408 (unusual)", IDC_EMRFC, NULL); + radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2, + "Passive", IDC_TPASSIVE, "Active", + IDC_TACTIVE, NULL); + checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt", + IDC_TELNETKEY); endbox(&cp); } } @@ -1192,6 +1196,33 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) } } +/* + * Helper function to load the session selected in SESSLIST + * if any, as this is done in more than one place in + * GenericMainDlgProc(). 0 => failure. + */ +static int load_selected_session(HWND hwnd) +{ + int n = SendDlgItemMessage(hwnd, IDC_SESSLIST, + LB_GETCURSEL, 0, 0); + int isdef; + if (n == LB_ERR) { + MessageBeep(0); + return 0; + } + isdef = !strcmp(sessions[n], "Default Settings"); + load_settings(sessions[n], !isdef, &cfg); + init_dlg_ctrls(hwnd, TRUE); + if (!isdef) + SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]); + else + SetDlgItemText(hwnd, IDC_SESSEDIT, ""); + /* Restore the selection, which will have been clobbered by + * SESSEDIT handling. */ + SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0); + return 1; +} + /* * This function is the configuration box. */ @@ -1214,6 +1245,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, case WM_INITDIALOG: readytogo = 0; SetWindowLong(hwnd, GWL_USERDATA, 0); + SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG, + (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON))); /* * Centre the window. */ @@ -1311,6 +1344,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, } SetWindowLong(hwnd, GWL_USERDATA, 1); + sesslist_has_focus = 0; return 0; case WM_LBUTTONUP: /* @@ -1370,7 +1404,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, if (!strcmp(buffer, "Translation")) create_controls(hwnd, dlgtype, translationpanelstart); - init_dlg_ctrls(hwnd); + init_dlg_ctrls(hwnd, FALSE); SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */ return 0; @@ -1383,6 +1417,16 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) { case IDOK: + /* Behaviour of the "Open" button is different if the + * session list has focus, *unless* the user just + * double-clicked... */ + if (sesslist_has_focus && !readytogo) { + if (!load_selected_session(hwnd)) { + MessageBeep(0); + return 0; + } + } + /* If at this point we have a valid session, go! */ if (*cfg.host) EndDialog(hwnd, 1); else @@ -1462,6 +1506,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, &cfg); get_sesslist(FALSE); get_sesslist(TRUE); + SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW, + FALSE, 0); SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT, 0, 0); for (i = 0; i < nsessions; i++) @@ -1470,32 +1516,28 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, (LPARAM) (sessions[i])); SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, (WPARAM) - 1, 0); + SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW, + TRUE, 0); + InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL, + TRUE); } break; case IDC_SESSLIST: case IDC_SESSLOAD: + if (LOWORD(wParam) == IDC_SESSLIST) { + if (HIWORD(wParam) == LBN_SETFOCUS) + sesslist_has_focus = 1; + else if (HIWORD(wParam) == LBN_KILLFOCUS) + sesslist_has_focus = 0; + } if (LOWORD(wParam) == IDC_SESSLOAD && HIWORD(wParam) != BN_CLICKED && HIWORD(wParam) != BN_DOUBLECLICKED) break; if (LOWORD(wParam) == IDC_SESSLIST && HIWORD(wParam) != LBN_DBLCLK) break; - { - int n = SendDlgItemMessage(hwnd, IDC_SESSLIST, - LB_GETCURSEL, 0, 0); - int isdef; - if (n == LB_ERR) { - MessageBeep(0); - break; - } - isdef = !strcmp(sessions[n], "Default Settings"); - load_settings(sessions[n], !isdef, &cfg); - init_dlg_ctrls(hwnd); - if (!isdef) - SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]); - else - SetDlgItemText(hwnd, IDC_SESSEDIT, ""); - } - if (LOWORD(wParam) == IDC_SESSLIST) { + /* Load the session selected in SESSLIST. */ + if (load_selected_session(hwnd) && + LOWORD(wParam) == IDC_SESSLIST) { /* * A double-click on a saved session should * actually start the session, not just load it. @@ -1520,6 +1562,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, del_settings(sessions[n]); get_sesslist(FALSE); get_sesslist(TRUE); + SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW, + FALSE, 0); SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT, 0, 0); for (i = 0; i < nsessions; i++) @@ -1528,6 +1572,10 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, (LPARAM) (sessions[i])); SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, (WPARAM) - 1, 0); + SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW, + TRUE, 0); + InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL, + TRUE); } case IDC_PINGEDIT: if (HIWORD(wParam) == EN_CHANGE) @@ -1690,6 +1738,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.ctrlaltkeys = IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS); break; + case IDC_TELNETKEY: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.telnet_keyboard = + IsDlgButtonChecked(hwnd, IDC_TELNETKEY); + break; case IDC_WRAPMODE: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) @@ -1720,7 +1774,13 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines); break; case IDC_CHOOSEFONT: - lf.lfHeight = cfg.fontheight; + { + HDC hdc = GetDC(0); + lf.lfHeight = -MulDiv(cfg.fontheight, + GetDeviceCaps(hdc, LOGPIXELSY), + 72); + ReleaseDC(0, hdc); + } lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0; lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0; lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0); @@ -1981,6 +2041,11 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, case IDC_EMRFC: cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC); break; + case IDC_TPASSIVE: + case IDC_TACTIVE: + cfg.passive_telnet = + IsDlgButtonChecked(hwnd, IDC_TPASSIVE); + break; case IDC_ENVADD: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { @@ -2160,7 +2225,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, if (!ok) MessageBeep(0); else { - for (i = 0; i < 256; i++) + for (i = 0; i < 128; i++) if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) { char str[100]; @@ -2183,6 +2248,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, int n, i; cfg.bold_colour = IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR); + SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW, + FALSE, 0); n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0); @@ -2196,6 +2263,10 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, LB_ADDSTRING, 0, (LPARAM) colours[i]); } + SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW, + TRUE, 0); + InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL, + TRUE); } break; case IDC_PALETTE: @@ -2207,9 +2278,10 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, case IDC_COLOURLIST: if (HIWORD(wParam) == LBN_DBLCLK || HIWORD(wParam) == LBN_SELCHANGE) { - int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST, - LB_GETCURSEL, - 0, 0); + int i = + SendDlgItemMessage(hwnd, IDC_COLOURLIST, + LB_GETCURSEL, + 0, 0); if (!cfg.bold_colour) i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2); SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0], @@ -2225,9 +2297,10 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) { static CHOOSECOLOR cc; static DWORD custom[16] = { 0 }; /* zero initialisers */ - int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST, - LB_GETCURSEL, - 0, 0); + int i = + SendDlgItemMessage(hwnd, IDC_COLOURLIST, + LB_GETCURSEL, + 0, 0); if (!cfg.bold_colour) i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2); cc.lStructSize = sizeof(cc); @@ -2254,34 +2327,44 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, } } break; - case IDC_NOXLAT: - case IDC_KOI8WIN1251: - case IDC_88592WIN1250: - case IDC_88592CP852: - cfg.xlat_enablekoiwin = - IsDlgButtonChecked(hwnd, IDC_KOI8WIN1251); - cfg.xlat_88592w1250 = - IsDlgButtonChecked(hwnd, IDC_88592WIN1250); - cfg.xlat_88592cp852 = - IsDlgButtonChecked(hwnd, IDC_88592CP852); - break; - case IDC_CAPSLOCKCYR: - if (HIWORD(wParam) == BN_CLICKED || - HIWORD(wParam) == BN_DOUBLECLICKED) { - cfg.xlat_capslockcyr = - IsDlgButtonChecked(hwnd, IDC_CAPSLOCKCYR); + case IDC_CODEPAGE: + if (HIWORD(wParam) == EN_CHANGE) + GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage, + sizeof(cfg.line_codepage) - 1); + if (HIWORD(wParam) == EN_KILLFOCUS) { + int cp = decode_codepage(cfg.line_codepage); + char buf[256]; + if (cp < -1) { + if (cp == -2) + sprintf(buf, + "Unable to identify character set '%s', " + "translation disabled.", + cfg.line_codepage); + if (cp == -3) + sprintf(buf, + "Character set '%s' is a DBCS, " + "translation is not available.", + cfg.line_codepage); + MessageBox(hwnd, buf, "PuTTY Error", + MB_ICONERROR | MB_OK); + } + strcpy(cfg.line_codepage, cp_name(cp)); + SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage); } break; case IDC_VTXWINDOWS: case IDC_VTOEMANSI: case IDC_VTOEMONLY: case IDC_VTPOORMAN: + case IDC_VTUNICODE: cfg.vtmode = (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS : IsDlgButtonChecked(hwnd, IDC_VTOEMANSI) ? VT_OEMANSI : IsDlgButtonChecked(hwnd, IDC_VTOEMONLY) ? VT_OEMONLY : + IsDlgButtonChecked(hwnd, + IDC_VTUNICODE) ? VT_UNICODE : VT_POORMAN); break; case IDC_X11_FORWARD: @@ -2429,7 +2512,9 @@ void verify_ssh_host_key(char *host, int port, char *keytype, "%s\n" "If you trust this host, hit Yes to add the key to\n" "PuTTY's cache and carry on connecting.\n" - "If you do not trust this host, hit No to abandon the\n" + "If you want to carry on connecting just once, without\n" + "adding the key to the cache, hit No.\n" + "If you do not trust this host, hit Cancel to abandon the\n" "connection.\n"; static const char wrongmsg[] = @@ -2451,9 +2536,8 @@ void verify_ssh_host_key(char *host, int port, char *keytype, static const char mbtitle[] = "PuTTY Security Alert"; - char message[160 + - /* sensible fingerprint max size */ + /* sensible fingerprint max size */ (sizeof(absentmsg) > sizeof(wrongmsg) ? sizeof(absentmsg) : sizeof(wrongmsg))]; @@ -2478,10 +2562,11 @@ void verify_ssh_host_key(char *host, int port, char *keytype, int mbret; sprintf(message, absentmsg, fingerprint); mbret = MessageBox(NULL, message, mbtitle, - MB_ICONWARNING | MB_YESNO); - if (mbret == IDNO) + MB_ICONWARNING | MB_YESNOCANCEL); + if (mbret == IDYES) + store_host_key(host, port, keytype, keystr); + if (mbret == IDCANCEL) exit(0); - store_host_key(host, port, keytype, keystr); } }