Skip to content

Commit fa4268c

Browse files
rpigottgregkh
authored andcommitted
vt: support ITU-T T.416 color subparameters
The colon ("bit combination 03/10") is a valid character in parameter substrings. ECMA-48 says: Each parameter sub-string consists of one or more bit combinations from 03/00 to 03/10; the bit combinations from 03/00 to 03/09 represent the digits ZERO to NINE; bit combination 03/10 may be used as a separator in a parameter sub-string, for example, to separate the fractional part of a decimal number from the integer part of that number. To my knowledge, the only codes where 03/10 is actually used as a separator are the CSI-m SGR sequences. The colon separated format is superior as an embedded string for software that doesn't wish to link ncurses terminal database, because terminals that do not support the requested SGR sequence can safely skip the sub-parameters rather than misinterpret them as another sequence. Hence, some software have started using this "modern" format [1]. We should support the colon separated format as well. [1] systemd/systemd@6eabe9f Signed-off-by: Ronan Pigott <ronan@rjp.ie> Link: https://patch.msgid.link/20260303010701.631022-1-ronan@rjp.ie Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 0b1837c commit fa4268c

1 file changed

Lines changed: 45 additions & 3 deletions

File tree

drivers/tty/vt/vt.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,9 +1644,7 @@ static void rgb_background(struct vc_data *vc, const struct rgb *c)
16441644

16451645
/*
16461646
* ITU T.416 Higher colour modes. They break the usual properties of SGR codes
1647-
* and thus need to be detected and ignored by hand. That standard also
1648-
* wants : rather than ; as separators but sequences containing : are currently
1649-
* completely ignored by the parser.
1647+
* and thus need to be detected and ignored by hand.
16501648
*
16511649
* Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in
16521650
* supporting them.
@@ -1703,6 +1701,7 @@ enum {
17031701
CSI_m_BG_COLOR_END = 47,
17041702
CSI_m_BG_COLOR = 48,
17051703
CSI_m_DEFAULT_BG_COLOR = 49,
1704+
CSI_m_UNDERLINE_COLOR = 58,
17061705
CSI_m_BRIGHT_FG_COLOR_BEG = 90,
17071706
CSI_m_BRIGHT_FG_COLOR_END = 97,
17081707
CSI_m_BRIGHT_FG_COLOR_OFF = CSI_m_BRIGHT_FG_COLOR_BEG - CSI_m_FG_COLOR_BEG,
@@ -2160,6 +2159,7 @@ static void restore_cur(struct vc_data *vc)
21602159
* @ESesc: ESC parsed
21612160
* @ESsquare: CSI parsed -- modifiers/parameters/ctrl chars expected
21622161
* @ESgetpars: CSI parsed -- parameters/ctrl chars expected
2162+
* @ESgetsubpars: CSI m parsed -- subparameters expected
21632163
* @ESfunckey: CSI [ parsed
21642164
* @EShash: ESC # parsed
21652165
* @ESsetG0: ESC ( parsed
@@ -2180,6 +2180,7 @@ enum vc_ctl_state {
21802180
ESesc,
21812181
ESsquare,
21822182
ESgetpars,
2183+
ESgetsubpars,
21832184
ESfunckey,
21842185
EShash,
21852186
ESsetG0,
@@ -2699,6 +2700,47 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
26992700
fallthrough;
27002701
case ESgetpars: /* ESC [ aka CSI, parameters expected */
27012702
switch (c) {
2703+
case ':': /* ITU-T T.416 color subparameters */
2704+
if (vc->vc_par[vc->vc_npar] == CSI_m_FG_COLOR ||
2705+
vc->vc_par[vc->vc_npar] == CSI_m_BG_COLOR ||
2706+
vc->vc_par[vc->vc_npar] == CSI_m_UNDERLINE_COLOR)
2707+
vc->vc_state = ESgetsubpars;
2708+
else
2709+
break;
2710+
fallthrough;
2711+
case ';':
2712+
if (vc->vc_npar < NPAR - 1) {
2713+
vc->vc_npar++;
2714+
return;
2715+
}
2716+
break;
2717+
case '0' ... '9':
2718+
vc->vc_par[vc->vc_npar] *= 10;
2719+
vc->vc_par[vc->vc_npar] += c - '0';
2720+
return;
2721+
}
2722+
if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST) {
2723+
vc->vc_state = EScsiignore;
2724+
return;
2725+
}
2726+
2727+
/* parameters done, handle the control char @c */
2728+
2729+
vc->vc_state = ESnormal;
2730+
2731+
switch (vc->vc_priv) {
2732+
case EPdec:
2733+
csi_DEC(tty, vc, c);
2734+
return;
2735+
case EPecma:
2736+
csi_ECMA(tty, vc, c);
2737+
return;
2738+
default:
2739+
return;
2740+
}
2741+
case ESgetsubpars: /* ESC [ 38/48/58, subparameters expected */
2742+
switch (c) {
2743+
case ':':
27022744
case ';':
27032745
if (vc->vc_npar < NPAR - 1) {
27042746
vc->vc_npar++;

0 commit comments

Comments
 (0)