summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBastian Stender <bst@pengutronix.de>2017-02-23 18:20:22 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-02-28 07:45:38 +0100
commit3cade5ec3a8a0bbf15c8495915961c9d718877be (patch)
tree93318dfa27204e865eeea7740e1464a29844ff0c
parent1e2f65d72a66da459227d5fdc165b2f02ce7f186 (diff)
downloadbarebox-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>
-rw-r--r--drivers/video/fbconsole.c55
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;
}