On 7 September 2017 at 14:28, Rob Clark <robdcl...@gmail.com> wrote: > Really just the subset that is needed by efi_console. Perhaps more will > be added later, for example color support would be useful to implement > efi_cout_set_attribute(). > > Signed-off-by: Rob Clark <robdcl...@gmail.com> > --- > drivers/video/vidconsole-uclass.c | 112 > ++++++++++++++++++++++++++++++++++++++ > drivers/video/video-uclass.c | 4 +- > include/video.h | 7 +++ > include/video_console.h | 11 ++++ > 4 files changed, 131 insertions(+), 3 deletions(-) > > diff --git a/drivers/video/vidconsole-uclass.c > b/drivers/video/vidconsole-uclass.c > index e081d5a0ee..7998b4cf5f 100644 > --- a/drivers/video/vidconsole-uclass.c > +++ b/drivers/video/vidconsole-uclass.c > @@ -9,6 +9,7 @@ > */ > > #include <common.h> > +#include <linux/ctype.h> > #include <dm.h> > #include <video.h> > #include <video_console.h> > @@ -107,12 +108,123 @@ static void vidconsole_newline(struct udevice *dev) > video_sync(dev->parent); > } > > +/* > + * Parse a number from string that ends in a non-numeric character.. > + * sscanf() would be nice. This is just enough for parsing ANSI escape > + * sequences. > + */ > +static char *parsenum(char *s, int *num)
Can you use simple_strtoul() or similar? > +{ > + int n = 0; > + > + while (isdigit(*s)) { > + n = (10 * n) + (*s - '0'); > + s++; > + } > + > + *num = n; > + return s; > +} > + > +static void vidconsole_escape_char(struct udevice *dev, char ch) Please add a function comment > +{ > + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); > + > + /* Sanity checking for bogus ESC sequences: */ > + if (priv->escape_len >= sizeof(priv->escape_buf)) > + goto error; > + if (priv->escape_len == 0 && ch != '[') > + goto error; > + > + priv->escape_buf[priv->escape_len++] = ch; > + > + /* > + * Escape sequences are terminated by a letter, so keep > + * accumulating until we get one: > + */ > + if (!isalpha(ch)) > + return; > + > + /* > + * clear escape mode first, otherwise things will get highly > + * surprising if you hit any debug prints that come back to > + * this console. > + */ > + priv->escape = 0; > + > + switch (ch) { > + case 'H': > + case 'f': { > + int row, col; > + char *s = priv->escape_buf; > + > + /* > + * Set cursor position: [%d;%df or [%d;%dH > + */ > + s++; /* [ */ > + s = parsenum(s, &row); > + s++; /* ; */ > + s = parsenum(s, &col); > + > + priv->ycur = row * priv->y_charsize; > + priv->xcur_frac = priv->xstart_frac + > + VID_TO_POS(col * priv->x_charsize); > + > + break; > + } > + case 'J': { > + int mode; > + > + /* > + * Clear part/all screen: > + * [J or [0J - clear screen from cursor down > + * [1J - clear screen from cursor up > + * [2J - clear entire screen > + * > + * TODO we really only handle entire-screen case, others > + * probably require some additions to video-uclass (and > + * are not really needed yet by efi_console) > + */ > + parsenum(priv->escape_buf + 1, &mode); > + > + if (mode == 2) { > + video_clear(dev->parent); > + video_sync(dev->parent); > + priv->ycur = 0; > + priv->xcur_frac = priv->xstart_frac; > + } else { > + debug("unsupported clear mode: %d\n", mode); > + } > + break; > + } > + default: > + debug("unrecognized escape sequence: %*s\n", > + priv->escape_len, priv->escape_buf); > + } > + > + return; > + > +error: > + /* something went wrong, just revert to normal mode: */ > + priv->escape = 0; > + return; > +} > + > int vidconsole_put_char(struct udevice *dev, char ch) > { > struct vidconsole_priv *priv = dev_get_uclass_priv(dev); > int ret; > > + if (priv->escape) { > + vidconsole_escape_char(dev, ch); > + return 0; > + } Is it possible to add a CONFIG_VIDEO_ANSI option to enable this? Perhaps it could be on by default. Then: if (CONFIG_IS_ENABLED(VIDEO_ANSI) && priv-escape) { ... This helps to reduce base code size. > + > switch (ch) { > + case '\x1b': > + priv->escape_len = 0; > + priv->escape = 1; > + break; > case '\a': > /* beep */ > break; > diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c > index dfa39b0d1b..dcaceed42c 100644 > --- a/drivers/video/video-uclass.c > +++ b/drivers/video/video-uclass.c > @@ -87,7 +87,7 @@ int video_reserve(ulong *addrp) > return 0; > } > > -static int video_clear(struct udevice *dev) > +void video_clear(struct udevice *dev) > { > struct video_priv *priv = dev_get_uclass_priv(dev); > > @@ -100,8 +100,6 @@ static int video_clear(struct udevice *dev) > } else { > memset(priv->fb, priv->colour_bg, priv->fb_size); > } > - > - return 0; > } > > /* Flush video activity to the caches */ > diff --git a/include/video.h b/include/video.h > index 5b4e78b182..61ff653121 100644 > --- a/include/video.h > +++ b/include/video.h > @@ -115,6 +115,13 @@ struct video_ops { > int video_reserve(ulong *addrp); > > /** > + * video_clear() - Clear a device's frame buffer to background color. > + * > + * @dev: Device to clear > + */ > +void video_clear(struct udevice *dev); > + > +/** > * video_sync() - Sync a device's frame buffer with its hardware > * > * Some frame buffers are cached or have a secondary frame buffer. This > diff --git a/include/video_console.h b/include/video_console.h > index 26047934da..9dce234bd9 100644 > --- a/include/video_console.h > +++ b/include/video_console.h > @@ -29,6 +29,9 @@ > * @xsize_frac: Width of the display in fractional units > * @xstart_frac: Left margin for the text console in fractional units > * @last_ch: Last character written to the text console on this line > + * @escape: TRUE if currently accumulating an ANSI escape sequence > + * @escape_len: Length of accumulated escape sequence so far > + * @escape_buf: Buffer to accumulate escape sequence > */ > struct vidconsole_priv { > struct stdio_dev sdev; > @@ -42,6 +45,14 @@ struct vidconsole_priv { > int xsize_frac; > int xstart_frac; > int last_ch; > + /* > + * ANSI escape sequences are accumulated character by character, > + * starting after the ESC char (0x1b) until the entire sequence > + * is consumed at which point it is acted upon. > + */ > + int escape; > + int escape_len; > + char escape_buf[32]; > }; > > /** > -- > 2.13.5 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot