Three changes to fix problems with xterm in VT340 mode, reported by Thomas

Sattler.

1) Do not include the DECSLRM or DECFRA features for xterm; they will be added
   instead if secondary DA responds as VT420 (this happens already).

2) Set or reset the individual flags after terminal-overrides is applied, so
   the user can properly disable them.

3) Add a capability for DECFRA ("Rect").
This commit is contained in:
Nicholas Marriott 2021-04-22 09:01:22 +01:00
parent cd6af4a52e
commit 7a6446ac17
4 changed files with 80 additions and 36 deletions

4
tmux.1
View File

@ -6049,6 +6049,10 @@ Disable and enable focus reporting.
These are set automatically if the These are set automatically if the
.Em XT .Em XT
capability is present. capability is present.
.It Em \&Rect
Tell
.Nm
that the terminal supports rectangle operations.
.It Em \&Smol .It Em \&Smol
Enable the overline attribute. Enable the overline attribute.
.It Em \&Smulx .It Em \&Smulx

1
tmux.h
View File

@ -452,6 +452,7 @@ enum tty_code_code {
TTYC_MS, TTYC_MS,
TTYC_OL, TTYC_OL,
TTYC_OP, TTYC_OP,
TTYC_RECT,
TTYC_REV, TTYC_REV,
TTYC_RGB, TTYC_RGB,
TTYC_RI, TTYC_RI,

View File

@ -218,9 +218,13 @@ static const struct tty_feature tty_feature_margins = {
}; };
/* Terminal supports DECFRA rectangle fill. */ /* Terminal supports DECFRA rectangle fill. */
static const char *tty_feature_rectfill_capabilities[] = {
"Rect",
NULL
};
static const struct tty_feature tty_feature_rectfill = { static const struct tty_feature tty_feature_rectfill = {
"rectfill", "rectfill",
NULL, tty_feature_rectfill_capabilities,
TERM_DECFRA TERM_DECFRA
}; };
@ -351,8 +355,13 @@ tty_default_features(int *feat, const char *name, u_int version)
",cstyle,extkeys,margins,sync" ",cstyle,extkeys,margins,sync"
}, },
{ .name = "XTerm", { .name = "XTerm",
/*
* xterm also supports DECSLRM and DECFRA, but they can be
* disabled so not set it here - they will be added if
* secondary DA shows VT420.
*/
.features = TTY_FEATURES_BASE_MODERN_XTERM .features = TTY_FEATURES_BASE_MODERN_XTERM
",ccolour,cstyle,extkeys,focus,margins,rectfill" ",ccolour,cstyle,extkeys,focus"
} }
}; };
u_int i; u_int i;

View File

