[Concept,09/14] video: Move xcur_frac into vidconsole_ctx

Message ID 20260116171424.398597-10-sjg@u-boot.org
State New
Headers
Series video: Add per-client context to vidconsole |

Commit Message

Simon Glass Jan. 16, 2026, 5:14 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Move the xcur_frac field from vidconsole_priv into vidconsole_ctx as
part of the per-client context refactoring. This allows each client to
maintain its own cursor X position.

Update all files that access xcur_frac to use the ctx pointer:
vidconsole-uclass.c, console_normal.c, and console_truetype.c.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 drivers/video/console_normal.c    |  6 +++--
 drivers/video/console_truetype.c  | 17 +++++++++-----
 drivers/video/vidconsole-uclass.c | 37 ++++++++++++++++++-------------
 include/video_console.h           | 12 +++++-----
 4 files changed, 42 insertions(+), 30 deletions(-)
  

Patch

diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index cc0ac79a924..0aadd8bc96f 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -150,6 +150,7 @@  static __maybe_unused int normal_entry_save(struct udevice *dev,
 					    struct abuf *buf)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv);
 	struct console_store store;
 	const uint size = sizeof(store);
 
@@ -159,7 +160,7 @@  static __maybe_unused int normal_entry_save(struct udevice *dev,
 	if (!abuf_realloc(buf, size))
 		return log_msg_ret("sav", -ENOMEM);
 
-	store.xpos_frac = vc_priv->xcur_frac;
+	store.xpos_frac = ctx->xcur_frac;
 	store.ypos  = vc_priv->ycur;
 	store.cli_index  = vc_priv->cli_index;
 	memcpy(abuf_data(buf), &store, size);
@@ -171,6 +172,7 @@  static __maybe_unused int normal_entry_restore(struct udevice *dev,
 					       struct abuf *buf)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv);
 	struct console_store store;
 
 	if (xpl_phase() <= PHASE_SPL)
@@ -178,7 +180,7 @@  static __maybe_unused int normal_entry_restore(struct udevice *dev,
 
 	memcpy(&store, abuf_data(buf), sizeof(store));
 
-	vc_priv->xcur_frac = store.xpos_frac;
+	ctx->xcur_frac = store.xpos_frac;
 	vc_priv->ycur = store.ypos;
 	vc_priv->cli_index = store.cli_index;
 
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 62a3f501958..386e9aa8a59 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -416,6 +416,7 @@  static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 				    int cp)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *vc_ctx = vidconsole_ctx_from_priv(vc_priv);
 	struct udevice *vid = dev->parent;
 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
 	struct console_tt_priv *priv = dev_get_priv(dev);
@@ -495,7 +496,7 @@  static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 		}
 
 		pos = &ctx->pos[ctx->pos_ptr];
-		pos->xpos_frac = vc_priv->xcur_frac;
+		pos->xpos_frac = vc_ctx->xcur_frac;
 		pos->ypos = vc_priv->ycur;
 		pos->width = (width_frac + VID_FRAC_DIV - 1) / VID_FRAC_DIV;
 		pos->cp = cp;
@@ -683,6 +684,7 @@  static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y,
 static int console_truetype_backspace(struct udevice *dev)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *vc_ctx = vidconsole_ctx_from_priv(vc_priv);
 	struct console_tt_priv *priv = dev_get_priv(dev);
 	struct console_tt_ctx *ctx = &priv->ctx;
 	struct udevice *vid_dev = dev->parent;
@@ -706,12 +708,12 @@  static int console_truetype_backspace(struct udevice *dev)
 	 * line, we clear from the end of the line.
 	 */
 	if (pos->ypos == vc_priv->ycur)
-		xend = VID_TO_PIXEL(vc_priv->xcur_frac);
+		xend = VID_TO_PIXEL(vc_ctx->xcur_frac);
 	else
 		xend = vid_priv->xsize;
 
 	/* Move the cursor back to where it was when we pushed this record */
-	vc_priv->xcur_frac = pos->xpos_frac;
+	vc_ctx->xcur_frac = pos->xpos_frac;
 	vc_priv->ycur = pos->ypos;
 
 	return 0;
@@ -1183,6 +1185,7 @@  static int truetype_ctx_dispose(struct udevice *dev, void *ctx)
 static int truetype_entry_save(struct udevice *dev, struct abuf *buf)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *vc_ctx = vidconsole_ctx_from_priv(vc_priv);
 	struct console_tt_priv *priv = dev_get_priv(dev);
 	struct console_tt_store store;
 	const uint size = sizeof(store);
@@ -1198,7 +1201,7 @@  static int truetype_entry_save(struct udevice *dev, struct abuf *buf)
 		return log_msg_ret("sav", -ENOMEM);
 
 	store.priv = *priv;
