diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index b5d0e3dcec..fd03fc65a8 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -32,6 +32,7 @@ static int console_set_font(struct udevice *dev, struct video_fontdata *fontdata priv->fontdata = fontdata; vc_priv->x_charsize = fontdata->width; vc_priv->y_charsize = fontdata->height; + vc_priv->cursor_visible = true; if (vid_priv->rot % 2) { vc_priv->cols = vid_priv->ysize / fontdata->width; vc_priv->rows = vid_priv->xsize / fontdata->height; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index b5b3b66259..a6d994bd63 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -56,6 +56,26 @@ static int vidconsole_entry_start(struct udevice *dev) return ops->entry_start(dev); } +static void draw_cursor(struct udevice *dev, bool state) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); + u32 tmp; + + if (!priv->cursor_visible) + return; + + if (state) { + tmp = vid_priv->colour_bg; + vid_priv->colour_bg = vid_priv->colour_fg; + } + + vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ' '); + + if (state) + vid_priv->colour_bg = tmp; +} + /* Move backwards one space */ static int vidconsole_back(struct udevice *dev) { @@ -63,6 +83,8 @@ static int vidconsole_back(struct udevice *dev) struct vidconsole_ops *ops = vidconsole_get_ops(dev); int ret; + draw_cursor(dev, false); + if (ops->backspace) { ret = ops->backspace(dev); if (ret != -ENOSYS) @@ -89,6 +111,8 @@ static void vidconsole_newline(struct udevice *dev) const int rows = CONFIG_VAL(CONSOLE_SCROLL_LINES); int i, ret; + draw_cursor(dev, false); + priv->xcur_frac = priv->xstart_frac; priv->ycur += priv->y_charsize; @@ -282,6 +306,14 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) break; } + case 'l': + draw_cursor(dev, false); + priv->cursor_visible = 0; + break; + case 'h': + priv->cursor_visible = 1; + draw_cursor(dev, true); + break; case 'J': { int mode; @@ -456,6 +488,11 @@ int vidconsole_put_char(struct udevice *dev, char ch) struct vidconsole_priv *priv = dev_get_uclass_priv(dev); int ret; + /* + * We don't need to clear the cursor since we are going to overwrite + * that character anyway. + */ + if (priv->escape) { vidconsole_escape_char(dev, ch); return 0; @@ -470,6 +507,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) /* beep */ break; case '\r': + draw_cursor(dev, false); priv->xcur_frac = priv->xstart_frac; break; case '\n': @@ -477,6 +515,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) vidconsole_entry_start(dev); break; case '\t': /* Tab (8 chars alignment) */ + draw_cursor(dev, false); priv->xcur_frac = ((priv->xcur_frac / priv->tab_width_frac) + 1) * priv->tab_width_frac; @@ -494,6 +533,8 @@ int vidconsole_put_char(struct udevice *dev, char ch) break; } + draw_cursor(dev, true); + return 0; } @@ -646,6 +687,7 @@ static int vidconsole_pre_probe(struct udevice *dev) struct video_priv *vid_priv = dev_get_uclass_priv(vid); priv->xsize_frac = VID_TO_POS(vid_priv->xsize); + priv->cursor_visible = false; return 0; } diff --git a/include/video_console.h b/include/video_console.h index 2694e44f6e..949abb3861 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -59,6 +59,7 @@ struct vidconsole_priv { int escape_len; int row_saved; int col_saved; + bool cursor_visible; char escape_buf[32]; };