[PATCH 1/8] video: Add cursor support for DM_VIDEO consoles

Andre Przywara andre.przywara at arm.com
Mon Jan 10 01:56:31 CET 2022


So far the DM_VIDEO console is completely lacking any cursor, which makes
typing and correcting quite irritating.

Add a simple cursor display by writing a SPACE glyph in the background
colour to the next character position on the screen. Any typed character
will naturally overwrite it, so we need to only explicitly clear it if
the next character will appear somewhere else (newline, backspace).

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/video/console_normal.c    |  1 +
 drivers/video/vidconsole-uclass.c | 42 +++++++++++++++++++++++++++++++
 include/video_console.h           |  1 +
 3 files changed, 44 insertions(+)

diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index 04f022491e5..bfd3aab8d24 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -160,6 +160,7 @@ static int console_normal_probe(struct udevice *dev)
 	vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
 	vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
 	vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
+	vc_priv->cursor_visible = true;
 
 	return 0;
 }
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index f42db40d4cd..420fd86f9ac 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -70,6 +70,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)
 {
@@ -77,6 +97,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)
@@ -103,6 +125,8 @@ static void vidconsole_newline(struct udevice *dev)
 	const int rows = CONFIG_CONSOLE_SCROLL_LINES;
 	int i, ret;
 
+	draw_cursor(dev, false);
+
 	priv->xcur_frac = priv->xstart_frac;
 	priv->ycur += priv->y_charsize;
 
@@ -342,6 +366,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;
 
@@ -516,6 +548,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;
@@ -530,6 +567,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':
@@ -537,6 +575,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;
 
@@ -554,6 +593,8 @@ int vidconsole_put_char(struct udevice *dev, char ch)
 		break;
 	}
 
+	draw_cursor(dev, true);
+
 	return 0;
 }
 
@@ -620,6 +661,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 06b798ef10c..a908f1412e8 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -83,6 +83,7 @@ struct vidconsole_priv {
 	int escape_len;
 	int row_saved;
 	int col_saved;
+	bool cursor_visible;
 	char escape_buf[32];
 };
 
-- 
2.17.6



More information about the U-Boot mailing list