From 0d2086c5db1f23869109ba6776cb6d2e6037714c Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 6 Mar 2002 23:04:20 +0000 Subject: [PATCH] Add the Features panel, allowing you to disable a bunch of the more controversial terminal features. git-svn-id: svn://svn.tartarus.org/sgt/putty@1576 cda61777-01e9-0310-a592-d414129be87e --- doc/config.but | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- putty.h | 6 ++++ settings.c | 10 ++++++ terminal.c | 89 ++++++++++++++++++++++++++++++++++++++--------------- windlg.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ window.c | 3 ++ 6 files changed, 260 insertions(+), 40 deletions(-) diff --git a/doc/config.but b/doc/config.but index 604fcb16..b7e16acd 100644 --- a/doc/config.but +++ b/doc/config.but @@ -1,4 +1,4 @@ -\versionid $Id: config.but,v 1.26 2002/02/24 15:25:19 simon Exp $ +\versionid $Id: config.but,v 1.27 2002/03/06 23:04:20 simon Exp $ \C{config} Configuring PuTTY @@ -469,8 +469,11 @@ they send \c{ESC OA} through to \c{ESC OD}. Application Cursor Keys mode can be turned on and off by the server, depending on the application. PuTTY allows you to configure the -initial state, and also allows you to disable application mode -completely. +initial state. + +You can also disable application cursor keys mode completely, using +the \q{Features} configuration panel; see +\k{config-features-application}. \S{config-appkeypad} Controlling Application Keypad mode @@ -494,8 +497,11 @@ function key. This is unavoidable. Application keypad mode can be turned on and off by the server, depending on the application. PuTTY allows you to configure the -initial state, and also allows you to disable application mode -completely. +initial state. + +You can also disable application keypad mode completely, using the +\q{Features} configuration panel; see +\k{config-features-application}. \S{config-nethack} Using NetHack keypad mode @@ -641,6 +647,86 @@ constitute an overload, how short a time period they have to arrive in to do so, and how much silent time is required before the overload feature will deactivate itself. +\H{config-features} The Features panel + +PuTTY's terminal emulation is very highly featured, and can do a lot +of things under remote server control. Some of these features can +cause problems due to buggy or strangely configured server +applications. + +The Features configuration panel allows you to disable some of +PuTTY's more advanced terminal features, in case they cause trouble. + +\S{config-features-application} Disabling application keypad and cursor keys + +\cfg{winhelp-topic}{features.application} + +Application keypad mode (see \k{config-appkeypad}) and application +cursor keys mode (see \k{config-appcursor}) alter the behaviour of +the keypad and cursor keys. Some applications enable these modes but +then do not deal correctly with the modified keys. You can force +these modes to be permanently disabled no matter what the server +tries to do. + +\S{config-features-resize} Disabling remote terminal resizing + +\cfg{winhelp-topic}{features.resize} + +PuTTY has the ability to change the terminal's size and position in +response to commands from the server. If you find PuTTY is doing +this unexpectedly or inconveniently, you can tell PuTTY not to +respond to those server commands. + +\S{config-features-altscreen} Disabling switching to the alternate screen + +\cfg{winhelp-topic}{features.altscreen} + +Many terminals, including PuTTY, support an \q{alternate screen}. +This is the same size as the ordinary terminal screen, but separate. +Typically a screen-based program such as a text editor might switch +the terminal to the alternate screen before starting up. Then at the +end of the run, it switches back to the primary screen, and you see +the screen contents just as they were before starting the editor. + +Some people prefer this not to happen. If you want your editor to +run in the same screen as the rest of your terminal activity, you +can disable the alternate screen feature completely. + +\S{config-features-retitle} Disabling remote window title changing + +\cfg{winhelp-topic}{features.retitle} + +PuTTY has the ability to change the window title in response to +commands from the server. If you find PuTTY is doing this +unexpectedly or inconveniently, you can tell PuTTY not to respond to +those server commands. + +\S{config-features-dbackspace} Disabling destructive backspace + +\cfg{winhelp-topic}{features.dbackspace} + +Normally, when PuTTY receives character 127 (^?) from the server, it +will perform a \q{destructive backspace}: move the cursor one space +left and delete the character under it. This can apparently cause +problems in some applications, so PuTTY provides the ability to +configure character 127 to perform a normal backspace (without +deleting a character) instead. + +\S{config-features-charset} Disabling remote character set +configuration + +\cfg{winhelp-topic}{features.charset} + +PuTTY has the ability to change its character set configuration in +response to commands from the server. Some programs send these +commands unexpectedly or inconveniently. In particular, BitchX (an +IRC client) seems to have a habit of reconfiguring the character set +to something other than the user intended. + +If you find that accented characters are not showing up the way you +expect them to, particularly if you're running BitchX, you could try +disabling the remote character set configuration commands. + \H{config-window} The Window panel The Window configuration panel allows you to control aspects of the diff --git a/putty.h b/putty.h index 04804c27..52e39dfc 100644 --- a/putty.h +++ b/putty.h @@ -277,6 +277,11 @@ typedef struct { int funky_type; int no_applic_c; /* totally disable app cursor keys */ int no_applic_k; /* totally disable app keypad */ + int no_remote_resize; /* disable remote resizing */ + int no_alt_screen; /* disable alternate screen */ + int no_remote_wintitle; /* disable remote retitling */ + int no_dbackspace; /* disable destructive backspace */ + int no_remote_charset; /* disable remote charset config */ int app_cursor; int app_keypad; int nethack_keypad; @@ -490,6 +495,7 @@ int from_backend(int is_stderr, char *data, int len); void logfopen(void); void logfclose(void); void term_copyall(void); +void term_reconfig(void); /* * Exports from logging.c. diff --git a/settings.c b/settings.c index 03401858..aead1061 100644 --- a/settings.c +++ b/settings.c @@ -189,6 +189,11 @@ void save_settings(char *section, int do_host, Config * cfg) write_setting_i(sesskey, "LinuxFunctionKeys", cfg->funky_type); write_setting_i(sesskey, "NoApplicationKeys", cfg->no_applic_k); write_setting_i(sesskey, "NoApplicationCursors", cfg->no_applic_c); + write_setting_i(sesskey, "NoRemoteResize", cfg->no_remote_resize); + write_setting_i(sesskey, "NoAltScreen", cfg->no_alt_screen); + write_setting_i(sesskey, "NoRemoteWinTitle", cfg->no_remote_wintitle); + write_setting_i(sesskey, "NoDBackspace", cfg->no_dbackspace); + write_setting_i(sesskey, "NoRemoteCharset", cfg->no_remote_charset); write_setting_i(sesskey, "ApplicationCursorKeys", cfg->app_cursor); write_setting_i(sesskey, "ApplicationKeypad", cfg->app_keypad); write_setting_i(sesskey, "NetHackKeypad", cfg->nethack_keypad); @@ -380,6 +385,11 @@ void load_settings(char *section, int do_host, Config * cfg) gppi(sesskey, "LinuxFunctionKeys", 0, &cfg->funky_type); gppi(sesskey, "NoApplicationKeys", 0, &cfg->no_applic_k); gppi(sesskey, "NoApplicationCursors", 0, &cfg->no_applic_c); + gppi(sesskey, "NoRemoteResize", 0, &cfg->no_remote_resize); + gppi(sesskey, "NoAltScreen", 0, &cfg->no_alt_screen); + gppi(sesskey, "NoRemoteWinTitle", 0, &cfg->no_remote_wintitle); + gppi(sesskey, "NoDBackspace", 0, &cfg->no_dbackspace); + gppi(sesskey, "NoRemoteCharset", 0, &cfg->no_remote_charset); gppi(sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor); gppi(sesskey, "ApplicationKeypad", 0, &cfg->app_keypad); gppi(sesskey, "NetHackKeypad", 0, &cfg->nethack_keypad); diff --git a/terminal.c b/terminal.c index 7b69e06e..a322debd 100644 --- a/terminal.c +++ b/terminal.c @@ -351,6 +351,21 @@ void term_pwron(void) } /* + * When the user reconfigures us, we need to check the forbidden- + * alternate-screen config option. + */ +void term_reconfig(void) +{ + if (cfg.no_alt_screen) + swap_screen(0); + if (cfg.no_remote_charset) { + cset_attr[0] = cset_attr[1] = ATTR_ASCII; + sco_acs = alt_sco_acs = 0; + utf = 0; + } +} + +/* * Clear the scrollback. */ void term_clrsb(void) @@ -877,7 +892,8 @@ static void toggle_mode(int mode, int query, int state) break; case 3: /* 80/132 columns */ deselect(); - request_resize(state ? 132 : 80, rows); + if (!cfg.no_remote_resize) + request_resize(state ? 132 : 80, rows); reset_132 = state; break; case 5: /* reverse video */ @@ -929,7 +945,7 @@ static void toggle_mode(int mode, int query, int state) case 47: /* alternate screen */ compatibility(OTHER); deselect(); - swap_screen(state); + swap_screen(cfg.no_alt_screen ? 0 : state); disptop = 0; break; case 1000: /* xterm mouse 1 */ @@ -972,13 +988,15 @@ static void do_osc(void) switch (esc_args[0]) { case 0: case 1: - set_icon(osc_string); + if (!cfg.no_remote_wintitle) + set_icon(osc_string); if (esc_args[0] == 1) break; /* fall through: parameter 0 means set both */ case 2: case 21: - set_title(osc_string); + if (!cfg.no_remote_wintitle) + set_title(osc_string); break; } } @@ -1172,7 +1190,8 @@ void term_out(void) curs.x--; wrapnext = FALSE; fix_cpos; - *cpos = (' ' | curr_attr | ATTR_ASCII); + if (!cfg.no_dbackspace) /* destructive bksp might be disabled */ + *cpos = (' ' | curr_attr | ATTR_ASCII); } else /* Or normal C0 controls. */ if ((c & -32) == 0 && termstate < DO_CTRLS) { @@ -1517,7 +1536,8 @@ void term_out(void) compatibility(VT100); power_on(); if (reset_132) { - request_resize(80, rows); + if (!cfg.no_remote_resize) + request_resize(80, rows); reset_132 = 0; } fix_cpos; @@ -1581,46 +1601,56 @@ void term_out(void) case ANSI('A', '('): compatibility(VT100); - cset_attr[0] = ATTR_GBCHR; + if (!cfg.no_remote_charset) + cset_attr[0] = ATTR_GBCHR; break; case ANSI('B', '('): compatibility(VT100); - cset_attr[0] = ATTR_ASCII; + if (!cfg.no_remote_charset) + cset_attr[0] = ATTR_ASCII; break; case ANSI('0', '('): compatibility(VT100); - cset_attr[0] = ATTR_LINEDRW; + if (!cfg.no_remote_charset) + cset_attr[0] = ATTR_LINEDRW; break; case ANSI('U', '('): compatibility(OTHER); - cset_attr[0] = ATTR_SCOACS; + if (!cfg.no_remote_charset) + cset_attr[0] = ATTR_SCOACS; break; case ANSI('A', ')'): compatibility(VT100); - cset_attr[1] = ATTR_GBCHR; + if (!cfg.no_remote_charset) + cset_attr[1] = ATTR_GBCHR; break; case ANSI('B', ')'): compatibility(VT100); - cset_attr[1] = ATTR_ASCII; + if (!cfg.no_remote_charset) + cset_attr[1] = ATTR_ASCII; break; case ANSI('0', ')'): compatibility(VT100); - cset_attr[1] = ATTR_LINEDRW; + if (!cfg.no_remote_charset) + cset_attr[1] = ATTR_LINEDRW; break; case ANSI('U', ')'): compatibility(OTHER); - cset_attr[1] = ATTR_SCOACS; + if (!cfg.no_remote_charset) + cset_attr[1] = ATTR_SCOACS; break; case ANSI('8', '%'): /* Old Linux code */ case ANSI('G', '%'): compatibility(OTHER); - utf = 1; + if (!cfg.no_remote_charset) + utf = 1; break; case ANSI('@', '%'): compatibility(OTHER); - utf = 0; + if (!cfg.no_remote_charset) + utf = 0; break; } break; @@ -1880,12 +1910,15 @@ void term_out(void) break; case 10: /* SCO acs off */ compatibility(SCOANSI); + if (cfg.no_remote_charset) break; sco_acs = 0; break; case 11: /* SCO acs on */ compatibility(SCOANSI); + if (cfg.no_remote_charset) break; sco_acs = 1; break; case 12: /* SCO acs on flipped */ compatibility(SCOANSI); + if (cfg.no_remote_charset) break; sco_acs = 2; break; case 22: /* disable bold */ compatibility2(OTHER, VT220); @@ -1962,7 +1995,8 @@ void term_out(void) if (esc_nargs <= 1 && (esc_args[0] < 1 || esc_args[0] >= 24)) { compatibility(VT340TEXT); - request_resize(cols, def(esc_args[0], 24)); + if (!cfg.no_remote_resize) + request_resize(cols, def(esc_args[0], 24)); deselect(); } else if (esc_nargs >= 1 && esc_args[0] >= 1 && @@ -2001,8 +2035,9 @@ void term_out(void) break; case 8: if (esc_nargs >= 3) { - request_resize(def(esc_args[2], cfg.width), - def(esc_args[1], cfg.height)); + if (!cfg.no_remote_resize) + request_resize(def(esc_args[2], cfg.width), + def(esc_args[1], cfg.height)); } break; case 9: @@ -2084,7 +2119,8 @@ void term_out(void) */ compatibility(VT420); if (esc_nargs == 1 && esc_args[0] > 0) { - request_resize(cols, def(esc_args[0], cfg.height)); + if (!cfg.no_remote_resize) + request_resize(cols, def(esc_args[0], cfg.height)); deselect(); } break; @@ -2095,7 +2131,8 @@ void term_out(void) */ compatibility(VT340TEXT); if (esc_nargs <= 1) { - request_resize(def(esc_args[0], cfg.width), rows); + if (!cfg.no_remote_resize) + request_resize(def(esc_args[0], cfg.width), rows); deselect(); } break; @@ -2222,10 +2259,12 @@ void term_out(void) * Well we should do a soft reset at this point ... */ if (!has_compat(VT420) && has_compat(VT100)) { - if (reset_132) - request_resize(132, 24); - else - request_resize(80, 24); + if (!cfg.no_remote_resize) { + if (reset_132) + request_resize(132, 24); + else + request_resize(80, 24); + } } #endif break; diff --git a/windlg.c b/windlg.c index 20d7fc27..a05ac077 100644 --- a/windlg.c +++ b/windlg.c @@ -296,8 +296,6 @@ enum { IDCX_ABOUT = IDC_KPNORMAL, IDC_KPAPPLIC, IDC_KPNH, - IDC_NOAPPLICK, - IDC_NOAPPLICC, IDC_CURSTATIC, IDC_CURNORMAL, IDC_CURAPPLIC, @@ -326,6 +324,18 @@ enum { IDCX_ABOUT = IDC_EDITNO, terminalpanelend, + featurespanelstart, + IDC_TITLE_FEATURES, + IDC_BOX_FEATURES1, + IDC_NOAPPLICK, + IDC_NOAPPLICC, + IDC_NORESIZE, + IDC_NOALTSCREEN, + IDC_NOWINTITLE, + IDC_NODBACKSPACE, + IDC_NOCHARSET, + featurespanelend, + bellpanelstart, IDC_TITLE_BELL, IDC_BOX_BELL1, @@ -662,9 +672,7 @@ char *help_context_cmd(int id) case IDC_KPSTATIC: case IDC_KPNORMAL: case IDC_KPAPPLIC: - case IDC_NOAPPLICK: return "JI(`',`keyboard.appkeypad')"; - case IDC_NOAPPLICC: case IDC_CURSTATIC: case IDC_CURNORMAL: case IDC_CURAPPLIC: @@ -676,6 +684,20 @@ char *help_context_cmd(int id) case IDC_CTRLALTKEYS: return "JI(`',`keyboard.ctrlalt')"; + case IDC_NOAPPLICK: + case IDC_NOAPPLICC: + return "JI(`',`features.application')"; + case IDC_NORESIZE: + return "JI(`',`features.resize')"; + case IDC_NOALTSCREEN: + return "JI(`',`features.altscreen')"; + case IDC_NOWINTITLE: + return "JI(`',`features.retitle')"; + case IDC_NODBACKSPACE: + return "JI(`',`features.dbackspace')"; + case IDC_NOCHARSET: + return "JI(`',`features.charset')"; + case IDC_WRAPMODE: return "JI(`',`terminal.autowrap')"; case IDC_DECOM: @@ -967,6 +989,11 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE); CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c); CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k); + CheckDlgButton(hwnd, IDC_NORESIZE, cfg.no_remote_resize); + CheckDlgButton(hwnd, IDC_NOALTSCREEN, cfg.no_alt_screen); + CheckDlgButton(hwnd, IDC_NOWINTITLE, cfg.no_remote_wintitle); + CheckDlgButton(hwnd, IDC_NODBACKSPACE, cfg.no_dbackspace); + CheckDlgButton(hwnd, IDC_NOCHARSET, cfg.no_remote_charset); CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC, cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL); CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH, @@ -1325,6 +1352,28 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) endbox(&cp); } + if (panel == featurespanelstart) { + /* The Features panel. Accelerators used: [acgoh] uksvatbr */ + struct ctlpos cp; + ctlposinit(&cp, hwnd, 80, 3, 13); + bartitle(&cp, "Enabling and disabling advanced terminal features ", + IDC_TITLE_FEATURES); + beginbox(&cp, NULL, IDC_BOX_FEATURES1); + checkbox(&cp, "Disable application c&ursor keys mode", IDC_NOAPPLICC); + checkbox(&cp, "Disable application &keypad mode", IDC_NOAPPLICK); + checkbox(&cp, "Disable remote-controlled terminal re&sizing", + IDC_NORESIZE); + checkbox(&cp, "Disable switching to &alternate terminal screen", + IDC_NOALTSCREEN); + checkbox(&cp, "Disable remote-controlled window &title changing", + IDC_NOWINTITLE); + checkbox(&cp, "Disable destructive &backspace on server sending ^?", + IDC_NODBACKSPACE); + checkbox(&cp, "Disable remote-controlled cha&racter set configuration", + IDC_NOCHARSET); + endbox(&cp); + } + if (panel == bellpanelstart) { /* The Bell panel. Accelerators used: [acgoh] bdsm wit */ struct ctlpos cp; @@ -1382,15 +1431,9 @@ static void create_controls(HWND hwnd, int dlgtype, int panel) "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL); endbox(&cp); beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2); - checkbox(&cp, - "Application c&ursor keys totally disabled", - IDC_NOAPPLICC); radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2, "Normal", IDC_CURNORMAL, "Application", IDC_CURAPPLIC, NULL); - checkbox(&cp, - "Application ke&ypad keys totally disabled", - IDC_NOAPPLICK); radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC, 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC, "NetHack", IDC_KPNH, NULL); @@ -1869,6 +1912,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, treeview_insert(&tvfaff, 0, "Terminal"); treeview_insert(&tvfaff, 1, "Keyboard"); treeview_insert(&tvfaff, 1, "Bell"); + treeview_insert(&tvfaff, 1, "Features"); treeview_insert(&tvfaff, 0, "Window"); treeview_insert(&tvfaff, 1, "Appearance"); treeview_insert(&tvfaff, 1, "Behaviour"); @@ -1948,6 +1992,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, create_controls(hwnd, dlgtype, terminalpanelstart); if (!strcmp(buffer, "Bell")) create_controls(hwnd, dlgtype, bellpanelstart); + if (!strcmp(buffer, "Features")) + create_controls(hwnd, dlgtype, featurespanelstart); if (!strcmp(buffer, "Window")) create_controls(hwnd, dlgtype, windowpanelstart); if (!strcmp(buffer, "Appearance")) @@ -2269,6 +2315,36 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, cfg.no_applic_k = IsDlgButtonChecked(hwnd, IDC_NOAPPLICK); break; + case IDC_NORESIZE: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.no_remote_resize = + IsDlgButtonChecked(hwnd, IDC_NORESIZE); + break; + case IDC_NOALTSCREEN: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.no_alt_screen = + IsDlgButtonChecked(hwnd, IDC_NOALTSCREEN); + break; + case IDC_NOWINTITLE: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.no_remote_wintitle = + IsDlgButtonChecked(hwnd, IDC_NOWINTITLE); + break; + case IDC_NODBACKSPACE: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.no_dbackspace = + IsDlgButtonChecked(hwnd, IDC_NODBACKSPACE); + break; + case IDC_NOCHARSET: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) + cfg.no_remote_charset = + IsDlgButtonChecked(hwnd, IDC_NOCHARSET); + break; case IDC_ALTF4: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) diff --git a/window.c b/window.c index a779dbc7..a0e3b03f 100644 --- a/window.c +++ b/window.c @@ -1684,6 +1684,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, cfgtopalette(); init_palette(); + /* Give terminal a heads-up on miscellaneous stuff */ + term_reconfig(); + /* Screen size changed ? */ if (cfg.height != prev_cfg.height || cfg.width != prev_cfg.width || -- 2.11.0