-	store.cur.xpos_frac = vc_priv->xcur_frac;
+	store.cur.xpos_frac = vc_ctx->xcur_frac;
 	store.cur.ypos  = vc_priv->ycur;
 	memcpy(abuf_data(buf), &store, size);
 
@@ -1208,6 +1211,7 @@  static int truetype_entry_save(struct udevice *dev, struct abuf *buf)
 static int truetype_entry_restore(struct udevice *dev, struct abuf *buf)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *vc_ctx = vidconsole_ctx_from_priv(vc_priv);
 	struct console_tt_priv *priv = dev_get_priv(dev);
 	struct console_tt_ctx *ctx = &priv->ctx;
 	struct console_tt_store store;
@@ -1217,7 +1221,7 @@  static int truetype_entry_restore(struct udevice *dev, struct abuf *buf)
 
 	memcpy(&store, abuf_data(buf), sizeof(store));
 
-	vc_priv->xcur_frac = store.cur.xpos_frac;
+	vc_ctx->xcur_frac = store.cur.xpos_frac;
 	vc_priv->ycur = store.cur.ypos;
 	*ctx = store.priv.ctx;
 
@@ -1227,6 +1231,7 @@  static int truetype_entry_restore(struct udevice *dev, struct abuf *buf)
 static int truetype_get_cursor_info(struct udevice *dev)
 {
 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *vc_ctx = vidconsole_ctx_from_priv(vc_priv);
 	struct console_tt_priv *priv = dev_get_priv(dev);
 	struct console_tt_ctx *ctx = &priv->ctx;
 	struct vidconsole_cursor *curs = &vc_priv->curs;
@@ -1249,7 +1254,7 @@  static int truetype_get_cursor_info(struct udevice *dev)
 	if (0 && index < ctx->pos_count)
 		x = VID_TO_PIXEL(ctx->pos[index].xpos_frac);
 	else
-		x = VID_TO_PIXEL(vc_priv->xcur_frac);
+		x = VID_TO_PIXEL(vc_ctx->xcur_frac);
 	y = vc_priv->ycur;
 
 	/* Get font height from current font type */
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index ddcf2e87b6b..8bc2384dd7a 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -76,9 +76,9 @@  static int vidconsole_back(struct udevice *dev)
 	/* Hide cursor at old position if it's visible */
 	vidconsole_hide_cursor(dev);
 
-	priv->xcur_frac -= VID_TO_POS(ctx->x_charsize);
-	if (priv->xcur_frac < priv->xstart_frac) {
-		priv->xcur_frac = (ctx->cols - 1) *
+	ctx->xcur_frac -= VID_TO_POS(ctx->x_charsize);
+	if (ctx->xcur_frac < priv->xstart_frac) {
+		ctx->xcur_frac = (ctx->cols - 1) *
 			VID_TO_POS(ctx->x_charsize);
 		priv->ycur -= ctx->y_charsize;
 		if (priv->ycur < 0)
@@ -100,7 +100,7 @@  static void vidconsole_newline(struct udevice *dev)
 	const int rows = CONFIG_VAL(CONSOLE_SCROLL_LINES);
 	int i, ret;
 
-	priv->xcur_frac = priv->xstart_frac;
+	ctx->xcur_frac = priv->xstart_frac;
 	priv->ycur += ctx->y_charsize;
 
 	/* Check if we need to scroll the terminal */
@@ -133,12 +133,13 @@  static char *parsenum(char *s, int *num)
 void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv);
 
 	/* Hide cursor at old position if it's visible */
 	vidconsole_hide_cursor(dev);
 
-	priv->xcur_frac = VID_TO_POS(x);
-	priv->xstart_frac = priv->xcur_frac;
+	ctx->xcur_frac = VID_TO_POS(x);
+	priv->xstart_frac = ctx->xcur_frac;
 	priv->ycur = y;
 
 	/* make sure not to kern against the previous character */
@@ -181,7 +182,7 @@  static void get_cursor_position(struct vidconsole_priv *priv,
 	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv);
 
 	*row = priv->ycur / ctx->y_charsize;
-	*col = VID_TO_PIXEL(priv->xcur_frac - priv->xstart_frac) /
+	*col = VID_TO_PIXEL(ctx->xcur_frac - priv->xstart_frac) /
 	       ctx->x_charsize;
 }
 
@@ -193,6 +194,7 @@  static void get_cursor_position(struct vidconsole_priv *priv,
 static void vidconsole_escape_char(struct udevice *dev, char ch)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv);
 	struct vidconsole_ansi *ansi = &priv->ansi;
 
 	if (!IS_ENABLED(CONFIG_VIDEO_ANSI))
@@ -331,7 +333,7 @@  static void vidconsole_escape_char(struct udevice *dev, char ch)
 #endif
 			}
 			priv->ycur = 0;
-			priv->xcur_frac = priv->xstart_frac;
+			ctx->xcur_frac = priv->xstart_frac;
 		} else {
 			debug("unsupported clear mode: %d\n", mode);
 		}
