[U-Boot] [PATCH 1/1] dm: video: Correct color ANSI escape sequence support

Support increased intensity (bold). Get RGB sequence in pixels right (swap blue and red). Do not set reserved bits. Use u32 instead of unsigned for color bit mask.
qemu-system-i386 -display sdl -vga virtio and qemu-system-i386 -display sdl -vga cirrus now display the same colors as qemu-system-i386 -nographic
Testing is possible via
setenv efi_selftest test output bootefi selftest
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de --- drivers/video/vidconsole-uclass.c | 53 ++++++++++++++++++++++++++------------- drivers/video/video-uclass.c | 38 +++++++++++++++++++++++++--- include/video.h | 6 +++-- 3 files changed, 74 insertions(+), 23 deletions(-)
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 5f63c12d6c..79c7f2113f 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -114,28 +114,35 @@ static const struct { unsigned b; } colors[] = { { 0x00, 0x00, 0x00 }, /* black */ - { 0xff, 0x00, 0x00 }, /* red */ - { 0x00, 0xff, 0x00 }, /* green */ + { 0xc0, 0x00, 0x00 }, /* red */ + { 0x00, 0xc0, 0x00 }, /* green */ + { 0xc0, 0x60, 0x00 }, /* brown */ + { 0x00, 0x00, 0xc0 }, /* blue */ + { 0xc0, 0x00, 0xc0 }, /* magenta */ + { 0x00, 0xc0, 0xc0 }, /* cyan */ + { 0xc0, 0xc0, 0xc0 }, /* light gray */ + { 0x80, 0x80, 0x80 }, /* gray */ + { 0xff, 0x00, 0x00 }, /* bright red */ + { 0x00, 0xff, 0x00 }, /* bright green */ { 0xff, 0xff, 0x00 }, /* yellow */ - { 0x00, 0x00, 0xff }, /* blue */ - { 0xff, 0x00, 0xff }, /* magenta */ - { 0x00, 0xff, 0xff }, /* cyan */ + { 0x00, 0x00, 0xff }, /* bright blue */ + { 0xff, 0x00, 0xff }, /* bright magenta */ + { 0x00, 0xff, 0xff }, /* bright cyan */ { 0xff, 0xff, 0xff }, /* white */ };
-static void set_color(struct video_priv *priv, unsigned idx, unsigned *c) +static void set_color(struct video_priv *priv, unsigned int idx, u32 *c) { switch (priv->bpix) { case VIDEO_BPP16: - *c = ((colors[idx].r >> 3) << 0) | - ((colors[idx].g >> 2) << 5) | - ((colors[idx].b >> 3) << 11); + *c = ((colors[idx].r >> 3) << 11) | + ((colors[idx].g >> 2) << 5) | + ((colors[idx].b >> 3) << 0); break; case VIDEO_BPP32: - *c = 0xff000000 | - (colors[idx].r << 0) | - (colors[idx].g << 8) | - (colors[idx].b << 16); + *c = (colors[idx].r << 16) | + (colors[idx].g << 8) | + (colors[idx].b << 0); break; default: /* unsupported, leave current color in place */ @@ -270,18 +277,30 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) s++;
switch (val) { + case 0: + /* all attributes off */ + vid_priv->fg &= 7; + break; + case 1: + /* bold */ + vid_priv->fg |= 8; + set_color(vid_priv, vid_priv->fg, + (unsigned int *)&vid_priv->colour_fg); + break; case 30 ... 37: /* fg color */ - set_color(vid_priv, val - 30, - (unsigned *)&vid_priv->colour_fg); + vid_priv->fg &= ~7; + vid_priv->fg |= val - 30; + set_color(vid_priv, vid_priv->fg, + &vid_priv->colour_fg); break; case 40 ... 47: /* bg color */ set_color(vid_priv, val - 40, - (unsigned *)&vid_priv->colour_bg); + &vid_priv->colour_bg); break; default: - /* unknown/unsupported */ + /* ignore unsupported SGR parameter */ break; } } diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index dcaceed42c..8dfb6b1902 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -91,14 +91,26 @@ void video_clear(struct udevice *dev) { struct video_priv *priv = dev_get_uclass_priv(dev);
- if (priv->bpix == VIDEO_BPP32) { + switch (priv->bpix) { + case VIDEO_BPP16: { + u16 *ppix = priv->fb; + u16 *end = priv->fb + priv->fb_size; + + while (ppix < end) + *ppix++ = priv->colour_bg; + break; + } + case VIDEO_BPP32: { u32 *ppix = priv->fb; u32 *end = priv->fb + priv->fb_size;
while (ppix < end) *ppix++ = priv->colour_bg; - } else { + break; + } + default: memset(priv->fb, priv->colour_bg, priv->fb_size); + break; } }
@@ -193,9 +205,27 @@ static int video_post_probe(struct udevice *dev)
/* Set up colours - we could in future support other colours */ #ifdef CONFIG_SYS_WHITE_ON_BLACK - priv->colour_fg = 0xffffff; + switch (priv->bpix) { + case VIDEO_BPP16: + priv->colour_fg = 0xc618; + break; + case VIDEO_BPP32: + priv->colour_fg = 0xc0c0c0; + break; + default: + priv->colour_fg = 0xffffff; + break; + } + priv->fg = 7; #else - priv->colour_bg = 0xffffff; + switch (priv->bpix) { + case VIDEO_BPP16: + priv->colour_bg = 0xcffff; + break; + default: + priv->colour_bg = 0xffffff; + break; + } #endif
if (!CONFIG_IS_ENABLED(NO_FB_CLEAR)) diff --git a/include/video.h b/include/video.h index 61ff653121..c02e0315a7 100644 --- a/include/video.h +++ b/include/video.h @@ -67,6 +67,7 @@ enum video_log2_bpp { * @flush_dcache: true to enable flushing of the data cache after * the LCD is updated * @cmap: Colour map for 8-bit-per-pixel displays + * @fg: Foreground color code (bit 3 = bold, bit 0-2 = color) */ struct video_priv { /* Things set up by the driver: */ @@ -84,10 +85,11 @@ struct video_priv { void *fb; int fb_size; int line_length; - int colour_fg; - int colour_bg; + u32 colour_fg; + u32 colour_bg; bool flush_dcache; ushort *cmap; + u8 fg; };
/* Placeholder - there are no video operations at present */
participants (1)
-
Heinrich Schuchardt