dm: video: Add color ANSI escape sequence support

Note that this doesn't differentiate (due to lack of information in
video_priv) between different possible component orders for 32bpp.
But the main user at this point is efi_loader, and GOP expects xBGR
so any video drivers that this is incorrect for already have problems.
(Also, conveniently, this matches what simple-framebuffer bindings
expect for kernels that use the simple-framebuffer DT binding to
take over the bootloader display.)

Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Rob Clark 2017-09-13 18:12:22 -04:00 committed by Anatolij Gustschin
parent a085aa1f27
commit 703d885c22

View file

@ -108,6 +108,41 @@ static void vidconsole_newline(struct udevice *dev)
video_sync(dev->parent);
}
static const struct {
unsigned r;
unsigned g;
unsigned b;
} colors[] = {
{ 0x00, 0x00, 0x00 }, /* black */
{ 0xff, 0x00, 0x00 }, /* red */
{ 0x00, 0xff, 0x00 }, /* green */
{ 0xff, 0xff, 0x00 }, /* yellow */
{ 0x00, 0x00, 0xff }, /* blue */
{ 0xff, 0x00, 0xff }, /* magenta */
{ 0x00, 0xff, 0xff }, /* cyan */
{ 0xff, 0xff, 0xff }, /* white */
};
static void set_color(struct video_priv *priv, unsigned idx, unsigned *c)
{
switch (priv->bpix) {
case VIDEO_BPP16:
*c = ((colors[idx].r >> 3) << 0) |
((colors[idx].g >> 2) << 5) |
((colors[idx].b >> 3) << 11);
break;
case VIDEO_BPP32:
*c = 0xff000000 |
(colors[idx].r << 0) |
(colors[idx].g << 8) |
(colors[idx].b << 16);
break;
default:
/* unsupported, leave current color in place */
break;
}
}
static char *parsenum(char *s, int *num)
{
char *end;
@ -194,6 +229,65 @@ static void vidconsole_escape_char(struct udevice *dev, char ch)
}
break;
}
case 'm': {
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
char *s = priv->escape_buf;
char *end = &priv->escape_buf[priv->escape_len];
/*
* Set graphics mode: [%d;...;%dm
*
* Currently only supports the color attributes:
*
* Foreground Colors:
*
* 30 Black
* 31 Red
* 32 Green
* 33 Yellow
* 34 Blue
* 35 Magenta
* 36 Cyan
* 37 White
*
* Background Colors:
*
* 40 Black
* 41 Red
* 42 Green
* 43 Yellow
* 44 Blue
* 45 Magenta
* 46 Cyan
* 47 White
*/
s++; /* [ */
while (s < end) {
int val;
s = parsenum(s, &val);
s++;
switch (val) {
case 30 ... 37:
/* fg color */
set_color(vid_priv, val - 30,
(unsigned *)&vid_priv->colour_fg);
break;
case 40 ... 47:
/* bg color */
set_color(vid_priv, val - 40,
(unsigned *)&vid_priv->colour_bg);
break;
default:
/* unknown/unsupported */
break;
}
}
break;
}
default:
debug("unrecognized escape sequence: %*s\n",
priv->escape_len, priv->escape_buf);