@@ -452,6 +454,7 @@  error:
 static int vidconsole_output_glyph(struct udevice *dev, int ch)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv);
 	int ret;
 
 	if (_DEBUG) {
@@ -464,16 +467,16 @@  static int vidconsole_output_glyph(struct udevice *dev, int ch)
 	 * colour depth. Check this and return an error to help with
 	 * diagnosis.
 	 */
-	ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch);
+	ret = vidconsole_putc_xy(dev, ctx->xcur_frac, priv->ycur, ch);
 	if (ret == -EAGAIN) {
 		vidconsole_newline(dev);
-		ret = vidconsole_putc_xy(dev, priv->xcur_frac, priv->ycur, ch);
+		ret = vidconsole_putc_xy(dev, ctx->xcur_frac, priv->ycur, ch);
 	}
 	if (ret < 0)
 		return ret;
-	priv->xcur_frac += ret;
+	ctx->xcur_frac += ret;
 	priv->last_ch = ch;
-	if (priv->xcur_frac >= priv->xsize_frac)
+	if (ctx->xcur_frac >= priv->xsize_frac)
 		vidconsole_newline(dev);
 	cli_index_adjust(priv, 1);
 
@@ -483,6 +486,7 @@  static int vidconsole_output_glyph(struct udevice *dev, int ch)
 int vidconsole_put_char(struct udevice *dev, char ch)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv);
 	struct vidconsole_ansi *ansi = &priv->ansi;
 	int cp, ret;
 
@@ -503,17 +507,17 @@  int vidconsole_put_char(struct udevice *dev, char ch)
 		/* beep */
 		break;
 	case '\r':
-		priv->xcur_frac = priv->xstart_frac;
+		ctx->xcur_frac = priv->xstart_frac;
 		break;
 	case '\n':
 		vidconsole_newline(dev);
 		vidconsole_entry_start(dev);
 		break;
 	case '\t':	/* Tab (8 chars alignment) */
-		priv->xcur_frac = ((priv->xcur_frac / priv->tab_width_frac)
+		ctx->xcur_frac = ((ctx->xcur_frac / priv->tab_width_frac)
 				+ 1) * priv->tab_width_frac;
 
-		if (priv->xcur_frac >= priv->xsize_frac)
+		if (ctx->xcur_frac >= priv->xsize_frac)
 			vidconsole_newline(dev);
 		break;
 	case '\b':
@@ -832,9 +836,10 @@  int vidconsole_hide_cursor(struct udevice *dev)
 int vidconsole_mark_start(struct udevice *dev)
 {
 	struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+	struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv);
 	struct vidconsole_ops *ops = vidconsole_get_ops(dev);
 
-	priv->xmark_frac = priv->xcur_frac;
+	priv->xmark_frac = ctx->xcur_frac;
 	priv->ymark = priv->ycur;
 	priv->cli_index = 0;
 	if (ops->mark_start) {
diff --git a/include/video_console.h b/include/video_console.h
index 6f74f64cddf..f6971a20e0d 100644
--- a/include/video_console.h
+++ b/include/video_console.h
@@ -83,12 +83,14 @@  struct vidconsole_cursor {
  * @cols:		Number of text columns
  * @x_charsize:		Character width in pixels
  * @y_charsize:		Character height in pixels
+ * @xcur_frac:		Current X position, in fractional units (VID_TO_POS(x))
  */
 struct vidconsole_ctx {
 	int rows;
 	int cols;
 	int x_charsize;
 	int y_charsize;
+	int xcur_frac;
 };
 
 /**
@@ -121,13 +123,12 @@  struct vidconsole_ansi {
  * Note that these values relate to the rotated console, so that an 80x25
  * console which is rotated 90 degrees will have rows=80 and cols=25
  *
- * The xcur_frac and ycur values refer to the unrotated coordinates, that is
- * xcur_frac always advances with each character, even if its limit might be
- * vid_priv->ysize instead of vid_priv->xsize if the console is rotated 90 or
- * 270 degrees.
+ * The ctx.xcur_frac and ycur values refer to the unrotated coordinates, that
+ * is ctx.xcur_frac always advances with each character, even if its limit
+ * might be vid_priv->ysize instead of vid_priv->xsize if the console is
+ * rotated 90 or 270 degrees.
  *
  * @sdev:		stdio device, acting as an output sink
- * @xcur_frac:		Current X position, in fractional units (VID_TO_POS(x))
  * @ycur:		Current Y position in pixels (0=top)
  * @ctx:		Per-client context
  * @tab_width_frac:	Tab width in fractional units
@@ -145,7 +146,6 @@  struct vidconsole_ansi {
 struct vidconsole_priv {
 	struct stdio_dev sdev;
 	struct vidconsole_ctx ctx;
-	int xcur_frac;
 	int ycur;
 	int tab_width_frac;
 	int xsize_frac;