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>
This commit is contained in:
parent
1e2f65d72a
commit
3cade5ec3a
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue