diff --git a/drivers/video/fbconsole.c b/drivers/video/fbconsole.c index 598ca29..b5e608e 100644 --- a/drivers/video/fbconsole.c +++ b/drivers/video/fbconsole.c @@ -11,6 +11,7 @@ LIT, /* Literal input */ ESC, /* Start of escape sequence */ CSI, /* Reading arguments in "CSI Pn ;...*/ + CSI_CNT, }; struct fbc_priv { @@ -34,10 +35,12 @@ #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 @@ 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 @@ priv->y = priv->rows; } - video_invertchar(priv, priv->x, priv->y); + show_cursor(priv, priv->x, priv->y); return; } @@ -258,12 +267,43 @@ 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 @@ 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 @@ 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; }