X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/374330e25a6b51c40436fa869a381dd510790f6e..972a41c8b8558a89b9acd5b19a53367de7b1a7c5:/windlg.c diff --git a/windlg.c b/windlg.c index ecd3e5f2..afe96249 100644 --- a/windlg.c +++ b/windlg.c @@ -5,18 +5,16 @@ #include #include -#include "putty.h" #include "ssh.h" +#include "putty.h" #include "win_res.h" -#define NPANELS 7 -#define MAIN_NPANELS 7 -#define RECONF_NPANELS 4 +#define NPANELS 8 +#define MAIN_NPANELS 8 +#define RECONF_NPANELS 5 static const char *const puttystr = PUTTY_REG_POS "\\Sessions"; -static void get_sesslist(int allocate); - static char **negots = NULL; static int nnegots = 0, negsize = 0; static HWND logbox = NULL, abtbox = NULL; @@ -42,8 +40,6 @@ static void mungestr(char *in, char *out) { } static void unmungestr(char *in, char *out) { - int candot = 0; - while (*in) { if (*in == '%' && in[1] && in[2]) { int i, j; @@ -95,16 +91,9 @@ static void gppi(HKEY key, LPCTSTR name, int def, int *i) { *i = val; } -typedef struct { - void *posn; - void *temp; - char dataspace[2048]; -} DTemplate; - static HINSTANCE hinst; -static char **sessions; -static int nsessions; +static int readytogo; static void save_settings (char *section, int do_host) { int i; @@ -116,7 +105,6 @@ static void save_settings (char *section, int do_host) { if (RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1)!=ERROR_SUCCESS || RegCreateKey(subkey1, p, &sesskey) != ERROR_SUCCESS) { - free(p); sesskey = NULL; } @@ -128,15 +116,17 @@ static void save_settings (char *section, int do_host) { wpps (sesskey, "HostName", cfg.host); wppi (sesskey, "PortNumber", cfg.port); wpps (sesskey, "Protocol", - cfg.protocol == PROT_SSH ? "ssh" : "telnet"); + cfg.protocol == PROT_SSH ? "ssh" : + cfg.protocol == PROT_TELNET ? "telnet" : "raw" ); } wppi (sesskey, "CloseOnExit", !!cfg.close_on_exit); + wppi (sesskey, "WarnOnClose", !!cfg.warn_on_close); wpps (sesskey, "TerminalType", cfg.termtype); wpps (sesskey, "TerminalSpeed", cfg.termspeed); { - char buf[2*sizeof(cfg.environ)], *p, *q; + char buf[2*sizeof(cfg.environmt)], *p, *q; p = buf; - q = cfg.environ; + q = cfg.environmt; while (*q) { while (*q) { int c = *q++; @@ -153,6 +143,9 @@ static void save_settings (char *section, int do_host) { wpps (sesskey, "Environment", buf); } wpps (sesskey, "UserName", cfg.username); + wppi (sesskey, "NoPTY", cfg.nopty); + wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" : + cfg.cipher == CIPHER_DES ? "des" : "3des"); wppi (sesskey, "RFCEnviron", cfg.rfc_environ); wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete); wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend); @@ -162,11 +155,13 @@ static void save_settings (char *section, int do_host) { wppi (sesskey, "ScrollbackLines", cfg.savelines); wppi (sesskey, "DECOriginMode", cfg.dec_om); wppi (sesskey, "AutoWrapMode", cfg.wrap_mode); + wppi (sesskey, "LFImpliesCR", cfg.lfhascr); wppi (sesskey, "WinNameAlways", cfg.win_name_always); wppi (sesskey, "TermWidth", cfg.width); wppi (sesskey, "TermHeight", cfg.height); wpps (sesskey, "Font", cfg.font); wppi (sesskey, "FontIsBold", cfg.fontisbold); + wppi (sesskey, "FontCharSet", cfg.fontcharset); wppi (sesskey, "FontHeight", cfg.fontheight); wppi (sesskey, "FontVTMode", cfg.vtmode); wppi (sesskey, "TryPalette", cfg.try_palette); @@ -190,6 +185,8 @@ static void save_settings (char *section, int do_host) { } wpps (sesskey, buf, buf2); } + wppi (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin); + wppi (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr); RegCloseKey(sesskey); } @@ -213,42 +210,45 @@ static void load_settings (char *section, int do_host) { int i; HKEY subkey1, sesskey; char *p; + char prot[10]; p = malloc(3*strlen(section)+1); mungestr(section, p); - - if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS || - RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) { - free(p); + + if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) { sesskey = NULL; + } else { + if (RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) { + sesskey = NULL; + } + RegCloseKey(subkey1); } free(p); - RegCloseKey(subkey1); - if (do_host) { - char prot[10]; - gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host)); - gppi (sesskey, "PortNumber", 23, &cfg.port); - gpps (sesskey, "Protocol", "telnet", prot, 10); - if (!strcmp(prot, "ssh")) - cfg.protocol = PROT_SSH; - else - cfg.protocol = PROT_TELNET; - } else { - cfg.port = 23; - *cfg.host = '\0'; - } + gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host)); + gppi (sesskey, "PortNumber", default_port, &cfg.port); + gpps (sesskey, "Protocol", "default", prot, 10); + if (!strcmp(prot, "ssh")) + cfg.protocol = PROT_SSH; + else if (!strcmp(prot, "telnet")) + cfg.protocol = PROT_TELNET; + else if (!strcmp(prot, "raw")) + cfg.protocol = PROT_RAW; + else + cfg.protocol = default_protocol; + gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit); + gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close); gpps (sesskey, "TerminalType", "xterm", cfg.termtype, sizeof(cfg.termtype)); gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed, sizeof(cfg.termspeed)); { - char buf[2*sizeof(cfg.environ)], *p, *q; + char buf[2*sizeof(cfg.environmt)], *p, *q; gpps (sesskey, "Environment", "", buf, sizeof(buf)); p = buf; - q = cfg.environ; + q = cfg.environmt; while (*p) { while (*p && *p != ',') { int c = *p++; @@ -264,6 +264,17 @@ static void load_settings (char *section, int do_host) { *q = '\0'; } gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username)); + gppi (sesskey, "NoPTY", 0, &cfg.nopty); + { + char cipher[10]; + gpps (sesskey, "Cipher", "3des", cipher, 10); + if (!strcmp(cipher, "blowfish")) + cfg.cipher = CIPHER_BLOWFISH; + else if (!strcmp(cipher, "des")) + cfg.cipher = CIPHER_DES; + else + cfg.cipher = CIPHER_3DES; + } gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ); gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete); gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend); @@ -273,11 +284,13 @@ static void load_settings (char *section, int do_host) { gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines); gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om); gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode); + gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr); gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always); gppi (sesskey, "TermWidth", 80, &cfg.width); gppi (sesskey, "TermHeight", 24, &cfg.height); gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font)); gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold); + gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset); gppi (sesskey, "FontHeight", 10, &cfg.fontheight); gppi (sesskey, "FontVTMode", VT_POORMAN, &cfg.vtmode); gppi (sesskey, "TryPalette", 0, &cfg.try_palette); @@ -320,6 +333,9 @@ static void load_settings (char *section, int do_host) { cfg.wordness[j] = atoi(q); } } + gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin); + gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr); + RegCloseKey(sesskey); } @@ -359,10 +375,32 @@ static int CALLBACK LogProc (HWND hwnd, UINT msg, return 0; } +static int CALLBACK LicenceProc (HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_INITDIALOG: + return 1; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + abtbox = NULL; + DestroyWindow (hwnd); + return 0; + } + return 0; + case WM_CLOSE: + abtbox = NULL; + DestroyWindow (hwnd); + return 0; + } + return 0; +} + static int CALLBACK AboutProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: + SetDlgItemText (hwnd, IDA_VERSION, ver); return 1; /* case WM_CTLCOLORDLG: */ /* return (int) GetStockObject (LTGRAY_BRUSH); */ @@ -378,7 +416,7 @@ static int CALLBACK AboutProc (HWND hwnd, UINT msg, case IDA_LICENCE: EnableWindow(hwnd, 0); DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX), - NULL, AboutProc); + NULL, LicenceProc); EnableWindow(hwnd, 1); return 0; } @@ -421,18 +459,31 @@ static int CALLBACK ConnectionProc (HWND hwnd, UINT msg, for (i = 0; i < nsessions; i++) SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING, 0, (LPARAM) (sessions[i])); - CheckRadioButton (hwnd, IDC0_PROTTELNET, IDC0_PROTSSH, - cfg.protocol==PROT_SSH ? IDC0_PROTSSH : IDC0_PROTTELNET); + CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH, + cfg.protocol==PROT_SSH ? IDC0_PROTSSH : + cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW ); CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit); + CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close); break; + case WM_LBUTTONUP: + /* + * Button release should trigger WM_OK if there was a + * previous double click on the session list. + */ + ReleaseCapture(); + if (readytogo) + SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0); + break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC0_PROTTELNET: case IDC0_PROTSSH: + case IDC0_PROTRAW: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH); - cfg.protocol = i ? PROT_SSH : PROT_TELNET; + int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET); + cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ; if ((cfg.protocol == PROT_SSH && cfg.port == 23) || (cfg.protocol == PROT_TELNET && cfg.port == 22)) { cfg.port = i ? 22 : 23; @@ -454,6 +505,11 @@ static int CALLBACK ConnectionProc (HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT); break; + case IDC0_CLOSEWARN: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN); + break; case IDC0_SESSEDIT: if (HIWORD(wParam) == EN_CHANGE) SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL, @@ -508,10 +564,11 @@ static int CALLBACK ConnectionProc (HWND hwnd, UINT msg, !!strcmp(sessions[n], "Default Settings")); SetDlgItemText (hwnd, IDC0_HOST, cfg.host); SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE); - CheckRadioButton (hwnd, IDC0_PROTTELNET, IDC0_PROTSSH, + CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH, (cfg.protocol==PROT_SSH ? IDC0_PROTSSH : - IDC0_PROTTELNET)); + cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW)); CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit); + CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close); SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL, (WPARAM) -1, 0); } @@ -522,8 +579,10 @@ static int CALLBACK ConnectionProc (HWND hwnd, UINT msg, * Unless it's Default Settings or some other * host-less set of saved settings. */ - if (*cfg.host) - SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0); + if (*cfg.host) { + readytogo = TRUE; + SetCapture(hwnd); + } } break; case IDC0_SESSDEL: @@ -618,6 +677,7 @@ static int CALLBACK TerminalProc (HWND hwnd, UINT msg, CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode); CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always); CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om); + CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr); SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE); SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE); SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE); @@ -646,6 +706,11 @@ static int CALLBACK TerminalProc (HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM); break; + case IDC2_LFHASCR: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR); + break; case IDC2_ROWSEDIT: if (HIWORD(wParam) == EN_CHANGE) MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height); @@ -663,7 +728,7 @@ static int CALLBACK TerminalProc (HWND hwnd, UINT msg, lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0; lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0; lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0); - lf.lfCharSet = ANSI_CHARSET; + lf.lfCharSet = cfg.fontcharset; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; @@ -681,6 +746,7 @@ static int CALLBACK TerminalProc (HWND hwnd, UINT msg, strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1); cfg.font[sizeof(cfg.font)-1] = '\0'; cfg.fontisbold = (lf.lfWeight == FW_BOLD); + cfg.fontcharset = lf.lfCharSet; cfg.fontheight = lf.lfHeight; fmtfont (fontstatic); SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic); @@ -712,7 +778,7 @@ static int CALLBACK TelnetProc (HWND hwnd, UINT msg, SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed); SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username); { - char *p = cfg.environ; + char *p = cfg.environmt; while (*p) { SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0, (LPARAM) p); @@ -746,7 +812,7 @@ static int CALLBACK TelnetProc (HWND hwnd, UINT msg, case IDC3_ENVADD: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { - char str[sizeof(cfg.environ)]; + char str[sizeof(cfg.environmt)]; char *p; GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1); if (!*str) { @@ -760,12 +826,12 @@ static int CALLBACK TelnetProc (HWND hwnd, UINT msg, MessageBeep(0); break; } - p = cfg.environ; + p = cfg.environmt; while (*p) { while (*p) p++; p++; } - if ((p-cfg.environ) + strlen(str) + 2 < sizeof(cfg.environ)) { + if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) { strcpy (p, str); p[strlen(str)+1] = '\0'; SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, @@ -790,7 +856,7 @@ static int CALLBACK TelnetProc (HWND hwnd, UINT msg, SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING, i, 0); - p = cfg.environ; + p = cfg.environmt; while (i > 0) { if (!*p) goto disaster; @@ -824,6 +890,12 @@ static int CALLBACK SshProc (HWND hwnd, UINT msg, case WM_INITDIALOG: SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype); SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username); + CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty); + CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES, + cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF : + cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES : + + IDC3_CIPHER3DES); break; case WM_COMMAND: switch (LOWORD(wParam)) { @@ -837,6 +909,24 @@ static int CALLBACK SshProc (HWND hwnd, UINT msg, GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username, sizeof(cfg.username)-1); break; + case IDC3_NOPTY: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY); + break; + case IDC3_CIPHER3DES: + case IDC3_CIPHERBLOWF: + case IDC3_CIPHERDES: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES)) + cfg.cipher = CIPHER_3DES; + else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF)) + cfg.cipher = CIPHER_BLOWFISH; + else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES)) + cfg.cipher = CIPHER_DES; + } + break; } break; } @@ -1016,10 +1106,36 @@ static int CALLBACK ColourProc (HWND hwnd, UINT msg, return GeneralPanelProc (hwnd, msg, wParam, lParam); } -static DTemplate negot, main, reconf, panels[NPANELS]; +static int CALLBACK LanguageProc (HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_INITDIALOG: + CheckDlgButton (hwnd, IDC6_ENABLEKOIWINXLAT, cfg.xlat_enablekoiwin); + CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr); + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC6_ENABLEKOIWINXLAT: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + cfg.xlat_enablekoiwin = + IsDlgButtonChecked (hwnd, IDC6_ENABLEKOIWINXLAT); + } + break; + case IDC6_CAPSLOCKCYR: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + cfg.xlat_capslockcyr = + IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR); + } + break; + } + } + return GeneralPanelProc (hwnd, msg, wParam, lParam); +} + static DLGPROC panelproc[NPANELS] = { ConnectionProc, KeyboardProc, TerminalProc, - TelnetProc, SshProc, SelectionProc, ColourProc + TelnetProc, SshProc, SelectionProc, ColourProc, LanguageProc }; static char *panelids[NPANELS] = { MAKEINTRESOURCE(IDD_PANEL0), @@ -1028,14 +1144,17 @@ static char *panelids[NPANELS] = { MAKEINTRESOURCE(IDD_PANEL3), MAKEINTRESOURCE(IDD_PANEL35), MAKEINTRESOURCE(IDD_PANEL4), - MAKEINTRESOURCE(IDD_PANEL5) + MAKEINTRESOURCE(IDD_PANEL5), + MAKEINTRESOURCE(IDD_PANEL6) }; + static char *names[NPANELS] = { - "Connection", "Keyboard", "Terminal", "Telnet", "SSH", "Selection", "Colours" + "Connection", "Keyboard", "Terminal", "Telnet", + "SSH", "Selection", "Colours", "Language" }; -static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6 }; -static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6 }; +static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7}; static int GenericMainDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, @@ -1154,7 +1273,7 @@ static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg, RECONF_NPANELS, reconfp, &page); } -static void get_sesslist(int allocate) { +void get_sesslist(int allocate) { static char *buffer; int buflen, bufsize, i, ret; char otherbuf[2048];