@ -251,6 +251,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_MS] = { TTYCODE_STRING, "Ms" }, [TTYC_MS] = { TTYCODE_STRING, "Ms" },
[TTYC_OL] = { TTYCODE_STRING, "ol" }, [TTYC_OL] = { TTYCODE_STRING, "ol" },
[TTYC_OP] = { TTYCODE_STRING, "op" }, [TTYC_OP] = { TTYCODE_STRING, "op" },
[TTYC_RECT] = { TTYCODE_STRING, "Rect" },
[TTYC_REV] = { TTYCODE_STRING, "rev" }, [TTYC_REV] = { TTYCODE_STRING, "rev" },
[TTYC_RGB] = { TTYCODE_FLAG, "RGB" }, [TTYC_RGB] = { TTYCODE_FLAG, "RGB" },
[TTYC_RIN] = { TTYCODE_STRING, "rin" }, [TTYC_RIN] = { TTYCODE_STRING, "rin" },
@ -434,10 +435,11 @@ tty_term_apply_overrides(struct tty_term *term)
struct options_entry *o; struct options_entry *o;
struct options_array_item *a; struct options_array_item *a;
union options_value *ov; union options_value *ov;
const char *s; const char *s, *acs;
size_t offset; size_t offset;
char *first; char *first;
/* Update capabilities from the option. */
o = options_get_only(global_options, "terminal-overrides"); o = options_get_only(global_options, "terminal-overrides");
a = options_array_first(o); a = options_array_first(o);
while (a != NULL) { while (a != NULL) {
@ -450,6 +452,64 @@ tty_term_apply_overrides(struct tty_term *term)
tty_term_apply(term, s + offset, 0); tty_term_apply(term, s + offset, 0);
a = options_array_next(a); a = options_array_next(a);
} }
/* Update the RGB flag if the terminal has RGB colours. */
if (tty_term_has(term, TTYC_SETRGBF) &&
tty_term_has(term, TTYC_SETRGBB))
term->flags |= TERM_RGBCOLOURS;
else
term->flags &= ~TERM_RGBCOLOURS;
log_debug("RGBCOLOURS flag is %d", !!(term->flags & TERM_RGBCOLOURS));
/*
* Set or clear the DECSLRM flag if the terminal has the margin
* capabilities.
*/
if (tty_term_has(term, TTYC_CMG) && tty_term_has(term, TTYC_CLMG))
term->flags |= TERM_DECSLRM;
else
term->flags &= ~TERM_DECSLRM;
log_debug("DECSLRM flag is %d", !!(term->flags & TERM_DECSLRM));
/*
* Set or clear the DECFRA flag if the terminal has the rectangle
* capability.
*/
if (tty_term_has(term, TTYC_RECT))
term->flags |= TERM_DECFRA;
else
term->flags &= ~TERM_DECFRA;
log_debug("DECFRA flag is %d", !!(term->flags & TERM_DECFRA));
/*
* Terminals without am (auto right margin) wrap at at $COLUMNS - 1
* rather than $COLUMNS (the cursor can never be beyond $COLUMNS - 1).
*
* Terminals without xenl (eat newline glitch) ignore a newline beyond
* the right edge of the terminal, but tmux doesn't care about this -
* it always uses absolute only moves the cursor with a newline when
* also sending a linefeed.
*
* This is irritating, most notably because it is painful to write to
* the very bottom-right of the screen without scrolling.
*
* Flag the terminal here and apply some workarounds in other places to
* do the best possible.
*/
if (!tty_term_flag(term, TTYC_AM))
term->flags |= TERM_NOAM;
else
term->flags &= ~TERM_NOAM;
log_debug("NOAM flag is %d", !!(term->flags & TERM_NOAM));
/* Generate ACS table. If none is present, use nearest ASCII. */
memset(term->acs, 0, sizeof term->acs);
if (tty_term_has(term, TTYC_ACSC))
acs = tty_term_string(term, TTYC_ACSC);
else
acs = "a#j+k+l+m+n+o-p-q-r-s-t+u+v+w+x|y<z>~.";
for (; acs[0] != '\0' && acs[1] != '\0'; acs += 2)
term->acs[(u_char) acs[0]][0] = acs[1];
} }
struct tty_term * struct tty_term *
@ -463,7 +523,7 @@ tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
struct options_array_item *a; struct options_array_item *a;
union options_value *ov; union options_value *ov;
u_int i, j; u_int i, j;
const char *s, *acs, *value; const char *s, *value;
size_t offset, namelen; size_t offset, namelen;
char *first; char *first;
@ -566,40 +626,10 @@ tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
(!tty_term_has(term, TTYC_SETRGBF) || (!tty_term_has(term, TTYC_SETRGBF) ||
!tty_term_has(term, TTYC_SETRGBB))) !tty_term_has(term, TTYC_SETRGBB)))
tty_add_features(feat, "RGB", ","); tty_add_features(feat, "RGB", ",");
if (tty_term_has(term, TTYC_SETRGBF) &&
tty_term_has(term, TTYC_SETRGBB))
term->flags |= TERM_RGBCOLOURS;
/* Apply the features and overrides again. */ /* Apply the features and overrides again. */
tty_apply_features(term, *feat); if (tty_apply_features(term, *feat))
tty_term_apply_overrides(term); tty_term_apply_overrides(term);
/*
* Terminals without am (auto right margin) wrap at at $COLUMNS - 1
* rather than $COLUMNS (the cursor can never be beyond $COLUMNS - 1).
*
* Terminals without xenl (eat newline glitch) ignore a newline beyond
* the right edge of the terminal, but tmux doesn't care about this -
* it always uses absolute only moves the cursor with a newline when
* also sending a linefeed.
*
* This is irritating, most notably because it is painful to write to
* the very bottom-right of the screen without scrolling.
*
* Flag the terminal here and apply some workarounds in other places to
* do the best possible.
*/
if (!tty_term_flag(term, TTYC_AM))
term->flags |= TERM_NOAM;
/* Generate ACS table. If none is present, use nearest ASCII. */
memset(term->acs, 0, sizeof term->acs);
if (tty_term_has(term, TTYC_ACSC))
acs = tty_term_string(term, TTYC_ACSC);
else
acs = "a#j+k+l+m+n+o-p-q-r-s-t+u+v+w+x|y<z>~.";
for (; acs[0] != '\0' && acs[1] != '\0'; acs += 2)
term->acs[(u_char) acs[0]][0] = acs[1];
/* Log the capabilities. */ /* Log the capabilities. */
for (i = 0; i < tty_term_ncodes(); i++) for (i = 0; i < tty_term_ncodes(); i++)