vt: emulate 8- and 24-bit colour codes.
Most other mainstream terminals support "xterm256" colours, which means people sometimes use these blindly without checking capabilities. Because of hardware limitations of VGA consoles, colours are downgraded to 16 foregrounds and 8 backgrounds. On fbdev consoles it would be possible to support them without quality loss, but adding that would require quite a large amount of code. Signed-off-by: Adam Borowski <kilobyte@angband.pl> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7fa21dd8bd
commit
cec5b2a97a
@ -1231,6 +1231,52 @@ static void default_attr(struct vc_data *vc)
|
|||||||
vc->vc_color = vc->vc_def_color;
|
vc->vc_color = vc->vc_def_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rgb { u8 r; u8 g; u8 b; };
|
||||||
|
|
||||||
|
struct rgb rgb_from_256(int i)
|
||||||
|
{
|
||||||
|
struct rgb c;
|
||||||
|
if (i < 8) { /* Standard colours. */
|
||||||
|
c.r = i&1 ? 0xaa : 0x00;
|
||||||
|
c.g = i&2 ? 0xaa : 0x00;
|
||||||
|
c.b = i&4 ? 0xaa : 0x00;
|
||||||
|
} else if (i < 16) {
|
||||||
|
c.r = i&1 ? 0xff : 0x55;
|
||||||
|
c.g = i&2 ? 0xff : 0x55;
|
||||||
|
c.b = i&4 ? 0xff : 0x55;
|
||||||
|
} else if (i < 232) { /* 6x6x6 colour cube. */
|
||||||
|
c.r = (i - 16) / 36 * 85 / 2;
|
||||||
|
c.g = (i - 16) / 6 % 6 * 85 / 2;
|
||||||
|
c.b = (i - 16) % 6 * 85 / 2;
|
||||||
|
} else /* Grayscale ramp. */
|
||||||
|
c.r = c.g = c.b = i * 10 - 2312;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rgb_foreground(struct vc_data *vc, struct rgb c)
|
||||||
|
{
|
||||||
|
u8 hue, max = c.r;
|
||||||
|
if (c.g > max)
|
||||||
|
max = c.g;
|
||||||
|
if (c.b > max)
|
||||||
|
max = c.b;
|
||||||
|
hue = (c.r > max/2 ? 4 : 0)
|
||||||
|
| (c.g > max/2 ? 2 : 0)
|
||||||
|
| (c.b > max/2 ? 1 : 0);
|
||||||
|
if (hue == 7 && max <= 0x55)
|
||||||
|
hue = 0, vc->vc_intensity = 2;
|
||||||
|
else
|
||||||
|
vc->vc_intensity = (max > 0xaa) + 1;
|
||||||
|
vc->vc_color = (vc->vc_color & 0xf0) | hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rgb_background(struct vc_data *vc, struct rgb c)
|
||||||
|
{
|
||||||
|
/* For backgrounds, err on the dark side. */
|
||||||
|
vc->vc_color = (vc->vc_color & 0x0f)
|
||||||
|
| (c.r&0x80) >> 1 | (c.g&0x80) >> 2 | (c.b&0x80) >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
/* console_lock is held */
|
/* console_lock is held */
|
||||||
static void csi_m(struct vc_data *vc)
|
static void csi_m(struct vc_data *vc)
|
||||||
{
|
{
|
||||||
@ -1302,8 +1348,7 @@ static void csi_m(struct vc_data *vc)
|
|||||||
case 27:
|
case 27:
|
||||||
vc->vc_reverse = 0;
|
vc->vc_reverse = 0;
|
||||||
break;
|
break;
|
||||||
case 38:
|
case 38: /* ITU T.416
|
||||||
case 48: /* ITU T.416
|
|
||||||
* Higher colour modes.
|
* Higher colour modes.
|
||||||
* They break the usual properties of SGR codes
|
* They break the usual properties of SGR codes
|
||||||
* and thus need to be detected and ignored by
|
* and thus need to be detected and ignored by
|
||||||
@ -1315,15 +1360,41 @@ static void csi_m(struct vc_data *vc)
|
|||||||
i++;
|
i++;
|
||||||
if (i > vc->vc_npar)
|
if (i > vc->vc_npar)
|
||||||
break;
|
break;
|
||||||
if (vc->vc_par[i] == 5) /* 256 colours */
|
if (vc->vc_par[i] == 5 && /* 256 colours */
|
||||||
i++; /* ubiquitous */
|
i < vc->vc_npar) { /* ubiquitous */
|
||||||
else if (vc->vc_par[i] == 2) /* 24 bit colours */
|
i++;
|
||||||
i += 3; /* extremely rare */
|
rgb_foreground(vc,
|
||||||
|
rgb_from_256(vc->vc_par[i]));
|
||||||
|
} else if (vc->vc_par[i] == 2 && /* 24 bit */
|
||||||
|
i <= vc->vc_npar + 3) {/* extremely rare */
|
||||||
|
struct rgb c = {r:vc->vc_par[i+1],
|
||||||
|
g:vc->vc_par[i+2],
|
||||||
|
b:vc->vc_par[i+3]};
|
||||||
|
rgb_foreground(vc, c);
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
/* Subcommands 3 (CMY) and 4 (CMYK) are so insane
|
/* Subcommands 3 (CMY) and 4 (CMYK) are so insane
|
||||||
* that detecting them is not worth the few extra
|
* there's no point in supporting them.
|
||||||
* bytes of kernel's size.
|
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
case 48:
|
||||||
|
i++;
|
||||||
|
if (i > vc->vc_npar)
|
||||||
|
break;
|
||||||
|
if (vc->vc_par[i] == 5 && /* 256 colours */
|
||||||
|
i < vc->vc_npar) {
|
||||||
|
i++;
|
||||||
|
rgb_background(vc,
|
||||||
|
rgb_from_256(vc->vc_par[i]));
|
||||||
|
} else if (vc->vc_par[i] == 2 && /* 24 bit */
|
||||||
|
i <= vc->vc_npar + 3) {
|
||||||
|
struct rgb c = {r:vc->vc_par[i+1],
|
||||||
|
g:vc->vc_par[i+2],
|
||||||
|
b:vc->vc_par[i+3]};
|
||||||
|
rgb_background(vc, c);
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 39:
|
case 39:
|
||||||
vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
|
vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user