1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Rework handling of the SRM escape sequence.

This sequence (ESC[12l, ESC[12h) enables and disables local echo in
the terminal. We were previously implementing it by gatewaying it
directly through to the local echo facility in the line discipline,
which in turn would pass it on to the terminal it was running in (if
it was Plink).

This seems to be at odds with how other terminals do it: they treat
SRM as its own entirely separate thing, in which the terminal
_emulator_ performs its own echoing of input keypress data,
independently of whether the Unix terminal device (or closest
equivalent) is doing the same thing or not.

Now we're doing it the same way as everyone else (or at least I think
so): the new internal terminal function that the term_keyinput pair
feed to is also implementing SRM-driven local echo as another of its
side effects. One observable effect is that SRM now doesn't interfere
with the termios settings of the terminal it's running in; another is
that the echo now only applies to real keypress data, and not
sequences auto-generated by the terminal.
This commit is contained in:
Simon Tatham 2019-06-17 20:21:06 +01:00
parent 71e42b04a5
commit 9fccb065a6
2 changed files with 54 additions and 19 deletions

View File

@ -1341,7 +1341,7 @@ static void power_on(Terminal *term, bool clear)
term->alt_save_attr = term->curr_attr = ATTR_DEFAULT;
term->curr_truecolour.fg = term->curr_truecolour.bg = optionalrgb_none;
term->save_truecolour = term->alt_save_truecolour = term->curr_truecolour;
term->term_editing = term->term_echoing = false;
term->term_editing = false;
term->app_cursor_keys = conf_get_bool(term->conf, CONF_app_cursor);
term->app_keypad_keys = conf_get_bool(term->conf, CONF_app_keypad);
term->use_bce = conf_get_bool(term->conf, CONF_bce);
@ -1354,6 +1354,7 @@ static void power_on(Terminal *term, bool clear)
term->urxvt_extended_mouse = false;
win_set_raw_mouse_mode(term->win, false);
term->bracketed_paste = false;
term->srm_echo = false;
{
int i;
for (i = 0; i < 256; i++)
@ -1755,6 +1756,8 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win)
term->trusted = true;
term->bracketed_paste_active = false;
return term;
}
@ -2702,9 +2705,7 @@ static void toggle_mode(Terminal *term, int mode, int query, bool state)
term->insert = state;
break;
case 12: /* SRM: set echo mode */
term->term_echoing = !state;
if (term->ldisc) /* cause ldisc to notice changes */
ldisc_echoedit_update(term->ldisc);
term->srm_echo = !state;
break;
case 20: /* LNM: Return sends ... */
term->cr_lf_return = state;
@ -3026,9 +3027,49 @@ static strbuf *term_input_data_from_charset(
return buf;
}
static inline void term_bracketed_paste_start(Terminal *term)
{
ptrlen seq = PTRLEN_LITERAL("\033[200~");
if (term->ldisc)
ldisc_send(term->ldisc, seq.ptr, seq.len, false);
term->bracketed_paste_active = true;
}
static inline void term_bracketed_paste_stop(Terminal *term)
{
if (!term->bracketed_paste_active)
return;
ptrlen seq = PTRLEN_LITERAL("\033[201~");
if (term->ldisc)
ldisc_send(term->ldisc, seq.ptr, seq.len, false);
term->bracketed_paste_active = false;
}
static inline void term_keyinput_internal(
Terminal *term, const void *buf, int len, bool interactive)
{
if (term->srm_echo) {
/*
* Implement the terminal-level local echo behaviour that
* ECMA-48 specifies when terminal mode 12 is configured off
* (ESC[12l). In this mode, data input to the terminal via the
* keyboard is also added to the output buffer. But this
* doesn't apply to escape sequences generated as session
* input _within_ the terminal, e.g. in response to terminal
* query sequences, or the bracketing sequences of bracketed
* paste mode. Those will be sent directly via
* ldisc_send(term->ldisc, ...) and won't go through this
* function.
*/
/* Mimic the special case of negative length in ldisc_send */
int true_len = len >= 0 ? len : strlen(buf);
bufchain_add(&term->inbuf, buf, true_len);
term_added_data(term);
}
term_bracketed_paste_stop(term);
if (term->ldisc)
ldisc_send(term->ldisc, buf, len, interactive);
term_seen_key_event(term);
@ -6326,6 +6367,7 @@ static void term_paste_callback(void *vterm)
return;
}
}
term_bracketed_paste_stop(term);
sfree(term->paste_buffer);
term->paste_buffer = NULL;
term->paste_len = 0;
@ -6361,10 +6403,8 @@ void term_do_paste(Terminal *term, const wchar_t *data, int len)
term->paste_pos = term->paste_len = 0;
term->paste_buffer = snewn(len + 12, wchar_t);
if (term->bracketed_paste) {
memcpy(term->paste_buffer, L"\033[200~", 6 * sizeof(wchar_t));
term->paste_len += 6;
}
if (term->bracketed_paste)
term_bracketed_paste_start(term);
p = data;
while (p < data + len) {
@ -6413,12 +6453,6 @@ void term_do_paste(Terminal *term, const wchar_t *data, int len)
term->paste_buffer[term->paste_len++] = wc;
}
if (term->bracketed_paste) {
memcpy(term->paste_buffer + term->paste_len,
L"\033[201~", 6 * sizeof(wchar_t));
term->paste_len += 6;
}
/* Assume a small paste will be OK in one go. */
if (term->paste_len < 256) {
if (term->ldisc) {
@ -6429,7 +6463,8 @@ void term_do_paste(Terminal *term, const wchar_t *data, int len)
}
if (term->paste_buffer)
sfree(term->paste_buffer);
term->paste_buffer = 0;
term_bracketed_paste_stop(term);
term->paste_buffer = NULL;
term->paste_pos = term->paste_len = 0;
}
@ -6961,6 +6996,7 @@ void term_nopaste(Terminal *term)
if (term->paste_len == 0)
return;
sfree(term->paste_buffer);
term_bracketed_paste_stop(term);
term->paste_buffer = NULL;
term->paste_len = 0;
}
@ -6992,7 +7028,7 @@ void term_lost_clipboard_ownership(Terminal *term, int clipboard)
bool term_ldisc(Terminal *term, int option)
{
if (option == LD_ECHO)
return term->term_echoing;
return false;
if (option == LD_EDIT)
return term->term_editing;
return false;

View File

@ -123,7 +123,6 @@ struct terminal_tag {
bool cblinker; /* When blinking is the cursor on ? */
bool tblinker; /* When the blinking text is on */
bool blink_is_real; /* Actually blink blinking text */
bool term_echoing; /* Does terminal want local echo? */
bool term_editing; /* Does terminal want local edit? */
int sco_acs, save_sco_acs; /* CSI 10,11,12m -> OEM charset */
bool vt52_bold; /* Force bold on non-bold colours */
@ -148,7 +147,7 @@ struct terminal_tag {
bool in_vbell;
long vbell_end;
bool app_cursor_keys, app_keypad_keys, vt52_mode;
bool repeat_off, cr_lf_return;
bool repeat_off, srm_echo, cr_lf_return;
bool seen_disp_event;
bool big_cursor;
@ -157,7 +156,7 @@ struct terminal_tag {
bool urxvt_extended_mouse;
int mouse_is_down; /* used while tracking mouse buttons */
bool bracketed_paste;
bool bracketed_paste, bracketed_paste_active;
int cset_attr[2];