diff options
author | Bastian Stender <bst@pengutronix.de> | 2017-02-23 18:20:22 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2017-02-28 07:45:38 +0100 |
commit | 3cade5ec3a8a0bbf15c8495915961c9d718877be (patch) | |
tree | 93318dfa27204e865eeea7740e1464a29844ff0c /drivers/video | |
parent | 1e2f65d72a66da459227d5fdc165b2f02ce7f186 (diff) | |
download | barebox-3cade5ec3a8a0bbf15c8495915961c9d718877be.tar.gz barebox-3cade5ec3a8a0bbf15c8495915961c9d718877be.tar.xz |
fbconsole: implement vt100 cursor shown/hidden
This implements the vt100 show cursor command '[?25h' and the hide
cursor command '[?25l'. It is useful for displaying text on a non-active
(no stdout/stdin/stderr) console with 'echo'.
Signed-off-by: Bastian Stender <bst@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbconsole.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/drivers/video/fbconsole.c b/drivers/video/fbconsole.c index 598ca29282..b5e608e1e4 100644 --- a/drivers/video/fbconsole.c +++ b/drivers/video/fbconsole.c @@ -11,6 +11,7 @@ enum state_t { LIT, /* Literal input */ ESC, /* Start of escape sequence */ CSI, /* Reading arguments in "CSI Pn ;...*/ + CSI_CNT, }; struct fbc_priv { @@ -34,10 +35,12 @@ struct fbc_priv { #define ANSI_FLAG_INVERT (1 << 0) #define ANSI_FLAG_BRIGHT (1 << 1) +#define HIDE_CURSOR (1 << 2) unsigned flags; int csipos; u8 csi[256]; + unsigned char csi_cmd; int active; int in_console; @@ -144,6 +147,12 @@ static void video_invertchar(struct fbc_priv *priv, int x, int y) priv->font->width, priv->font->height); } +static void show_cursor(struct fbc_priv *priv, int x, int y) +{ + if (!(priv->flags & HIDE_CURSOR)) + video_invertchar(priv, x, y); +} + static void printchar(struct fbc_priv *priv, int c) { video_invertchar(priv, priv->x, priv->y); @@ -200,7 +209,7 @@ static void printchar(struct fbc_priv *priv, int c) priv->y = priv->rows; } - video_invertchar(priv, priv->x, priv->y); + show_cursor(priv, priv->x, priv->y); return; } @@ -258,12 +267,43 @@ static void fbc_parse_csi(struct fbc_priv *priv) case 'm': fbc_parse_colors(priv); return; + case '?': /* vt100: show/hide cursor */ + priv->csi_cmd = last; + priv->state = CSI_CNT; + return; + case 'h': + /* suffix for vt100 "[?25h" */ + switch (priv->csi_cmd) { + case '?': /* cursor visible */ + priv->csi_cmd = -1; + if (!(priv->flags & HIDE_CURSOR)) + break; + + priv->flags &= ~HIDE_CURSOR; + /* show cursor now */ + show_cursor(priv, priv->x, priv->y); + break; + } + break; + case 'l': + /* suffix for vt100 "[?25l" */ + switch (priv->csi_cmd) { + case '?': /* cursor invisible */ + priv->csi_cmd = -1; + + /* hide cursor now */ + video_invertchar(priv, priv->x, priv->y); + priv->flags |= HIDE_CURSOR; + + break; + } + break; case 'J': cls(priv); - video_invertchar(priv, priv->x, priv->y); + show_cursor(priv, priv->x, priv->y); return; case 'H': - video_invertchar(priv, priv->x, priv->y); + show_cursor(priv, priv->x, priv->y); pos = simple_strtoul(priv->csi, &end, 10); priv->y = clamp(pos - 1, 0, (int) priv->rows); @@ -271,7 +311,7 @@ static void fbc_parse_csi(struct fbc_priv *priv) pos = simple_strtoul(end + 1, NULL, 10); priv->x = clamp(pos - 1, 0, (int) priv->cols); - video_invertchar(priv, priv->x, priv->y); + show_cursor(priv, priv->x, priv->y); case 'K': pos = simple_strtoul(priv->csi, &end, 10); video_invertchar(priv, priv->x, priv->y); @@ -343,9 +383,14 @@ static void fbc_putc(struct console_device *cdev, char c) break; default: fbc_parse_csi(priv); - priv->state = LIT; + if (priv->state != CSI_CNT) + priv->state = LIT; } break; + case CSI_CNT: + priv->state = CSI; + break; + } priv->in_console = 0; } |