[PATCH 00/18] Refactor vidconsole context for dynamic allocation
From: Simon Glass <simon.glass@canonical.com> This series refactors the vidconsole subsystem to support dynamic context allocation. This is groundwork for allowing multiple independent contexts per vidconsole device, which will enable each expo textline to have its own context without needing save/restore logic. The main changes are: 1. Move fields from vidconsole_priv into vidconsole_ctx (patches 2-5) - curs, xstart_frac, tab_width_frac, xsize_frac - This consolidates per-context state into a single structure 2. Add infrastructure for dynamic context allocation (patches 8-10) - Add vidconsole_uc_plat with ctx_size for per-driver context sizes - Implement vidconsole_ctx_new/dispose for context lifecycle - Allocate vidconsole_ctx dynamically using ctx_size 3. Clean up truetype driver (patches 1, 11-12) - Rename vc_ctx to com for consistency - Remove embedded ctx from console_tt_priv - Use consistent ctx/com pattern throughout 4. Move truetype-specific fields to console_tt_ctx (patches 13-14) - cur_met, cur_fontdata now in console_tt_ctx - These are per-context rather than per-device 5. Simplify save/restore (patches 15-17) - Remove redundant store.cur field - Remove console_tt_store and console_store structs - Save/restore entire context directly 6. Add tests (patch 18) - Add dm_test_video_entry_save() for bitmap fonts - Add dm_test_video_entry_save_tt() for truetype fonts The next step (not in this series) is to add a ctx parameter to driver methods like putc_xy(), allowing callers to specify which context to use. This will enable expo textlines to each maintain their own cursor position and state. Simon Glass (18): video: truetype: Rename vc_ctx to com video: Move curs into vidconsole_ctx video: Move xstart_frac into vidconsole_ctx video: Move tab_width_frac into vidconsole_ctx video: Move xsize_frac into vidconsole_ctx video: Use vidconsole_ctx_from_priv() in expo_test video: Update cli_index_adjust() to use vidconsole_ctx video: Add vidconsole_uc_plat for per-device platform data video: Set ctx_size in console_truetype driver video: Allocate vidconsole_ctx dynamically using ctx_size video: truetype: Remove ctx from console_tt_priv video: truetype: Use consistent ctx/com pattern video: Move cur_met to console_tt_ctx video: Move cur_fontdata to console_tt_ctx video: truetype: Remove redundant store.cur field video: truetype: Remove console_tt_store struct video: normal: Remove console_store struct video: Add test for entry save/restore board/atmel/common/video_display.c | 4 +- boot/expo_test.c | 12 +- drivers/video/console_core.c | 8 +- drivers/video/console_normal.c | 29 +--- drivers/video/console_rotate.c | 6 +- drivers/video/console_truetype.c | 221 ++++++++++++----------------- drivers/video/vidconsole-uclass.c | 73 ++++++---- include/video_console.h | 50 ++++--- test/dm/video.c | 70 ++++++++- 9 files changed, 260 insertions(+), 213 deletions(-) -- 2.43.0 base-commit: 1f26d803f26bdf6a03494caaf5ae5b5df18c7905 branch: expc
From: Simon Glass <simon.glass@canonical.com> Rename the common vidconsole_ctx pointer from 'vc_ctx' to 'com' for consistency with other drivers. The truetype-specific console_tt_ctx is accessed via '&priv->ctx' where needed. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 84 ++++++++++++++++---------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index e607dff0aea..37cc1f0fc5d 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -266,7 +266,7 @@ struct console_tt_store { static int console_truetype_set_row(struct udevice *dev, uint row, int clr) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct vidconsole_ctx *vc_ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = vidconsole_ctx(dev); struct console_tt_priv *priv = dev_get_priv(dev); void *end, *line; int font_height; @@ -314,9 +314,9 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr) video_damage(dev->parent, 0, - vc_ctx->y_charsize * row, + com->y_charsize * row, vid_priv->xsize, - vc_ctx->y_charsize); + com->y_charsize); return 0; } @@ -325,7 +325,7 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, uint rowsrc, uint count) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct vidconsole_ctx *vc_ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = vidconsole_ctx(dev); struct console_tt_priv *priv = dev_get_priv(dev); struct console_tt_ctx *ctx = &priv->ctx; void *dst; @@ -349,9 +349,9 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, video_damage(dev->parent, 0, - vc_ctx->y_charsize * rowdst, + com->y_charsize * rowdst, vid_priv->xsize, - vc_ctx->y_charsize * count); + com->y_charsize * count); return 0; } @@ -368,12 +368,12 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, */ static void clear_from(struct udevice *dev, int index) { + struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *vc_ctx = vidconsole_ctx_from_priv(vc_priv); + struct vidconsole_ctx *com = 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; - struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); struct pos_info *start_pos, *end_pos; int xstart, xend; int ystart, yend; @@ -392,22 +392,22 @@ static void clear_from(struct udevice *dev, int index) /* If on the same line, just erase from start to end position */ if (ystart == yend) { video_fill_part(vid_dev, xstart, ystart, xend, - ystart + vc_ctx->y_charsize, + ystart + com->y_charsize, vid_priv->colour_bg); } else { /* Different lines - erase to end of first line */ video_fill_part(vid_dev, xstart, ystart, vid_priv->xsize, - ystart + vc_ctx->y_charsize, vid_priv->colour_bg); + ystart + com->y_charsize, vid_priv->colour_bg); /* Erase any complete lines in between */ - if (yend > ystart + vc_ctx->y_charsize) { - video_fill_part(vid_dev, 0, ystart + vc_ctx->y_charsize, + if (yend > ystart + com->y_charsize) { + video_fill_part(vid_dev, 0, ystart + com->y_charsize, vid_priv->xsize, yend, vid_priv->colour_bg); } /* Erase from start of final line to end of last character */ video_fill_part(vid_dev, 0, yend, xend, - yend + vc_ctx->y_charsize, + yend + com->y_charsize, vid_priv->colour_bg); } } @@ -416,9 +416,8 @@ 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 video_priv *vid_priv = dev_get_uclass_priv(dev->parent); + struct vidconsole_ctx *com = 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_metrics *met = priv->cur_met; @@ -452,8 +451,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, pos = ctx->pos_ptr < ctx->pos_count ? &ctx->pos[ctx->pos_ptr] : NULL; xpos = frac(VID_TO_PIXEL((double)x)); kern = 0; - if (vc_ctx->last_ch) { - int last_cp = vc_ctx->last_ch; + if (com->last_ch) { + int last_cp = com->last_ch; if (pos) last_cp = pos->cp; @@ -496,8 +495,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, } pos = &ctx->pos[ctx->pos_ptr]; - pos->xpos_frac = vc_ctx->xcur_frac; - pos->ypos = vc_ctx->ycur; + pos->xpos_frac = com->xcur_frac; + pos->ypos = com->ycur; pos->width = (width_frac + VID_FRAC_DIV - 1) / VID_FRAC_DIV; pos->cp = cp; ctx->pos_ptr++; @@ -684,11 +683,10 @@ 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 video_priv *vid_priv = dev_get_uclass_priv(dev->parent); + struct vidconsole_ctx *com = 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; - struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); struct pos_info *pos; int xend; @@ -707,14 +705,14 @@ static int console_truetype_backspace(struct udevice *dev) * cursor position, but if we are clearing a character on the previous * line, we clear from the end of the line. */ - if (pos->ypos == vc_ctx->ycur) - xend = VID_TO_PIXEL(vc_ctx->xcur_frac); + if (pos->ypos == com->ycur) + xend = VID_TO_PIXEL(com->xcur_frac); else xend = vid_priv->xsize; /* Move the cursor back to where it was when we pushed this record */ - vc_ctx->xcur_frac = pos->xpos_frac; - vc_ctx->ycur = pos->ypos; + com->xcur_frac = pos->xpos_frac; + com->ycur = pos->ypos; return 0; } @@ -722,14 +720,14 @@ static int console_truetype_backspace(struct udevice *dev) static int console_truetype_entry_start(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 vidconsole_ctx *com = vidconsole_ctx_from_priv(vc_priv); struct console_tt_priv *priv = dev_get_priv(dev); struct console_tt_ctx *ctx = &priv->ctx; /* A new input line has start, so clear our history */ ctx->pos_ptr = 0; ctx->pos_count = 0; - vc_ctx->last_ch = 0; + com->last_ch = 0; return 0; } @@ -938,17 +936,17 @@ static void set_bitmap_font(struct udevice *dev, static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) { struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); + struct vidconsole_ctx *com = vidconsole_ctx_from_priv(vc_priv); struct console_tt_priv *priv = dev_get_priv(dev); struct udevice *vid_dev = dev_get_parent(dev); struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); priv->cur_met = met; - ctx->x_charsize = met->font_size; - ctx->y_charsize = met->font_size; + com->x_charsize = met->font_size; + com->y_charsize = met->font_size; vc_priv->xstart_frac = VID_TO_POS(2); - ctx->cols = vid_priv->xsize / met->font_size; - ctx->rows = vid_priv->ysize / met->font_size; + com->cols = vid_priv->xsize / met->font_size; + com->rows = vid_priv->ysize / met->font_size; vc_priv->tab_width_frac = VID_TO_POS(met->font_size) * 8 / 2; } @@ -1186,7 +1184,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 vidconsole_ctx *com = 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); @@ -1202,8 +1200,8 @@ 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_ctx->xcur_frac; - store.cur.ypos = vc_ctx->ycur; + store.cur.xpos_frac = com->xcur_frac; + store.cur.ypos = com->ycur; memcpy(abuf_data(buf), &store, size); return 0; @@ -1212,7 +1210,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 vidconsole_ctx *com = 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; @@ -1222,8 +1220,8 @@ static int truetype_entry_restore(struct udevice *dev, struct abuf *buf) memcpy(&store, abuf_data(buf), sizeof(store)); - vc_ctx->xcur_frac = store.cur.xpos_frac; - vc_ctx->ycur = store.cur.ypos; + com->xcur_frac = store.cur.xpos_frac; + com->ycur = store.cur.ypos; *ctx = store.priv.ctx; return 0; @@ -1232,7 +1230,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 vidconsole_ctx *com = 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; @@ -1255,8 +1253,8 @@ 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_ctx->xcur_frac); - y = vc_ctx->ycur; + x = VID_TO_PIXEL(com->xcur_frac); + y = com->ycur; /* Get font height from current font type */ if (priv->cur_fontdata) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The cursor state should be per-context so that different clients can maintain their own cursor information. Move the curs field from vidconsole_priv into vidconsole_ctx. Update all access to use the vidconsole_ctx() or vidconsole_ctx_from_priv() helpers for consistency. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_core.c | 6 +++--- drivers/video/console_normal.c | 2 +- drivers/video/console_truetype.c | 2 +- drivers/video/vidconsole-uclass.c | 24 +++++++++++++----------- include/video_console.h | 4 ++-- test/dm/video.c | 3 ++- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 9cf5831b562..50f67ffcf83 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -280,7 +280,7 @@ int cursor_hide(struct vidconsole_cursor *curs, struct video_priv *vid_priv, int console_alloc_cursor(struct udevice *dev) { - struct vidconsole_priv *vc_priv; + struct vidconsole_ctx *ctx; struct vidconsole_cursor *curs; struct video_priv *vid_priv; struct udevice *vid; @@ -289,10 +289,10 @@ int console_alloc_cursor(struct udevice *dev) if (!CONFIG_IS_ENABLED(CURSOR) || xpl_phase() < PHASE_BOARD_R) return 0; - vc_priv = dev_get_uclass_priv(dev); + ctx = vidconsole_ctx(dev); vid = dev_get_parent(dev); vid_priv = dev_get_uclass_priv(vid); - curs = &vc_priv->curs; + curs = &ctx->curs; /* Allocate cursor save buffer for maximum possible cursor height */ save_count = vid_priv->ysize * VIDCONSOLE_CURSOR_WIDTH; diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 73bf3a7ebe8..4854e953e58 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -98,7 +98,7 @@ static __maybe_unused int console_get_cursor_info(struct udevice *dev) struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); struct console_simple_priv *priv = dev_get_priv(dev); struct video_fontdata *fontdata = priv->fontdata; - struct vidconsole_cursor *curs = &vc_priv->curs; + struct vidconsole_cursor *curs = &ctx->curs; int x, y, index, xspace, xpos; /* for now, this is not used outside expo */ diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 37cc1f0fc5d..978e81a9350 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1233,7 +1233,7 @@ static int truetype_get_cursor_info(struct udevice *dev) struct vidconsole_ctx *com = 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; + struct vidconsole_cursor *curs = &com->curs; int x, y, index; uint height; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 2136253b15e..71bcb0d9c91 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -767,8 +767,9 @@ int vidconsole_entry_restore(struct udevice *dev, struct abuf *buf) int vidconsole_show_cursor(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); - struct vidconsole_cursor *curs = &priv->curs; + struct vidconsole_cursor *curs = &ctx->curs; int ret; /* find out where the cursor should be drawn */ @@ -807,7 +808,8 @@ int vidconsole_show_cursor(struct udevice *dev) int vidconsole_hide_cursor(struct udevice *dev) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_cursor *curs = &priv->curs; + struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); + struct vidconsole_cursor *curs = &ctx->curs; int ret; if (!curs->visible) @@ -912,9 +914,9 @@ static int vidconsole_post_probe(struct udevice *dev) static int vidconsole_pre_remove(struct udevice *dev) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = vidconsole_ctx(dev); - free(vc_priv->curs.save_data); + free(ctx->curs.save_data); return 0; } @@ -987,8 +989,8 @@ void vidconsole_set_bitmap_font(struct udevice *dev, void vidconsole_idle(struct udevice *dev) { - struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_cursor *curs = &priv->curs; + struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_cursor *curs = &ctx->curs; /* Only handle cursor if it's enabled */ if (curs->enabled && !curs->visible) { @@ -1008,10 +1010,10 @@ void vidconsole_readline_start(bool indent) struct udevice *dev; uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) { - struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = vidconsole_ctx(dev); - priv->curs.indent = indent; - priv->curs.enabled = true; + ctx->curs.indent = indent; + ctx->curs.enabled = true; vidconsole_mark_start(dev); } } @@ -1022,9 +1024,9 @@ void vidconsole_readline_end(void) struct udevice *dev; uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) { - struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = vidconsole_ctx(dev); - priv->curs.enabled = false; + ctx->curs.enabled = false; } } #endif /* CURSOR */ diff --git a/include/video_console.h b/include/video_console.h index bc468d753d4..5b90a5cf160 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -112,6 +112,7 @@ struct vidconsole_ansi { * @ymark: Y position of start of CLI text * @ansi: ANSI escape-sequence state * @utf8_buf: Buffer to accumulate UTF-8 byte sequence + * @curs: Cursor state and management */ struct vidconsole_ctx { int rows; @@ -126,6 +127,7 @@ struct vidconsole_ctx { int ymark; struct vidconsole_ansi ansi; char utf8_buf[5]; + struct vidconsole_cursor curs; }; /** @@ -148,7 +150,6 @@ struct vidconsole_ctx { * @xsize_frac: Width of the display in fractional units * @xstart_frac: Left margin for the text console in fractional units * @quiet: Suppress all output from stdio - * @curs: Cursor state and management */ struct vidconsole_priv { struct stdio_dev sdev; @@ -157,7 +158,6 @@ struct vidconsole_priv { int xsize_frac; int xstart_frac; bool quiet; - struct vidconsole_cursor curs; }; /** diff --git a/test/dm/video.c b/test/dm/video.c index d802a5cc24d..d3978f4b00c 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -1185,7 +1185,8 @@ static int check_cursor_backspace(struct unit_test_state *uts, { int with_a, with_cursor, after_backspace, after_idle, after_hide; struct vidconsole_priv *vc_priv = dev_get_uclass_priv(con); - struct vidconsole_cursor *curs = &vc_priv->curs; + struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); + struct vidconsole_cursor *curs = &ctx->curs; /* Output chars without cursor */ ut_assert(!curs->visible); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The left margin should be per-context so that different clients can maintain their own margin settings. Move the xstart_frac field from vidconsole_priv into vidconsole_ctx. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 2 +- drivers/video/vidconsole-uclass.c | 14 +++++++------- include/video_console.h | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 978e81a9350..36a2c33eb70 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -944,7 +944,7 @@ static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) priv->cur_met = met; com->x_charsize = met->font_size; com->y_charsize = met->font_size; - vc_priv->xstart_frac = VID_TO_POS(2); + com->xstart_frac = VID_TO_POS(2); com->cols = vid_priv->xsize / met->font_size; com->rows = vid_priv->ysize / met->font_size; vc_priv->tab_width_frac = VID_TO_POS(met->font_size) * 8 / 2; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 71bcb0d9c91..bc2b3943fc8 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -77,7 +77,7 @@ static int vidconsole_back(struct udevice *dev) vidconsole_hide_cursor(dev); ctx->xcur_frac -= VID_TO_POS(ctx->x_charsize); - if (ctx->xcur_frac < priv->xstart_frac) { + if (ctx->xcur_frac < ctx->xstart_frac) { ctx->xcur_frac = (ctx->cols - 1) * VID_TO_POS(ctx->x_charsize); ctx->ycur -= ctx->y_charsize; @@ -100,7 +100,7 @@ static void vidconsole_newline(struct udevice *dev) const int rows = CONFIG_VAL(CONSOLE_SCROLL_LINES); int i, ret; - ctx->xcur_frac = priv->xstart_frac; + ctx->xcur_frac = ctx->xstart_frac; ctx->ycur += ctx->y_charsize; /* Check if we need to scroll the terminal */ @@ -139,7 +139,7 @@ void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y) vidconsole_hide_cursor(dev); ctx->xcur_frac = VID_TO_POS(x); - priv->xstart_frac = ctx->xcur_frac; + ctx->xstart_frac = ctx->xcur_frac; ctx->ycur = y; /* make sure not to kern against the previous character */ @@ -182,7 +182,7 @@ static void get_cursor_position(struct vidconsole_priv *priv, struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); *row = ctx->ycur / ctx->y_charsize; - *col = VID_TO_PIXEL(ctx->xcur_frac - priv->xstart_frac) / + *col = VID_TO_PIXEL(ctx->xcur_frac - ctx->xstart_frac) / ctx->x_charsize; } @@ -333,7 +333,7 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) #endif } ctx->ycur = 0; - ctx->xcur_frac = priv->xstart_frac; + ctx->xcur_frac = ctx->xstart_frac; } else { debug("unsupported clear mode: %d\n", mode); } @@ -507,7 +507,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) /* beep */ break; case '\r': - ctx->xcur_frac = priv->xstart_frac; + ctx->xcur_frac = ctx->xstart_frac; break; case '\n': vidconsole_newline(dev); @@ -984,7 +984,7 @@ void vidconsole_set_bitmap_font(struct udevice *dev, ctx->rows = vid_priv->ysize / fontdata->height; /* xsize_frac is set in vidconsole_pre_probe() */ } - vc_priv->xstart_frac = 0; + ctx->xstart_frac = 0; } void vidconsole_idle(struct udevice *dev) diff --git a/include/video_console.h b/include/video_console.h index 5b90a5cf160..cedc94a83cf 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -113,6 +113,7 @@ struct vidconsole_ansi { * @ansi: ANSI escape-sequence state * @utf8_buf: Buffer to accumulate UTF-8 byte sequence * @curs: Cursor state and management + * @xstart_frac: Left margin for the text console in fractional units */ struct vidconsole_ctx { int rows; @@ -128,13 +129,14 @@ struct vidconsole_ctx { struct vidconsole_ansi ansi; char utf8_buf[5]; struct vidconsole_cursor curs; + int xstart_frac; }; /** * struct vidconsole_priv - uclass-private data about a console device * * Drivers must set up @ctx.rows, @ctx.cols, @ctx.x_charsize, @ctx.y_charsize - * in their probe() method. Drivers may set up @xstart_frac if desired. + * in their probe() method. Drivers may set up @ctx.xstart_frac if desired. * * 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 @@ -148,7 +150,6 @@ struct vidconsole_ctx { * @ctx: Per-client context * @tab_width_frac: Tab width in fractional units * @xsize_frac: Width of the display in fractional units - * @xstart_frac: Left margin for the text console in fractional units * @quiet: Suppress all output from stdio */ struct vidconsole_priv { @@ -156,7 +157,6 @@ struct vidconsole_priv { struct vidconsole_ctx ctx; int tab_width_frac; int xsize_frac; - int xstart_frac; bool quiet; }; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The tab width should be per-context so that different clients can maintain their own tab settings. Move the tab_width_frac field from vidconsole_priv into vidconsole_ctx. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 5 +++-- drivers/video/vidconsole-uclass.c | 8 ++++---- include/video_console.h | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 36a2c33eb70..9c7c116809b 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -923,6 +923,7 @@ static void set_bitmap_font(struct udevice *dev, struct video_fontdata *fontdata) { struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); struct console_tt_priv *priv = dev_get_priv(dev); priv->cur_fontdata = fontdata; @@ -930,7 +931,7 @@ static void set_bitmap_font(struct udevice *dev, vidconsole_set_bitmap_font(dev, fontdata); - vc_priv->tab_width_frac = VID_TO_POS(fontdata->width) * 8 / 2; + ctx->tab_width_frac = VID_TO_POS(fontdata->width) * 8 / 2; } static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) @@ -947,7 +948,7 @@ static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) com->xstart_frac = VID_TO_POS(2); com->cols = vid_priv->xsize / met->font_size; com->rows = vid_priv->ysize / met->font_size; - vc_priv->tab_width_frac = VID_TO_POS(met->font_size) * 8 / 2; + com->tab_width_frac = VID_TO_POS(met->font_size) * 8 / 2; } static int get_metrics(struct udevice *dev, const char *name, uint size, diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index bc2b3943fc8..414a33f7bf7 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -514,8 +514,8 @@ int vidconsole_put_char(struct udevice *dev, char ch) vidconsole_entry_start(dev); break; case '\t': /* Tab (8 chars alignment) */ - ctx->xcur_frac = ((ctx->xcur_frac / priv->tab_width_frac) - + 1) * priv->tab_width_frac; + ctx->xcur_frac = ((ctx->xcur_frac / ctx->tab_width_frac) + + 1) * ctx->tab_width_frac; if (ctx->xcur_frac >= priv->xsize_frac) vidconsole_newline(dev); @@ -894,8 +894,8 @@ static int vidconsole_post_probe(struct udevice *dev) struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); struct stdio_dev *sdev = &priv->sdev; - if (!priv->tab_width_frac) - priv->tab_width_frac = VID_TO_POS(ctx->x_charsize) * 8; + if (!ctx->tab_width_frac) + ctx->tab_width_frac = VID_TO_POS(ctx->x_charsize) * 8; if (dev_seq(dev)) { snprintf(sdev->name, sizeof(sdev->name), "vidconsole%d", diff --git a/include/video_console.h b/include/video_console.h index cedc94a83cf..ebba1ac7572 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -114,6 +114,7 @@ struct vidconsole_ansi { * @utf8_buf: Buffer to accumulate UTF-8 byte sequence * @curs: Cursor state and management * @xstart_frac: Left margin for the text console in fractional units + * @tab_width_frac: Tab width in fractional units */ struct vidconsole_ctx { int rows; @@ -130,6 +131,7 @@ struct vidconsole_ctx { char utf8_buf[5]; struct vidconsole_cursor curs; int xstart_frac; + int tab_width_frac; }; /** @@ -148,14 +150,12 @@ struct vidconsole_ctx { * * @sdev: stdio device, acting as an output sink * @ctx: Per-client context - * @tab_width_frac: Tab width in fractional units * @xsize_frac: Width of the display in fractional units * @quiet: Suppress all output from stdio */ struct vidconsole_priv { struct stdio_dev sdev; struct vidconsole_ctx ctx; - int tab_width_frac; int xsize_frac; bool quiet; }; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The display width should be per-context so that different clients can maintain their own display settings. Move the xsize_frac field from vidconsole_priv into vidconsole_ctx. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_core.c | 2 +- drivers/video/console_rotate.c | 6 +++--- drivers/video/console_truetype.c | 2 +- drivers/video/vidconsole-uclass.c | 10 +++++----- include/video_console.h | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 50f67ffcf83..18edc14bcd7 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -350,7 +350,7 @@ int console_fixed_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp, uchar *pfont = fontdata->video_fontdata + ch * fontdata->char_pixel_bytes; - if (x_frac + VID_TO_POS(ctx->x_charsize) > vc_priv->xsize_frac) + if (x_frac + VID_TO_POS(ctx->x_charsize) > ctx->xsize_frac) return -EAGAIN; linenum = y; x = VID_TO_PIXEL(x_frac); diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c index 85c571accd4..378c7ec6fc7 100644 --- a/drivers/video/console_rotate.c +++ b/drivers/video/console_rotate.c @@ -87,7 +87,7 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp) uchar *pfont = fontdata->video_fontdata + ch * fontdata->char_pixel_bytes; - if (x_frac + VID_TO_POS(ctx->x_charsize) > vc_priv->xsize_frac) + if (x_frac + VID_TO_POS(ctx->x_charsize) > ctx->xsize_frac) return -EAGAIN; linenum = VID_TO_PIXEL(x_frac) + 1; x = y + 1; @@ -176,7 +176,7 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp) uchar *pfont = fontdata->video_fontdata + ch * fontdata->char_pixel_bytes; - if (x_frac + VID_TO_POS(ctx->x_charsize) > vc_priv->xsize_frac) + if (x_frac + VID_TO_POS(ctx->x_charsize) > ctx->xsize_frac) return -EAGAIN; linenum = vid_priv->ysize - y - 1; x = vid_priv->xsize - VID_TO_PIXEL(x_frac) - 1; @@ -267,7 +267,7 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp) uchar *pfont = fontdata->video_fontdata + ch * fontdata->char_pixel_bytes; - if (x_frac + VID_TO_POS(ctx->x_charsize) > vc_priv->xsize_frac) + if (x_frac + VID_TO_POS(ctx->x_charsize) > ctx->xsize_frac) return -EAGAIN; x = y; linenum = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 9c7c116809b..a9553cc9a53 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -477,7 +477,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, x_shift = xpos - (double)tt_floor(xpos); xpos += advance * met->scale; width_frac = (int)VID_TO_POS((kern + advance) * met->scale); - if (x + width_frac >= vc_priv->xsize_frac) + if (x + width_frac >= vc_ctx->xsize_frac) return -EAGAIN; /* Write the current cursor position into history */ diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 414a33f7bf7..eda55fcf04e 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -476,7 +476,7 @@ static int vidconsole_output_glyph(struct udevice *dev, int ch) return ret; ctx->xcur_frac += ret; ctx->last_ch = ch; - if (ctx->xcur_frac >= priv->xsize_frac) + if (ctx->xcur_frac >= ctx->xsize_frac) vidconsole_newline(dev); cli_index_adjust(priv, 1); @@ -517,7 +517,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) ctx->xcur_frac = ((ctx->xcur_frac / ctx->tab_width_frac) + 1) * ctx->tab_width_frac; - if (ctx->xcur_frac >= priv->xsize_frac) + if (ctx->xcur_frac >= ctx->xsize_frac) vidconsole_newline(dev); break; case '\b': @@ -878,11 +878,11 @@ void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old) /* Set up the number of rows and colours (rotated drivers override this) */ static int vidconsole_pre_probe(struct udevice *dev) { - struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = vidconsole_ctx(dev); struct udevice *vid = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid); - priv->xsize_frac = VID_TO_POS(vid_priv->xsize); + ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); return 0; } @@ -978,7 +978,7 @@ void vidconsole_set_bitmap_font(struct udevice *dev, if (vid_priv->rot % 2) { ctx->cols = vid_priv->ysize / fontdata->width; ctx->rows = vid_priv->xsize / fontdata->height; - vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize); + ctx->xsize_frac = VID_TO_POS(vid_priv->ysize); } else { ctx->cols = vid_priv->xsize / fontdata->width; ctx->rows = vid_priv->ysize / fontdata->height; diff --git a/include/video_console.h b/include/video_console.h index ebba1ac7572..43b894048ed 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -115,6 +115,7 @@ struct vidconsole_ansi { * @curs: Cursor state and management * @xstart_frac: Left margin for the text console in fractional units * @tab_width_frac: Tab width in fractional units + * @xsize_frac: Width of the display in fractional units */ struct vidconsole_ctx { int rows; @@ -132,6 +133,7 @@ struct vidconsole_ctx { struct vidconsole_cursor curs; int xstart_frac; int tab_width_frac; + int xsize_frac; }; /** @@ -150,13 +152,11 @@ struct vidconsole_ctx { * * @sdev: stdio device, acting as an output sink * @ctx: Per-client context - * @xsize_frac: Width of the display in fractional units * @quiet: Suppress all output from stdio */ struct vidconsole_priv { struct stdio_dev sdev; struct vidconsole_ctx ctx; - int xsize_frac; bool quiet; }; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update expo_test_render() to use the vidconsole_ctx_from_priv() helper function instead of accessing the ctx field directly. This is more consistent with the rest of the codebase. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/expo_test.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/boot/expo_test.c b/boot/expo_test.c index a905b144745..a5ad571eedb 100644 --- a/boot/expo_test.c +++ b/boot/expo_test.c @@ -120,6 +120,7 @@ int expo_test_render(struct expo *exp) struct expo_test_mode *test = exp->test; struct vidconsole_priv *cons_priv; struct udevice *dev = exp->display; + struct vidconsole_ctx *ctx; struct video_priv *vid_priv; char buf[30]; ulong now; @@ -140,6 +141,7 @@ int expo_test_render(struct expo *exp) vid_priv = dev_get_uclass_priv(dev); cons_priv = dev_get_uclass_priv(exp->cons); + ctx = vidconsole_ctx_from_priv(cons_priv); /* Accumulate delta times for averaging */ test->render_total_us += test->render_delta_us; @@ -176,7 +178,7 @@ int expo_test_render(struct expo *exp) /* Display frame count */ snprintf(buf, sizeof(buf), "frame %6d", test->render_count); - x = vid_priv->xsize - 18 * cons_priv->ctx.x_charsize; + x = vid_priv->xsize - 18 * ctx->x_charsize; y = 10; vidconsole_set_cursor_pos(exp->cons, x, y); vidconsole_put_string(exp->cons, buf); @@ -184,7 +186,7 @@ int expo_test_render(struct expo *exp) /* Display FPS on next line (only if non-zero) */ if (test->fps_last > 0) { snprintf(buf, sizeof(buf), "fps %6d", test->fps_last); - y += cons_priv->ctx.y_charsize; + y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, x, y); vidconsole_put_string(exp->cons, buf); } @@ -193,7 +195,7 @@ int expo_test_render(struct expo *exp) snprintf(buf, sizeof(buf), "render %6lu.%01lums", test->render_avg_us / 1000, (test->render_avg_us % 1000) / 100); - y += cons_priv->ctx.y_charsize; + y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, x, y); vidconsole_put_string(exp->cons, buf); @@ -201,7 +203,7 @@ int expo_test_render(struct expo *exp) snprintf(buf, sizeof(buf), "sync %6lu.%01lums", test->sync_avg_us / 1000, (test->sync_avg_us % 1000) / 100); - y += cons_priv->ctx.y_charsize; + y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, x, y); vidconsole_put_string(exp->cons, buf); @@ -209,7 +211,7 @@ int expo_test_render(struct expo *exp) snprintf(buf, sizeof(buf), "poll %6lu.%01lums", test->poll_avg_us / 1000, (test->poll_avg_us % 1000) / 100); - y += cons_priv->ctx.y_charsize; + y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, x, y); vidconsole_put_string(exp->cons, buf); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Change cli_index_adjust() to take a struct vidconsole_ctx pointer instead of struct vidconsole_priv, since cli_index is now part of the context structure. Update all callers accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/vidconsole-uclass.c | 4 ++-- include/video_console.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index eda55fcf04e..ed9311bd05e 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -85,7 +85,7 @@ static int vidconsole_back(struct udevice *dev) ctx->ycur = 0; } assert(ctx->cli_index); - cli_index_adjust(priv, -1); + cli_index_adjust(ctx, -1); return video_sync(dev->parent, false); } @@ -478,7 +478,7 @@ static int vidconsole_output_glyph(struct udevice *dev, int ch) ctx->last_ch = ch; if (ctx->xcur_frac >= ctx->xsize_frac) vidconsole_newline(dev); - cli_index_adjust(priv, 1); + cli_index_adjust(ctx, 1); return 0; } diff --git a/include/video_console.h b/include/video_console.h index 43b894048ed..d3e8b3f3c9f 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -612,10 +612,10 @@ static inline void vidconsole_readline_end(void) } #endif /* CONFIG_CURSOR */ -static inline void cli_index_adjust(struct vidconsole_priv *priv, int by) +static inline void cli_index_adjust(struct vidconsole_ctx *ctx, int by) { if (CONFIG_IS_ENABLED(CURSOR)) - priv->ctx.cli_index += by; + ctx->cli_index += by; } /** -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a new struct vidconsole_uc_plat to hold uclass platform data for vidconsole devices. This includes ctx_size which allows drivers to specify the size of context data they need. This prepares for dynamic context allocation where drivers can have different sized contexts. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/vidconsole-uclass.c | 1 + include/video_console.h | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index ed9311bd05e..1ac8e2ddf3c 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -928,6 +928,7 @@ UCLASS_DRIVER(vidconsole) = { .post_probe = vidconsole_post_probe, .pre_remove = vidconsole_pre_remove, .per_device_auto = sizeof(struct vidconsole_priv), + .per_device_plat_auto = sizeof(struct vidconsole_uc_plat), }; int vidconsole_clear_and_reset(struct udevice *dev) diff --git a/include/video_console.h b/include/video_console.h index d3e8b3f3c9f..72bc0e5b0db 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -136,6 +136,19 @@ struct vidconsole_ctx { int xsize_frac; }; +/** + * struct vidconsole_uc_plat - uclass platform data for a vidconsole device + * + * This holds information that the uclass needs to know about each device. It + * is accessed using dev_get_uclass_plat(dev). + * + * @ctx_size: Size of context data needed by the driver, or 0 to use the + * default (sizeof(struct vidconsole_ctx)) + */ +struct vidconsole_uc_plat { + uint ctx_size; +}; + /** * struct vidconsole_priv - uclass-private data about a console device * -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a bind function to the truetype console driver that sets the ctx_size to sizeof(struct console_tt_ctx). This tells the uclass to allocate enough space for the driver's extended context structure, which includes the base vidconsole_ctx plus driver-specific fields for cursor position history. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index a9553cc9a53..faf10f2730b 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1375,10 +1375,20 @@ struct vidconsole_ops console_truetype_ops = { .mark_start = truetype_mark_start, }; +static int console_truetype_bind(struct udevice *dev) +{ + struct vidconsole_uc_plat *plat = dev_get_uclass_plat(dev); + + plat->ctx_size = sizeof(struct console_tt_ctx); + + return 0; +} + U_BOOT_DRIVER(vidconsole_truetype) = { .name = "vidconsole_tt", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_truetype_ops, + .bind = console_truetype_bind, .probe = console_truetype_probe, .remove = console_truetype_remove, .priv_auto = sizeof(struct console_tt_priv), -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Change the ctx field in vidconsole_priv from an embedded struct to a pointer, and allocate it dynamically in vidconsole_pre_probe(). The size is taken from the ctx_size field in vidconsole_uc_plat, falling back to sizeof(struct vidconsole_ctx) if ctx_size is 0 This allows drivers to specify a larger context size if they need to store additional per-context data beyond the base vidconsole_ctx. The context is freed in vidconsole_pre_remove() along with the cursor save data. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- board/atmel/common/video_display.c | 4 ++-- drivers/video/vidconsole-uclass.c | 18 +++++++++++++++--- include/video_console.h | 17 +++++++++-------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/board/atmel/common/video_display.c b/board/atmel/common/video_display.c index 4d6ac3a740e..55a49b45f16 100644 --- a/board/atmel/common/video_display.c +++ b/board/atmel/common/video_display.c @@ -68,8 +68,8 @@ int at91_video_show_board_info(void) priv = dev_get_uclass_priv(con); vidconsole_position_cursor(con, 0, (logo_info.logo_height + - priv->ctx.y_charsize - 1) / - priv->ctx.y_charsize); + priv->ctx->y_charsize - 1) / + priv->ctx->y_charsize); for (s = buf, i = 0; i < len; s++, i++) vidconsole_put_char(con, *s); diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 1ac8e2ddf3c..05426138b09 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -878,9 +878,18 @@ void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old) /* Set up the number of rows and colours (rotated drivers override this) */ static int vidconsole_pre_probe(struct udevice *dev) { - struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_uc_plat *plat = dev_get_uclass_plat(dev); + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct udevice *vid = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid); + struct vidconsole_ctx *ctx; + uint size; + + size = plat->ctx_size ?: sizeof(struct vidconsole_ctx); + ctx = calloc(1, size); + if (!ctx) + return -ENOMEM; + priv->ctx = ctx; ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); @@ -914,9 +923,12 @@ static int vidconsole_post_probe(struct udevice *dev) static int vidconsole_pre_remove(struct udevice *dev) { - struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = priv->ctx; free(ctx->curs.save_data); + free(ctx); + priv->ctx = NULL; return 0; } @@ -1036,5 +1048,5 @@ void *vidconsole_ctx(struct udevice *dev) { struct vidconsole_priv *uc_priv = dev_get_uclass_priv(dev); - return &uc_priv->ctx; + return uc_priv->ctx; } diff --git a/include/video_console.h b/include/video_console.h index 72bc0e5b0db..0e9784c8e3c 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -152,24 +152,25 @@ struct vidconsole_uc_plat { /** * struct vidconsole_priv - uclass-private data about a console device * - * Drivers must set up @ctx.rows, @ctx.cols, @ctx.x_charsize, @ctx.y_charsize - * in their probe() method. Drivers may set up @ctx.xstart_frac if desired. + * Drivers must set up @ctx->rows, @ctx->cols, @ctx->x_charsize, + * @ctx->y_charsize in their probe() method. Drivers may set up + * @ctx->xstart_frac if desired. * * 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 ctx.xcur_frac and ctx.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 + * The ctx->xcur_frac and ctx->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 - * @ctx: Per-client context + * @ctx: Per-client context (allocated by the uclass) * @quiet: Suppress all output from stdio */ struct vidconsole_priv { struct stdio_dev sdev; - struct vidconsole_ctx ctx; + struct vidconsole_ctx *ctx; bool quiet; }; @@ -461,7 +462,7 @@ void *vidconsole_ctx(struct udevice *dev); */ static inline void *vidconsole_ctx_from_priv(struct vidconsole_priv *uc_priv) { - return &uc_priv->ctx; + return uc_priv->ctx; } /** -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Now that vidconsole context is dynamically allocated and accessed via vidconsole_ctx(), remove the embedded ctx from console_tt_priv. Update console_tt_store to store console_tt_ctx directly instead of the entire priv structure. Also clean up functions to use vidconsole_ctx(dev) consistently and remove unused variable declarations. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 54 +++++++++++--------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index faf10f2730b..bafd35c2370 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -232,7 +232,6 @@ struct console_tt_ctx { * @metrics: List metrics that can be used * @num_metrics: Number of available metrics * @cur_fontdata: Current fixed font data (NULL if using TrueType) - * @ctx: Per-client context * @glyph_buf: Pre-allocated buffer for rendering glyphs. If a glyph fits, * this avoids malloc/free per character. Allocated lazily after * relocation to avoid using early malloc space. @@ -245,7 +244,6 @@ struct console_tt_priv { struct console_tt_metrics metrics[CONFIG_CONSOLE_TRUETYPE_MAX_METRICS]; int num_metrics; struct video_fontdata *cur_fontdata; - struct console_tt_ctx ctx; u8 *glyph_buf; int glyph_buf_size; struct stbtt_scratch scratch; @@ -255,11 +253,11 @@ struct console_tt_priv { /** * struct console_tt_store - Format used for save/restore of entry information * - * @priv: Private data + * @ctx: Per-client context * @cur: Current cursor position */ struct console_tt_store { - struct console_tt_priv priv; + struct console_tt_ctx ctx; struct pos_info cur; }; @@ -327,7 +325,7 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); struct vidconsole_ctx *com = vidconsole_ctx(dev); struct console_tt_priv *priv = dev_get_priv(dev); - struct console_tt_ctx *ctx = &priv->ctx; + struct console_tt_ctx *ctx = vidconsole_ctx(dev); void *dst; void *src; int i, diff, font_height; @@ -369,10 +367,8 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, static void clear_from(struct udevice *dev, int index) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *com = 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_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; struct udevice *vid_dev = dev->parent; struct pos_info *start_pos, *end_pos; int xstart, xend; @@ -419,7 +415,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); struct vidconsole_ctx *com = 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_ctx *ctx = vidconsole_ctx(dev); struct console_tt_metrics *met = priv->cur_met; stbtt_fontinfo *font; int width, height, xoff, yoff; @@ -477,7 +473,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, x_shift = xpos - (double)tt_floor(xpos); xpos += advance * met->scale; width_frac = (int)VID_TO_POS((kern + advance) * met->scale); - if (x + width_frac >= vc_ctx->xsize_frac) + if (x + width_frac >= com->xsize_frac) return -EAGAIN; /* Write the current cursor position into history */ @@ -682,11 +678,9 @@ 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 video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct vidconsole_ctx *com = 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_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; struct pos_info *pos; int xend; @@ -719,10 +713,8 @@ static int console_truetype_backspace(struct udevice *dev) static int console_truetype_entry_start(struct udevice *dev) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *com = 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_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; /* A new input line has start, so clear our history */ ctx->pos_ptr = 0; @@ -1184,23 +1176,18 @@ 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 *com = vidconsole_ctx_from_priv(vc_priv); - struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; struct console_tt_store store; const uint size = sizeof(store); if (xpl_phase() <= PHASE_SPL) return -ENOSYS; - /* - * store the whole priv structure as it is simpler that picking out - * what we need - */ if (!abuf_realloc(buf, size)) return log_msg_ret("sav", -ENOMEM); - store.priv = *priv; + store.ctx = *ctx; store.cur.xpos_frac = com->xcur_frac; store.cur.ypos = com->ycur; memcpy(abuf_data(buf), &store, size); @@ -1210,10 +1197,8 @@ 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 *com = 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_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; struct console_tt_store store; if (xpl_phase() <= PHASE_SPL) @@ -1223,7 +1208,7 @@ static int truetype_entry_restore(struct udevice *dev, struct abuf *buf) com->xcur_frac = store.cur.xpos_frac; com->ycur = store.cur.ypos; - *ctx = store.priv.ctx; + *ctx = store.ctx; return 0; } @@ -1233,7 +1218,7 @@ static int truetype_get_cursor_info(struct udevice *dev) struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); struct vidconsole_ctx *com = 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_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_cursor *curs = &com->curs; int x, y, index; uint height; @@ -1291,8 +1276,7 @@ const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep) static int truetype_mark_start(struct udevice *dev) { - struct console_tt_priv *priv = dev_get_priv(dev); - struct console_tt_ctx *ctx = &priv->ctx; + struct console_tt_ctx *ctx = vidconsole_ctx(dev); ctx->pos_start = ctx->pos_ptr; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update functions to use a consistent pattern for accessing vidconsole context: - Use vidconsole_ctx(dev) to get console_tt_ctx pointer - Get vidconsole_ctx via &ctx->com This removes usage of vidconsole_ctx_from_priv() and the intermediate vc_priv variable, simplifying the code. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index bafd35c2370..db9f89797bf 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -264,7 +264,8 @@ struct console_tt_store { static int console_truetype_set_row(struct udevice *dev, uint row, int clr) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct vidconsole_ctx *com = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; struct console_tt_priv *priv = dev_get_priv(dev); void *end, *line; int font_height; @@ -411,11 +412,10 @@ static void clear_from(struct udevice *dev, int index) 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 video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct vidconsole_ctx *com = vidconsole_ctx_from_priv(vc_priv); - struct console_tt_priv *priv = dev_get_priv(dev); struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; + struct console_tt_priv *priv = dev_get_priv(dev); struct console_tt_metrics *met = priv->cur_met; stbtt_fontinfo *font; int width, height, xoff, yoff; @@ -914,8 +914,8 @@ static struct console_tt_metrics *find_metrics(struct udevice *dev, static void set_bitmap_font(struct udevice *dev, struct video_fontdata *fontdata) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); + struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; struct console_tt_priv *priv = dev_get_priv(dev); priv->cur_fontdata = fontdata; @@ -923,13 +923,13 @@ static void set_bitmap_font(struct udevice *dev, vidconsole_set_bitmap_font(dev, fontdata); - ctx->tab_width_frac = VID_TO_POS(fontdata->width) * 8 / 2; + com->tab_width_frac = VID_TO_POS(fontdata->width) * 8 / 2; } static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *com = vidconsole_ctx_from_priv(vc_priv); + struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; struct console_tt_priv *priv = dev_get_priv(dev); struct udevice *vid_dev = dev_get_parent(dev); struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); @@ -1215,10 +1215,9 @@ 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 *com = vidconsole_ctx_from_priv(vc_priv); - struct console_tt_priv *priv = dev_get_priv(dev); struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; + struct console_tt_priv *priv = dev_get_priv(dev); struct vidconsole_cursor *curs = &com->curs; int x, y, index; uint height; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move the cur_met pointer from console_tt_priv to console_tt_ctx so that it can be tracked per-context rather than per-device. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index db9f89797bf..32d31b6d8cc 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -207,6 +207,7 @@ struct console_tt_metrics { * struct console_tt_ctx - Per-client context for this driver * * @com: Common fields from the vidconsole uclass + * @cur_met: Current metrics being used * @pos_ptr: Current position in the position history * @pos_start: Value of pos_ptr when the cursor is at the start of the text * being entered by the user @@ -219,6 +220,7 @@ struct console_tt_metrics { */ struct console_tt_ctx { struct vidconsole_ctx com; + struct console_tt_metrics *cur_met; int pos_ptr; int pos_start; int pos_count; @@ -228,7 +230,6 @@ struct console_tt_ctx { /** * struct console_tt_priv - Private data for this driver * - * @cur_met: Current metrics being used * @metrics: List metrics that can be used * @num_metrics: Number of available metrics * @cur_fontdata: Current fixed font data (NULL if using TrueType) @@ -240,7 +241,6 @@ struct console_tt_ctx { * @scratch_buf: Memory for scratch buffer */ struct console_tt_priv { - struct console_tt_metrics *cur_met; struct console_tt_metrics metrics[CONFIG_CONSOLE_TRUETYPE_MAX_METRICS]; int num_metrics; struct video_fontdata *cur_fontdata; @@ -274,7 +274,7 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr) if (priv->cur_fontdata) font_height = priv->cur_fontdata->height; else - font_height = priv->cur_met->font_size; + font_height = ctx->cur_met->font_size; line = vid_priv->fb + row * font_height * vid_priv->line_length; end = line + font_height * vid_priv->line_length; @@ -335,7 +335,7 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, if (priv->cur_fontdata) font_height = priv->cur_fontdata->height; else - font_height = priv->cur_met->font_size; + font_height = ctx->cur_met->font_size; dst = vid_priv->fb + rowdst * font_height * vid_priv->line_length; src = vid_priv->fb + rowsrc * font_height * vid_priv->line_length; @@ -416,7 +416,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_ctx *com = &ctx->com; struct console_tt_priv *priv = dev_get_priv(dev); - struct console_tt_metrics *met = priv->cur_met; + struct console_tt_metrics *met = ctx->cur_met; stbtt_fontinfo *font; int width, height, xoff, yoff; double xpos, x_shift; @@ -919,7 +919,7 @@ static void set_bitmap_font(struct udevice *dev, struct console_tt_priv *priv = dev_get_priv(dev); priv->cur_fontdata = fontdata; - priv->cur_met = NULL; + ctx->cur_met = NULL; vidconsole_set_bitmap_font(dev, fontdata); @@ -930,11 +930,10 @@ static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_ctx *com = &ctx->com; - struct console_tt_priv *priv = dev_get_priv(dev); struct udevice *vid_dev = dev_get_parent(dev); struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); - priv->cur_met = met; + ctx->cur_met = met; com->x_charsize = met->font_size; com->y_charsize = met->font_size; com->xstart_frac = VID_TO_POS(2); @@ -1245,7 +1244,7 @@ static int truetype_get_cursor_info(struct udevice *dev) if (priv->cur_fontdata) height = priv->cur_fontdata->height; else - height = priv->cur_met->font_size; + height = ctx->cur_met->font_size; /* Store line pointer and height in cursor struct */ curs->x = x; @@ -1258,6 +1257,7 @@ static int truetype_get_cursor_info(struct udevice *dev) const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep) { + struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct console_tt_priv *priv = dev_get_priv(dev); if (priv->cur_fontdata) { @@ -1266,7 +1266,7 @@ const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep) return priv->cur_fontdata->name; } else { /* Using TrueType font */ - struct console_tt_metrics *met = priv->cur_met; + struct console_tt_metrics *met = ctx->cur_met; *sizep = met->font_size; return met->font_name; @@ -1284,6 +1284,7 @@ static int truetype_mark_start(struct udevice *dev) static int console_truetype_probe(struct udevice *dev) { + struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct console_tt_priv *priv = dev_get_priv(dev); struct udevice *vid_dev = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); @@ -1316,7 +1317,7 @@ static int console_truetype_probe(struct udevice *dev) ret = truetype_add_metrics(dev, tab->name, font_size, tab->begin); if (ret < 0) return log_msg_ret("add", ret); - priv->cur_met = &priv->metrics[ret]; + ctx->cur_met = &priv->metrics[ret]; select_metrics(dev, &priv->metrics[ret]); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move the cur_fontdata pointer from console_tt_priv to console_tt_ctx so that it can be tracked per-context rather than per-device. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 38 ++++++++++++++------------------ 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 32d31b6d8cc..2ab4f7dcb25 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -221,6 +221,7 @@ struct console_tt_metrics { struct console_tt_ctx { struct vidconsole_ctx com; struct console_tt_metrics *cur_met; + struct video_fontdata *cur_fontdata; int pos_ptr; int pos_start; int pos_count; @@ -232,7 +233,6 @@ struct console_tt_ctx { * * @metrics: List metrics that can be used * @num_metrics: Number of available metrics - * @cur_fontdata: Current fixed font data (NULL if using TrueType) * @glyph_buf: Pre-allocated buffer for rendering glyphs. If a glyph fits, * this avoids malloc/free per character. Allocated lazily after * relocation to avoid using early malloc space. @@ -243,7 +243,6 @@ struct console_tt_ctx { struct console_tt_priv { struct console_tt_metrics metrics[CONFIG_CONSOLE_TRUETYPE_MAX_METRICS]; int num_metrics; - struct video_fontdata *cur_fontdata; u8 *glyph_buf; int glyph_buf_size; struct stbtt_scratch scratch; @@ -266,13 +265,12 @@ static int console_truetype_set_row(struct udevice *dev, uint row, int clr) struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_ctx *com = &ctx->com; - struct console_tt_priv *priv = dev_get_priv(dev); void *end, *line; int font_height; /* Get font height from current font type */ - if (priv->cur_fontdata) - font_height = priv->cur_fontdata->height; + if (ctx->cur_fontdata) + font_height = ctx->cur_fontdata->height; else font_height = ctx->cur_met->font_size; @@ -324,16 +322,15 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, uint rowsrc, uint count) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct vidconsole_ctx *com = vidconsole_ctx(dev); - struct console_tt_priv *priv = dev_get_priv(dev); struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *com = &ctx->com; void *dst; void *src; int i, diff, font_height; /* Get font height from current font type */ - if (priv->cur_fontdata) - font_height = priv->cur_fontdata->height; + if (ctx->cur_fontdata) + font_height = ctx->cur_fontdata->height; else font_height = ctx->cur_met->font_size; @@ -430,8 +427,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, bool use_buf; /* Use fixed font if selected */ - if (priv->cur_fontdata) - return console_fixed_putc_xy(dev, x, y, cp, priv->cur_fontdata); + if (ctx->cur_fontdata) + return console_fixed_putc_xy(dev, x, y, cp, ctx->cur_fontdata); /* Reset scratch buffer for this character */ stbtt_scratch_reset(&priv->scratch); @@ -916,9 +913,8 @@ static void set_bitmap_font(struct udevice *dev, { struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_ctx *com = &ctx->com; - struct console_tt_priv *priv = dev_get_priv(dev); - priv->cur_fontdata = fontdata; + ctx->cur_fontdata = fontdata; ctx->cur_met = NULL; vidconsole_set_bitmap_font(dev, fontdata); @@ -989,7 +985,7 @@ static int get_metrics(struct udevice *dev, const char *name, uint size, static int truetype_select_font(struct udevice *dev, const char *name, uint size) { - struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct console_tt_metrics *met; struct video_fontdata *fontdata; int ret; @@ -1006,7 +1002,7 @@ static int truetype_select_font(struct udevice *dev, const char *name, } /* Continue with TrueType font selection */ - priv->cur_fontdata = NULL; + ctx->cur_fontdata = NULL; ret = get_metrics(dev, name, size, &met); if (ret) return log_msg_ret("sel", ret); @@ -1216,7 +1212,6 @@ static int truetype_get_cursor_info(struct udevice *dev) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_ctx *com = &ctx->com; - struct console_tt_priv *priv = dev_get_priv(dev); struct vidconsole_cursor *curs = &com->curs; int x, y, index; uint height; @@ -1241,8 +1236,8 @@ static int truetype_get_cursor_info(struct udevice *dev) y = com->ycur; /* Get font height from current font type */ - if (priv->cur_fontdata) - height = priv->cur_fontdata->height; + if (ctx->cur_fontdata) + height = ctx->cur_fontdata->height; else height = ctx->cur_met->font_size; @@ -1258,12 +1253,11 @@ static int truetype_get_cursor_info(struct udevice *dev) const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); - struct console_tt_priv *priv = dev_get_priv(dev); - if (priv->cur_fontdata) { + if (ctx->cur_fontdata) { /* Using fixed font */ - *sizep = priv->cur_fontdata->height; - return priv->cur_fontdata->name; + *sizep = ctx->cur_fontdata->height; + return ctx->cur_fontdata->name; } else { /* Using TrueType font */ struct console_tt_metrics *met = ctx->cur_met; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The store.cur field is used to separately save xcur_frac and ycur, but these are already saved as part of store.ctx since console_tt_ctx contains vidconsole_ctx which has these fields. Additionally, the restore code is buggy - it sets com->xcur_frac and com->ycur, then immediately overwrites them with *ctx = store.ctx. Remove the redundant field and simplify the save/restore functions. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 2ab4f7dcb25..7b1540b6c40 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -253,11 +253,9 @@ struct console_tt_priv { * struct console_tt_store - Format used for save/restore of entry information * * @ctx: Per-client context - * @cur: Current cursor position */ struct console_tt_store { struct console_tt_ctx ctx; - struct pos_info cur; }; static int console_truetype_set_row(struct udevice *dev, uint row, int clr) @@ -1172,7 +1170,6 @@ static int truetype_ctx_dispose(struct udevice *dev, void *ctx) static int truetype_entry_save(struct udevice *dev, struct abuf *buf) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); - struct vidconsole_ctx *com = &ctx->com; struct console_tt_store store; const uint size = sizeof(store); @@ -1183,8 +1180,6 @@ static int truetype_entry_save(struct udevice *dev, struct abuf *buf) return log_msg_ret("sav", -ENOMEM); store.ctx = *ctx; - store.cur.xpos_frac = com->xcur_frac; - store.cur.ypos = com->ycur; memcpy(abuf_data(buf), &store, size); return 0; @@ -1193,16 +1188,12 @@ static int truetype_entry_save(struct udevice *dev, struct abuf *buf) static int truetype_entry_restore(struct udevice *dev, struct abuf *buf) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); - struct vidconsole_ctx *com = &ctx->com; struct console_tt_store store; if (xpl_phase() <= PHASE_SPL) return -ENOSYS; memcpy(&store, abuf_data(buf), sizeof(store)); - - com->xcur_frac = store.cur.xpos_frac; - com->ycur = store.cur.ypos; *ctx = store.ctx; return 0; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Now that console_tt_store only contains console_tt_ctx, remove the wrapper struct and save/restore console_tt_ctx directly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 7b1540b6c40..f73fb3e6595 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -249,15 +249,6 @@ struct console_tt_priv { char *scratch_buf; }; -/** - * struct console_tt_store - Format used for save/restore of entry information - * - * @ctx: Per-client context - */ -struct console_tt_store { - struct console_tt_ctx ctx; -}; - static int console_truetype_set_row(struct udevice *dev, uint row, int clr) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); @@ -1170,8 +1161,7 @@ static int truetype_ctx_dispose(struct udevice *dev, void *ctx) static int truetype_entry_save(struct udevice *dev, struct abuf *buf) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); - struct console_tt_store store; - const uint size = sizeof(store); + const uint size = sizeof(*ctx); if (xpl_phase() <= PHASE_SPL) return -ENOSYS; @@ -1179,8 +1169,7 @@ static int truetype_entry_save(struct udevice *dev, struct abuf *buf) if (!abuf_realloc(buf, size)) return log_msg_ret("sav", -ENOMEM); - store.ctx = *ctx; - memcpy(abuf_data(buf), &store, size); + memcpy(abuf_data(buf), ctx, size); return 0; } @@ -1188,13 +1177,11 @@ static int truetype_entry_save(struct udevice *dev, struct abuf *buf) static int truetype_entry_restore(struct udevice *dev, struct abuf *buf) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); - struct console_tt_store store; if (xpl_phase() <= PHASE_SPL) return -ENOSYS; - memcpy(&store, abuf_data(buf), sizeof(store)); - *ctx = store.ctx; + memcpy(ctx, abuf_data(buf), sizeof(*ctx)); return 0; } -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The console_store struct only saved a few fields from vidconsole_ctx. Since console_ctx contains vidconsole_ctx, save/restore the entire console_ctx directly instead. This is simpler and consistent with the truetype driver approach. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_normal.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 4854e953e58..fa9d496ef86 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -24,12 +24,6 @@ struct console_ctx { struct vidconsole_ctx com; }; -struct console_store { - int xpos_frac; - int ypos; - int cli_index; -}; - static int console_set_row(struct udevice *dev, uint row, int clr) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); @@ -149,10 +143,8 @@ static __maybe_unused int console_get_cursor_info(struct udevice *dev) 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); + struct console_ctx *ctx = vidconsole_ctx(dev); + const uint size = sizeof(*ctx); if (xpl_phase() <= PHASE_SPL) return -ENOSYS; @@ -160,10 +152,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 = ctx->xcur_frac; - store.ypos = ctx->ycur; - store.cli_index = ctx->cli_index; - memcpy(abuf_data(buf), &store, size); + memcpy(abuf_data(buf), ctx, size); return 0; } @@ -171,18 +160,12 @@ static __maybe_unused int normal_entry_save(struct udevice *dev, 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; + struct console_ctx *ctx = vidconsole_ctx(dev); if (xpl_phase() <= PHASE_SPL) return -ENOSYS; - memcpy(&store, abuf_data(buf), sizeof(store)); - - ctx->xcur_frac = store.xpos_frac; - ctx->ycur = store.ypos; - ctx->cli_index = store.cli_index; + memcpy(ctx, abuf_data(buf), sizeof(*ctx)); return 0; } -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add dm_test_video_entry_save() and dm_test_video_entry_save_tt() to directly test vidconsole_entry_save() and vidconsole_entry_restore() for both bitmap and truetype fonts. The tests verify that cursor position is correctly saved and restored. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/dm/video.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/dm/video.c b/test/dm/video.c index d3978f4b00c..97778a70559 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -1516,3 +1516,70 @@ static int dm_test_video_context_alloc(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_video_context_alloc, UTF_SCAN_PDATA | UTF_SCAN_FDT); + +/* Test vidconsole entry save/restore */ +static int check_entry_save(struct unit_test_state *uts, struct udevice *con) +{ + struct vidconsole_priv *priv; + struct vidconsole_ctx *ctx; + int xcur_frac, ycur; + struct abuf buf; + + priv = dev_get_uclass_priv(con); + ctx = priv->ctx; + + /* Move cursor to a known position */ + vidconsole_position_cursor(con, 5, 3); + xcur_frac = ctx->xcur_frac; + ycur = ctx->ycur; + + /* Save the state */ + abuf_init(&buf); + ut_assertok(vidconsole_entry_save(con, &buf)); + + /* Move cursor to a different position */ + vidconsole_position_cursor(con, 10, 7); + ut_assert(ctx->xcur_frac != xcur_frac || ctx->ycur != ycur); + + /* Restore the state */ + ut_assertok(vidconsole_entry_restore(con, &buf)); + + /* Verify cursor is back at saved position */ + ut_asserteq(xcur_frac, ctx->xcur_frac); + ut_asserteq(ycur, ctx->ycur); + + abuf_uninit(&buf); + + return 0; +} + +/* Test entry save/restore with bitmap font */ +static int dm_test_video_entry_save(struct unit_test_state *uts) +{ + struct udevice *dev, *con; + + ut_assertok(select_vidconsole(uts, "vidconsole0")); + ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, "8x16", 0)); + + ut_assertok(check_entry_save(uts, con)); + + return 0; +} +DM_TEST(dm_test_video_entry_save, UTF_SCAN_PDATA | UTF_SCAN_FDT); + +/* Test entry save/restore with truetype font */ +static int dm_test_video_entry_save_tt(struct unit_test_state *uts) +{ + struct udevice *dev, *con; + + ut_assertok(video_get_nologo(uts, &dev)); + ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); + ut_assertok(vidconsole_select_font(con, NULL, 30)); + + ut_assertok(check_entry_save(uts, con)); + + return 0; +} +DM_TEST(dm_test_video_entry_save_tt, UTF_SCAN_PDATA | UTF_SCAN_FDT); -- 2.43.0
participants (1)
-
Simon Glass