]> git.sur5r.net Git - u-boot/commitdiff
dm: video: Add color ANSI escape sequence support
authorRob Clark <robdclark@gmail.com>
Wed, 13 Sep 2017 22:12:22 +0000 (18:12 -0400)
committerAnatolij Gustschin <agust@denx.de>
Fri, 29 Sep 2017 15:55:16 +0000 (17:55 +0200)
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>
drivers/video/vidconsole-uclass.c

index 37eb2a0ef46da513f6565b9706545a9ec9a6be15..5f63c12d6c5924bf19c72234abb06f57fcecb8ab 100644 (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);