[PATCH 00/36] video: Add multiple-context support to vidconsole (part F)
From: Simon Glass <simon.glass@canonical.com> At present expo textline objects are handled in a rather ad-hoc manner. When a textline is 'opened', the text is written out using vidconsole and the state is saved in the scene. When the user types a character, the state is restored, the character is written to the vidconsole, then the state is saved again. It is basically using the command-editor code. If the user press Ctrl-A, a suitable number of backspaces are written to move the cursor to the start. If the user then inserts a character, the entire string is written out (which is probably undesirable) and then backspaces are written again. Typing into a lineedit shows the same characters on the text console. This approach was designed for the text console and extended into the vidconsole. It was further extended into expo as it is fairly simple and saves code space. However it is not really suitable for a textedit, which may have many lines of text and needs to support moving up and down through these lines. Ideally we would separate expo a little from the CLI editor. As a start towards resolving these problems, this series adds support for multiple, independent vidconsole contexts. This enables expo text-input objects to each have their own cursor position, font settings and CLI line state, allowing multiple text fields to operate independently on the same display. This series: - Adds a context parameter to vidconsole functions throughout the stack - Moves CLI line state into text-input objects for expo - Maintains a list of contexts in the vidconsole uclass - Centralises context allocation and freeing in the uclass This is preparation for supporting multiple text-input fields in the expo menu system, where each field needs independent cursor tracking. Size growth is approximately 300 bytes on Thumb2, for boards which enable command-line editing and expo. This series also includes a fix for LUKS in CI. Simon Glass (36): test: Fix LUKS device-name collision in CI environments video: Pass context to vidconsole_set_cursor_pos() video: Pass context to vidconsole_entry_start() cli: Split initial-text output from cli_cread_init() video: Add per-device vidconsole_readline_start/end() video: Pass context to vidconsole_readline_start/end() expo: Move and generalise scene_textline_send_key() expo: Add CLI line state to text-input objects expo: Use text-input CLI line state instead of scene's video: Pass context to backspace() method video: Pass context to vidconsole_newline/back() video: Pass context to console_fixed_putc_xy() video: Pass context to vidconsole_putc_xy() video: Pass context to vidconsole_output_glyph() video: Pass context to vidconsole_escape_char() video: Pass context to get_cursor_info() method video: Pass context to vidconsole_show/hide_cursor() video: Pass context to vidconsole_put_char() video: Pass context to vidconsole_put_string() et al video: Pass context to mark_start() method video: Pass context to select_font() method video: Pass context to select_metrics() video: Pass context to console_alloc_cursor() video: Pass context to vidconsole_set_bitmap_font() video: Pass context to set_bitmap_font() video: Pass context to console_set_font() video: Pass context to get_font_size() expo: Pass context to draw_string() expo: Pass context to scene_txt_render() expo: Pass context to scene_obj_render() expo: Pass context to scene_render_obj() video: Maintain a list of contexts in vidconsole video: Allocate the cursor in the uclass video: Pass a cursor pointer to console_alloc_cursor() video: Move context freeing to uclass video: Move context allocation from drivers to uclass board/atmel/common/video_display.c | 2 +- board/kosagi/novena/novena.c | 2 +- boot/expo_test.c | 22 +-- boot/scene.c | 83 +++++---- boot/scene_internal.h | 13 +- boot/scene_textline.c | 47 ----- boot/scene_txtin.c | 80 ++++++-- cmd/font.c | 6 +- cmd/video.c | 6 +- common/cli_readline.c | 16 +- common/splash.c | 2 +- drivers/video/console_core.c | 46 +++-- drivers/video/console_normal.c | 47 +---- drivers/video/console_rotate.c | 24 +-- drivers/video/console_truetype.c | 80 ++++---- drivers/video/vidconsole-uclass.c | 276 ++++++++++++++++++---------- drivers/video/vidconsole_internal.h | 49 ++++- include/cli.h | 12 ++ include/expo.h | 2 + include/video_console.h | 120 ++++++++---- test/boot/expo.c | 12 +- test/cmd/font.c | 6 +- test/dm/video.c | 114 ++++++------ test/py/tests/fs_helper.py | 7 +- 24 files changed, 621 insertions(+), 453 deletions(-) -- 2.43.0 base-commit: 6ffc40c796bef9ab0f4785ad978aebbcd883eec2 branch: expf
From: Simon Glass <simon.glass@canonical.com> In CI environments where process IDs are reused quickly, the LUKS device name (luks_test_<pid>) can collide with a stale device from a previous test run. This causes cryptsetup to fail with "Device already exists". Add a timestamp component to the device name to ensure uniqueness even when PIDs are reused. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- test/py/tests/fs_helper.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py index ccde6683534..269b1c2d10f 100644 --- a/test/py/tests/fs_helper.py +++ b/test/py/tests/fs_helper.py @@ -11,6 +11,7 @@ import shutil from subprocess import call, check_call, check_output, CalledProcessError, run from subprocess import DEVNULL import tempfile +import time class FsHelper: @@ -269,9 +270,11 @@ class FsHelper: 'kernel module is loaded and you have permission to use ' 'device-mapper. This is required for LUKS encryption tests.') - device_name = f'luks_test_{os.getpid()}' + # Use PID and timestamp for uniqueness in CI environments where PIDs + # get reused + device_name = f'luks_test_{os.getpid()}_{int(time.time() * 1000) % 100000}' - # Clean up any stale device with the same name + # Clean up any stale device with the same name (unlikely with timestamp) run(['sudo', 'cryptsetup', 'close', device_name], stdout=DEVNULL, stderr=DEVNULL, check=False) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to vidconsole_set_cursor_pos() to allow callers to specify which vidconsole context to use. If NULL is passed, the function falls back to using the default context from vidconsole_priv. This enables text-input objects to use their own context for cursor positioning. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/expo_test.c | 10 +++++----- boot/scene.c | 4 ++-- boot/scene_txtin.c | 2 +- cmd/video.c | 2 +- drivers/video/vidconsole-uclass.c | 6 +++--- include/video_console.h | 3 ++- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/boot/expo_test.c b/boot/expo_test.c index a5ad571eedb..ae4e70ceede 100644 --- a/boot/expo_test.c +++ b/boot/expo_test.c @@ -180,14 +180,14 @@ int expo_test_render(struct expo *exp) snprintf(buf, sizeof(buf), "frame %6d", test->render_count); x = vid_priv->xsize - 18 * ctx->x_charsize; y = 10; - vidconsole_set_cursor_pos(exp->cons, x, y); + vidconsole_set_cursor_pos(exp->cons, NULL, x, y); vidconsole_put_string(exp->cons, buf); /* Display FPS on next line (only if non-zero) */ if (test->fps_last > 0) { snprintf(buf, sizeof(buf), "fps %6d", test->fps_last); y += ctx->y_charsize; - vidconsole_set_cursor_pos(exp->cons, x, y); + vidconsole_set_cursor_pos(exp->cons, NULL, x, y); vidconsole_put_string(exp->cons, buf); } @@ -196,7 +196,7 @@ int expo_test_render(struct expo *exp) test->render_avg_us / 1000, (test->render_avg_us % 1000) / 100); y += ctx->y_charsize; - vidconsole_set_cursor_pos(exp->cons, x, y); + vidconsole_set_cursor_pos(exp->cons, NULL, x, y); vidconsole_put_string(exp->cons, buf); /* Display average sync time in milliseconds on next line */ @@ -204,7 +204,7 @@ int expo_test_render(struct expo *exp) test->sync_avg_us / 1000, (test->sync_avg_us % 1000) / 100); y += ctx->y_charsize; - vidconsole_set_cursor_pos(exp->cons, x, y); + vidconsole_set_cursor_pos(exp->cons, NULL, x, y); vidconsole_put_string(exp->cons, buf); /* Display average poll time in milliseconds on next line */ @@ -212,7 +212,7 @@ int expo_test_render(struct expo *exp) test->poll_avg_us / 1000, (test->poll_avg_us % 1000) / 100); y += ctx->y_charsize; - vidconsole_set_cursor_pos(exp->cons, x, y); + vidconsole_set_cursor_pos(exp->cons, NULL, x, y); vidconsole_put_string(exp->cons, buf); return 0; diff --git a/boot/scene.c b/boot/scene.c index 306625361b4..16814d53b65 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -685,7 +685,7 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, bbox.y1 = obj->bbox.y1; if (!mline) { - vidconsole_set_cursor_pos(cons, x, y); + vidconsole_set_cursor_pos(cons, NULL, x, y); draw_string(cons, str, strlen(str), obj->flags & SCENEOF_PASSWORD); } @@ -704,7 +704,7 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, y = obj->bbox.y0 + offset.yofs + mline->bbox.y0; if (y > bbox.y1) break; /* clip this line and any following */ - vidconsole_set_cursor_pos(cons, x, y); + vidconsole_set_cursor_pos(cons, NULL, x, y); draw_string(cons, str + mline->start, mline->len, obj->flags & SCENEOF_PASSWORD); } diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index d1aa24dac9f..fd7cefa1d5b 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -126,7 +126,7 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, if (!txt) return log_msg_ret("cur", -ENOENT); - vidconsole_set_cursor_pos(cons, txt->obj.bbox.x0, txt->obj.bbox.y0); + vidconsole_set_cursor_pos(cons, NULL, txt->obj.bbox.x0, txt->obj.bbox.y0); vidconsole_entry_start(cons); cli_cread_init(&scn->cls, abuf_data(&tin->buf), tin->line_chars); scn->cls.insert = true; diff --git a/cmd/video.c b/cmd/video.c index 4f00ffa2f77..5c228b48058 100644 --- a/cmd/video.c +++ b/cmd/video.c @@ -85,7 +85,7 @@ static int do_video_write(struct cmd_tbl *cmdtp, int flag, int argc, row = hextoul(colon + 1, NULL); if (use_pixels) - vidconsole_set_cursor_pos(dev, col, row); + vidconsole_set_cursor_pos(dev, NULL, col, row); else vidconsole_position_cursor(dev, col, row); diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 05426138b09..17366d2de40 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -130,10 +130,10 @@ static char *parsenum(char *s, int *num) return end; } -void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y) +void vidconsole_set_cursor_pos(struct udevice *dev, void *ctxp, int x, int y) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); + struct vidconsole_ctx *ctx = ctxp ? ctxp : vidconsole_ctx_from_priv(priv); /* Hide cursor at old position if it's visible */ vidconsole_hide_cursor(dev); @@ -964,7 +964,7 @@ void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row) x = min_t(short, col * ctx->x_charsize, vid_priv->xsize - 1); y = min_t(short, row * ctx->y_charsize, vid_priv->ysize - 1); - vidconsole_set_cursor_pos(dev, x, y); + vidconsole_set_cursor_pos(dev, NULL, x, y); } void vidconsole_set_quiet(struct udevice *dev, bool quiet) diff --git a/include/video_console.h b/include/video_console.h index 0e9784c8e3c..a91b2a510b4 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -774,10 +774,11 @@ int vidconsole_clear_and_reset(struct udevice *dev); * updated to the same position, so that a newline will return to @x * * @dev: video console device to update + * @ctx: vidconsole context to use, or NULL to use the default * @x: x position from left in pixels * @y: y position from top in pixels */ -void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y); +void vidconsole_set_cursor_pos(struct udevice *dev, void *ctx, int x, int y); /** * vidconsole_list_fonts() - List the available fonts -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to vidconsole_entry_start() to allow callers to specify which vidconsole context to use. If NULL is passed, the function falls back to using the default context from vidconsole_priv. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene_txtin.c | 2 +- drivers/video/console_truetype.c | 4 ++-- drivers/video/vidconsole-uclass.c | 14 ++++++++------ include/video_console.h | 6 ++++-- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index fd7cefa1d5b..4f9230f931d 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -127,7 +127,7 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, return log_msg_ret("cur", -ENOENT); vidconsole_set_cursor_pos(cons, NULL, txt->obj.bbox.x0, txt->obj.bbox.y0); - vidconsole_entry_start(cons); + vidconsole_entry_start(cons, NULL); cli_cread_init(&scn->cls, abuf_data(&tin->buf), tin->line_chars); scn->cls.insert = true; scn->cls.putch = scene_txtin_putch; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 98356de2fd2..106da0e086d 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -697,9 +697,9 @@ static int console_truetype_backspace(struct udevice *dev) return 0; } -static int console_truetype_entry_start(struct udevice *dev) +static int console_truetype_entry_start(struct udevice *dev, void *vctx) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vctx; struct vidconsole_ctx *com = &ctx->com; /* A new input line has start, so clear our history */ diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 17366d2de40..679d5d46f81 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -50,13 +50,15 @@ int vidconsole_set_row(struct udevice *dev, uint row, int clr) return ops->set_row(dev, row, clr); } -int vidconsole_entry_start(struct udevice *dev) +int vidconsole_entry_start(struct udevice *dev, void *ctx) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); + if (!ctx) + ctx = vidconsole_ctx_from_priv(dev_get_uclass_priv(dev)); if (!ops->entry_start) return -ENOSYS; - return ops->entry_start(dev); + return ops->entry_start(dev, ctx); } /* Move backwards one space */ @@ -130,10 +132,10 @@ static char *parsenum(char *s, int *num) return end; } -void vidconsole_set_cursor_pos(struct udevice *dev, void *ctxp, int x, int y) +void vidconsole_set_cursor_pos(struct udevice *dev, void *vctx, int x, int y) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = ctxp ? ctxp : vidconsole_ctx_from_priv(priv); + struct vidconsole_ctx *ctx = vctx ? vctx : vidconsole_ctx_from_priv(priv); /* Hide cursor at old position if it's visible */ vidconsole_hide_cursor(dev); @@ -144,7 +146,7 @@ void vidconsole_set_cursor_pos(struct udevice *dev, void *ctxp, int x, int y) /* make sure not to kern against the previous character */ ctx->last_ch = 0; - vidconsole_entry_start(dev); + vidconsole_entry_start(dev, NULL); } /** @@ -511,7 +513,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) break; case '\n': vidconsole_newline(dev); - vidconsole_entry_start(dev); + vidconsole_entry_start(dev, NULL); break; case '\t': /* Tab (8 chars alignment) */ ctx->xcur_frac = ((ctx->xcur_frac / ctx->tab_width_frac) diff --git a/include/video_console.h b/include/video_console.h index a91b2a510b4..bb0445dc7c9 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -278,6 +278,7 @@ struct vidconsole_ops { * entry_start() - Indicate that text entry is starting afresh * * @dev: Device to adjust + * @ctx: Vidconsole context to use * Returns: 0 on success, -ve on error * * Consoles which use proportional fonts need to track the position of @@ -287,7 +288,7 @@ struct vidconsole_ops { * command). The driver can use this signal to empty its list of * positions. */ - int (*entry_start)(struct udevice *dev); + int (*entry_start)(struct udevice *dev, void *ctx); /** * backspace() - Handle erasing the last character @@ -695,8 +696,9 @@ int vidconsole_set_row(struct udevice *dev, uint row, int clr); * Marks the current cursor position as the start of a line * * @dev: Device to adjust + * @ctx: vidconsole context to use, or NULL to use the default */ -int vidconsole_entry_start(struct udevice *dev); +int vidconsole_entry_start(struct udevice *dev, void *ctx); /** * vidconsole_put_char() - Output a character to the current console position -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move the initial-text output from cli_cread_init() into a new function cli_cread_add_initial(). This allows callers to set up additional state (like the putch callback) before the initial text is output. Update cread_line() and scene_txtin_open() to call the new function. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene_txtin.c | 1 + common/cli_readline.c | 12 ++++++++---- include/cli.h | 10 ++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index 4f9230f931d..b5413dc145f 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -131,6 +131,7 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, cli_cread_init(&scn->cls, abuf_data(&tin->buf), tin->line_chars); scn->cls.insert = true; scn->cls.putch = scene_txtin_putch; + cli_cread_add_initial(&scn->cls); ret = vidconsole_entry_save(cons, &scn->entry_save); if (ret) return log_msg_ret("sav", ret); diff --git a/common/cli_readline.c b/common/cli_readline.c index 4eb34d7cf7c..0173072109b 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -470,16 +470,19 @@ int cread_line_process_ch(struct cli_line_state *cls, char ichar) void cli_cread_init(struct cli_line_state *cls, char *buf, uint buf_size) { - int init_len = strlen(buf); - memset(cls, '\0', sizeof(struct cli_line_state)); cls->insert = true; cls->buf = buf; cls->len = buf_size; +} + +void cli_cread_add_initial(struct cli_line_state *cls) +{ + int init_len = strlen(cls->buf); if (init_len) - cread_add_str(cls, buf, init_len, 0, &cls->num, &cls->eol_num, - buf, buf_size); + cread_add_str(cls, cls->buf, init_len, 0, &cls->num, + &cls->eol_num, cls->buf, cls->len); } static int cread_line(const char *const prompt, char *buf, unsigned int *len, @@ -492,6 +495,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len, cli_ch_init(cch); cli_cread_init(cls, buf, *len); + cli_cread_add_initial(cls); cls->prompt = prompt; cls->history = true; cls->cmd_complete = true; diff --git a/include/cli.h b/include/cli.h index 88f96c03cb3..ec0f5d31046 100644 --- a/include/cli.h +++ b/include/cli.h @@ -279,6 +279,16 @@ int cread_line_process_ch(struct cli_line_state *cls, char ichar); */ void cli_cread_init(struct cli_line_state *cls, char *buf, uint buf_size); +/** + * cli_cread_add_initial() - Output initial buffer contents + * + * Called after cli_cread_init() to output the initial text in the buffer and + * set up the line state accordingly + * + * @cls: CLI line state + */ +void cli_cread_add_initial(struct cli_line_state *cls); + /** cread_print_hist_list() - Print the command-line history list */ void cread_print_hist_list(void); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add vidconsole_readline_start() and vidconsole_readline_end() functions that operate on a single device. Rename the existing functions that iterate all consoles to have an _all suffix. Update scene_txtin.c to use the per-device versions with the expo's console, and cli_readline.c to use the _all versions. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene_txtin.c | 4 ++-- common/cli_readline.c | 4 ++-- drivers/video/vidconsole-uclass.c | 36 +++++++++++++++++----------- include/video_console.h | 39 ++++++++++++++++++++++++++----- 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index b5413dc145f..2b72ecaed39 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -107,7 +107,7 @@ static void scene_txtin_putch(struct cli_line_state *cls, int ch) void scene_txtin_close(struct scene *scn) { /* cursor is not needed now */ - vidconsole_readline_end(); + vidconsole_readline_end(scn->expo->cons); } int scene_txtin_open(struct scene *scn, struct scene_obj *obj, @@ -137,7 +137,7 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, return log_msg_ret("sav", ret); /* make sure the cursor is visible */ - vidconsole_readline_start(true); + vidconsole_readline_start(cons, true); return 0; } diff --git a/common/cli_readline.c b/common/cli_readline.c index 0173072109b..27fecd835a0 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -710,7 +710,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, puts(prompt); /* tell the vidconsole the cursor is at its start position */ - vidconsole_readline_start(false); + vidconsole_readline_start_all(false); rc = cread_line(prompt, p, &len, timeout); rc = rc < 0 ? rc : len; @@ -721,7 +721,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, pager_set_bypass(gd_pager(), old_bypass); pager_reset(gd_pager()); - vidconsole_readline_end(); + vidconsole_readline_end_all(); return rc; } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 679d5d46f81..200bc60c55b 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -1019,30 +1019,38 @@ void vidconsole_idle(struct udevice *dev) } #ifdef CONFIG_CURSOR -void vidconsole_readline_start(bool indent) +void vidconsole_readline_start(struct udevice *dev, bool indent) { - struct uclass *uc; - struct udevice *dev; + struct vidconsole_ctx *ctx = vidconsole_ctx(dev); - uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) { - struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + ctx->curs.indent = indent; + ctx->curs.enabled = true; + vidconsole_mark_start(dev); +} - ctx->curs.indent = indent; - ctx->curs.enabled = true; - vidconsole_mark_start(dev); - } +void vidconsole_readline_end(struct udevice *dev) +{ + struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + + ctx->curs.enabled = false; } -void vidconsole_readline_end(void) +void vidconsole_readline_start_all(bool indent) { struct uclass *uc; struct udevice *dev; - uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) { - struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) + vidconsole_readline_start(dev, indent); +} - ctx->curs.enabled = false; - } +void vidconsole_readline_end_all(void) +{ + struct uclass *uc; + struct udevice *dev; + + uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) + vidconsole_readline_end(dev); } #endif /* CURSOR */ diff --git a/include/video_console.h b/include/video_console.h index bb0445dc7c9..663f89b25f2 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -591,22 +591,41 @@ int vidconsole_show_cursor(struct udevice *dev); int vidconsole_hide_cursor(struct udevice *dev); /** - * vidconsole_readline_start() - Enable cursor for all video consoles + * vidconsole_readline_start() - Enable cursor for a video console + * + * Called at the start of command line input to show the cursor + * + * @dev: vidconsole device + * @indent: indent subsequent lines to the same position as the first line + */ +void vidconsole_readline_start(struct udevice *dev, bool indent); + +/** + * vidconsole_readline_end() - Disable cursor for a video console + * + * Called at the end of command line input to hide the cursor + * + * @dev: vidconsole device + */ +void vidconsole_readline_end(struct udevice *dev); + +/** + * vidconsole_readline_start_all() - Enable cursor for all video consoles * * Called at the start of command line input to show cursors on all * active video consoles * * @indent: indent subsequent lines to the same position as the first line */ -void vidconsole_readline_start(bool indent); +void vidconsole_readline_start_all(bool indent); /** - * vidconsole_readline_end() - Disable cursor for all video consoles + * vidconsole_readline_end_all() - Disable cursor for all video consoles * * Called at the end of command line input to hide cursors on all * active video consoles */ -void vidconsole_readline_end(void); +void vidconsole_readline_end_all(void); #else static inline int vidconsole_show_cursor(struct udevice *dev) { @@ -618,11 +637,19 @@ static inline int vidconsole_hide_cursor(struct udevice *dev) return 0; } -static inline void vidconsole_readline_start(bool indent) +static inline void vidconsole_readline_start(struct udevice *dev, bool indent) +{ +} + +static inline void vidconsole_readline_end(struct udevice *dev) +{ +} + +static inline void vidconsole_readline_start_all(bool indent) { } -static inline void vidconsole_readline_end(void) +static inline void vidconsole_readline_end_all(void) { } #endif /* CONFIG_CURSOR */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a vctx parameter to vidconsole_readline_start() and vidconsole_readline_end() to allow callers to specify which vidconsole context to use. If NULL is passed, the function falls back to using the default context from the device. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene_txtin.c | 4 ++-- drivers/video/vidconsole-uclass.c | 12 ++++++------ include/video_console.h | 13 ++++++++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index 2b72ecaed39..3944bce9a96 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -107,7 +107,7 @@ static void scene_txtin_putch(struct cli_line_state *cls, int ch) void scene_txtin_close(struct scene *scn) { /* cursor is not needed now */ - vidconsole_readline_end(scn->expo->cons); + vidconsole_readline_end(scn->expo->cons, NULL); } int scene_txtin_open(struct scene *scn, struct scene_obj *obj, @@ -137,7 +137,7 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, return log_msg_ret("sav", ret); /* make sure the cursor is visible */ - vidconsole_readline_start(cons, true); + vidconsole_readline_start(cons, NULL, true); return 0; } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 200bc60c55b..ca21cb8154f 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -1019,18 +1019,18 @@ void vidconsole_idle(struct udevice *dev) } #ifdef CONFIG_CURSOR -void vidconsole_readline_start(struct udevice *dev, bool indent) +void vidconsole_readline_start(struct udevice *dev, void *vctx, bool indent) { - struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *ctx = vctx ?: vidconsole_ctx(dev); ctx->curs.indent = indent; ctx->curs.enabled = true; vidconsole_mark_start(dev); } -void vidconsole_readline_end(struct udevice *dev) +void vidconsole_readline_end(struct udevice *dev, void *vctx) { - struct vidconsole_ctx *ctx = vidconsole_ctx(dev); + struct vidconsole_ctx *ctx = vctx ?: vidconsole_ctx(dev); ctx->curs.enabled = false; } @@ -1041,7 +1041,7 @@ void vidconsole_readline_start_all(bool indent) struct udevice *dev; uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) - vidconsole_readline_start(dev, indent); + vidconsole_readline_start(dev, NULL, indent); } void vidconsole_readline_end_all(void) @@ -1050,7 +1050,7 @@ void vidconsole_readline_end_all(void) struct udevice *dev; uclass_id_foreach_dev(UCLASS_VIDEO_CONSOLE, dev, uc) - vidconsole_readline_end(dev); + vidconsole_readline_end(dev, NULL); } #endif /* CURSOR */ diff --git a/include/video_console.h b/include/video_console.h index 663f89b25f2..c6cc050e054 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -278,7 +278,7 @@ struct vidconsole_ops { * entry_start() - Indicate that text entry is starting afresh * * @dev: Device to adjust - * @ctx: Vidconsole context to use + * @ctx: Vidconsole context to use (cannot be NULL) * Returns: 0 on success, -ve on error * * Consoles which use proportional fonts need to track the position of @@ -596,9 +596,10 @@ int vidconsole_hide_cursor(struct udevice *dev); * Called at the start of command line input to show the cursor * * @dev: vidconsole device + * @vctx: vidconsole context to use, or NULL to use the default * @indent: indent subsequent lines to the same position as the first line */ -void vidconsole_readline_start(struct udevice *dev, bool indent); +void vidconsole_readline_start(struct udevice *dev, void *vctx, bool indent); /** * vidconsole_readline_end() - Disable cursor for a video console @@ -606,8 +607,9 @@ void vidconsole_readline_start(struct udevice *dev, bool indent); * Called at the end of command line input to hide the cursor * * @dev: vidconsole device + * @vctx: vidconsole context to use, or NULL to use the default */ -void vidconsole_readline_end(struct udevice *dev); +void vidconsole_readline_end(struct udevice *dev, void *vctx); /** * vidconsole_readline_start_all() - Enable cursor for all video consoles @@ -637,11 +639,12 @@ static inline int vidconsole_hide_cursor(struct udevice *dev) return 0; } -static inline void vidconsole_readline_start(struct udevice *dev, bool indent) +static inline void vidconsole_readline_start(struct udevice *dev, void *vctx, + bool indent) { } -static inline void vidconsole_readline_end(struct udevice *dev) +static inline void vidconsole_readline_end(struct udevice *dev, void *vctx) { } -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move scene_textline_send_key() from scene_textline.c to scene_txtin.c and rename it to scene_txtin_send_key(). Change the signature to take a scene_obj and scene_txtin instead of scene_obj_textline, allowing it to be used for both textline and textedit objects. The scene is now obtained from obj->scene rather than being passed as a separate parameter. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene.c | 22 +++++++------------ boot/scene_internal.h | 10 ++++----- boot/scene_textline.c | 47 ----------------------------------------- boot/scene_txtin.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 66 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index 16814d53b65..2627335c0e8 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -1176,27 +1176,21 @@ int scene_send_key(struct scene *scn, int key, struct expo_action *event) return log_msg_ret("key", ret); break; } - case SCENEOBJT_TEXTLINE: { - struct scene_obj_textline *tline; - - tline = (struct scene_obj_textline *)cur, - ret = scene_textline_send_key(scn, tline, key, event); + case SCENEOBJT_TEXTLINE: + case SCENEOBJT_TEXTEDIT: + ret = scene_txtin_send_key(cur, scene_obj_txtin(cur), + key, event); if (ret) return log_msg_ret("key", ret); break; } - case SCENEOBJT_TEXTEDIT: - /* TODO(sjg@chromium.org): Implement this */ - break; - } return 0; } - if (cur && cur->type == SCENEOBJT_TEXTLINE) { - struct scene_obj_textline *tline; - - tline = (struct scene_obj_textline *)cur; - ret = scene_textline_send_key(scn, tline, key, event); + if (cur && (cur->type == SCENEOBJT_TEXTLINE || + cur->type == SCENEOBJT_TEXTEDIT)) { + ret = scene_txtin_send_key(cur, scene_obj_txtin(cur), + key, event); if (ret) return log_msg_ret("key", ret); return 0; diff --git a/boot/scene_internal.h b/boot/scene_internal.h index e732650b99f..733f0c0f6ca 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -227,16 +227,16 @@ int scene_menu_send_click(struct scene *scn, struct scene_obj_menu *menu, int x, int y, struct expo_action *event); /** - * scene_textline_send_key() - Send a key to a textline for processing + * scene_txtin_send_key() - Send a key to a text-input object for processing * - * @scn: Scene to use - * @tline: textline to use + * @obj: Object to use + * @tin: Text-input info * @key: Key code to send (KEY_...) * @event: Place to put any event which is generated by the key * Returns: 0 if OK (always) */ -int scene_textline_send_key(struct scene *scn, struct scene_obj_textline *tline, - int key, struct expo_action *event); +int scene_txtin_send_key(struct scene_obj *obj, struct scene_txtin *tin, + int key, struct expo_action *event); /** * scene_menu_destroy() - Destroy a menu in a scene diff --git a/boot/scene_textline.c b/boot/scene_textline.c index 9b5c40462fd..304a6d914cd 100644 --- a/boot/scene_textline.c +++ b/boot/scene_textline.c @@ -98,53 +98,6 @@ int scene_textline_arrange(struct scene *scn, struct expo_arrange_info *arr, return 0; } -int scene_textline_send_key(struct scene *scn, struct scene_obj_textline *tline, - int key, struct expo_action *event) -{ - const bool open = tline->obj.flags & SCENEOF_OPEN; - - log_debug("key=%d\n", key); - switch (key) { - case BKEY_QUIT: - if (open) { - event->type = EXPOACT_CLOSE; - event->select.id = tline->obj.id; - - /* Copy the backup text from the scene buffer */ - memcpy(abuf_data(&tline->tin.buf), abuf_data(&scn->buf), - abuf_size(&scn->buf)); - - scene_txtin_close(scn); - } else { - event->type = EXPOACT_QUIT; - log_debug("menu quit\n"); - } - break; - case BKEY_SELECT: - if (!open) - break; - event->type = EXPOACT_CLOSE; - event->select.id = tline->obj.id; - key = '\n'; - fallthrough; - default: { - struct udevice *cons = scn->expo->cons; - int ret; - - ret = vidconsole_entry_restore(cons, &scn->entry_save); - if (ret) - return log_msg_ret("sav", ret); - ret = cread_line_process_ch(&scn->cls, key); - ret = vidconsole_entry_save(cons, &scn->entry_save); - if (ret) - return log_msg_ret("sav", ret); - break; - } - } - - return 0; -} - bool scene_textline_within(const struct scene *scn, struct scene_obj_textline *tline, int x, int y) { diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index 3944bce9a96..d08b9e4ff0f 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -8,6 +8,7 @@ #define LOG_CATEGORY LOGC_EXPO +#include <cli.h> #include <expo.h> #include <log.h> #include <menu.h> @@ -157,3 +158,51 @@ void scene_txtin_calc_bbox(struct scene_obj *obj, struct scene_txtin *tin, edit_bbox->valid = false; scene_bbox_union(scn, tin->edit_id, inset, edit_bbox); } + +int scene_txtin_send_key(struct scene_obj *obj, struct scene_txtin *tin, + int key, struct expo_action *event) +{ + const bool open = obj->flags & SCENEOF_OPEN; + struct scene *scn = obj->scene; + + log_debug("key=%d\n", key); + switch (key) { + case BKEY_QUIT: + if (open) { + event->type = EXPOACT_CLOSE; + event->select.id = obj->id; + + /* Copy the backup text from the scene buffer */ + memcpy(abuf_data(&tin->buf), abuf_data(&scn->buf), + abuf_size(&scn->buf)); + + scene_txtin_close(scn); + } else { + event->type = EXPOACT_QUIT; + log_debug("menu quit\n"); + } + break; + case BKEY_SELECT: + if (!open) + break; + event->type = EXPOACT_CLOSE; + event->select.id = obj->id; + key = '\n'; + fallthrough; + default: { + struct udevice *cons = scn->expo->cons; + int ret; + + ret = vidconsole_entry_restore(cons, &scn->entry_save); + if (ret) + return log_msg_ret("sav", ret); + ret = cread_line_process_ch(&scn->cls, key); + ret = vidconsole_entry_save(cons, &scn->entry_save); + if (ret) + return log_msg_ret("sav", ret); + break; + } + } + + return 0; +} -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a struct cli_line_state member to struct scene_txtin to hold the line-editing state for each text-input object. This allows each object to maintain its own editing context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- include/expo.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/expo.h b/include/expo.h index 248f2363fe1..afaf1e8d107 100644 --- a/include/expo.h +++ b/include/expo.h @@ -509,12 +509,14 @@ struct scene_menitem { * @edit_id: ID of the editable text object (not string ID) * @line_chars: Nominal number of characters in a line * @buf: Text buffer containing current text + * @cls: CLI line state for text editing */ struct scene_txtin { uint label_id; uint edit_id; uint line_chars; struct abuf buf; + struct cli_line_state cls; }; /** -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update scene_txtin to use tin->cls instead of scn->cls, so that each text-input object maintains its own CLI line-editing state. Add a priv pointer to struct cli_line_state so the putch callback can access the scene without using container_of. This is necessary because the cls is now embedded in scene_txtin rather than scene. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene_txtin.c | 18 +++++++++++------- include/cli.h | 2 ++ test/boot/expo.c | 12 ++++++------ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index d08b9e4ff0f..296b2fb1a1b 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -63,6 +63,7 @@ int scene_txtin_arrange(struct scene *scn, struct expo_arrange_info *arr, int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj, struct scene_txtin *tin) { + struct cli_line_state *cls = &tin->cls; const bool open = obj->flags & SCENEOF_OPEN; struct udevice *cons = scn->expo->cons; uint i; @@ -77,7 +78,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj, scene_render_obj(scn, tin->edit_id); /* move cursor back to the correct position */ - for (i = scn->cls.num; i < scn->cls.eol_num; i++) + for (i = cls->num; i < cls->eol_num; i++) vidconsole_put_char(cons, '\b'); ret = vidconsole_entry_save(cons, &scn->entry_save); if (ret) @@ -100,7 +101,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj, */ static void scene_txtin_putch(struct cli_line_state *cls, int ch) { - struct scene *scn = container_of(cls, struct scene, cls); + struct scene *scn = cls->priv; vidconsole_put_char(scn->expo->cons, ch); } @@ -114,6 +115,7 @@ void scene_txtin_close(struct scene *scn) int scene_txtin_open(struct scene *scn, struct scene_obj *obj, struct scene_txtin *tin) { + struct cli_line_state *cls = &tin->cls; struct udevice *cons = scn->expo->cons; struct scene_obj_txt *txt; int ret; @@ -129,10 +131,11 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, vidconsole_set_cursor_pos(cons, NULL, txt->obj.bbox.x0, txt->obj.bbox.y0); vidconsole_entry_start(cons, NULL); - cli_cread_init(&scn->cls, abuf_data(&tin->buf), tin->line_chars); - scn->cls.insert = true; - scn->cls.putch = scene_txtin_putch; - cli_cread_add_initial(&scn->cls); + cli_cread_init(cls, abuf_data(&tin->buf), tin->line_chars); + cls->insert = true; + cls->putch = scene_txtin_putch; + cls->priv = scn; + cli_cread_add_initial(cls); ret = vidconsole_entry_save(cons, &scn->entry_save); if (ret) return log_msg_ret("sav", ret); @@ -162,6 +165,7 @@ void scene_txtin_calc_bbox(struct scene_obj *obj, struct scene_txtin *tin, int scene_txtin_send_key(struct scene_obj *obj, struct scene_txtin *tin, int key, struct expo_action *event) { + struct cli_line_state *cls = &tin->cls; const bool open = obj->flags & SCENEOF_OPEN; struct scene *scn = obj->scene; @@ -196,7 +200,7 @@ int scene_txtin_send_key(struct scene_obj *obj, struct scene_txtin *tin, ret = vidconsole_entry_restore(cons, &scn->entry_save); if (ret) return log_msg_ret("sav", ret); - ret = cread_line_process_ch(&scn->cls, key); + ret = cread_line_process_ch(cls, key); ret = vidconsole_entry_save(cons, &scn->entry_save); if (ret) return log_msg_ret("sav", ret); diff --git a/include/cli.h b/include/cli.h index ec0f5d31046..a02e228bf8a 100644 --- a/include/cli.h +++ b/include/cli.h @@ -37,6 +37,7 @@ struct cli_ch_state { * @buf: Buffer containing line * @prompt: Prompt for the line * @putch: Function to call to output a character (NULL to use putc()) + * @priv: Private data for putch callback */ struct cli_line_state { uint num; @@ -48,6 +49,7 @@ struct cli_line_state { char *buf; const char *prompt; void (*putch)(struct cli_line_state *cls, int ch); + void *priv; }; /** diff --git a/test/boot/expo.c b/test/boot/expo.c index d7430dc4284..f94927eb6b7 100644 --- a/test/boot/expo.c +++ b/test/boot/expo.c @@ -1481,8 +1481,8 @@ static int expo_render_textline(struct unit_test_state *uts) ut_assertok(expo_send_key(exp, CTL_CH('b'))); /* check cursor moved back one position, before 'a' */ - ut_asserteq(14, scn->cls.num); - ut_asserteq(15, scn->cls.eol_num); + ut_asserteq(14, tline->tin.cls.num); + ut_asserteq(15, tline->tin.cls.eol_num); ut_asserteq_str("sample hopwinda", abuf_data(&tline->tin.buf)); ut_assertok(scene_arrange(scn)); ut_assertok(expo_render(exp)); @@ -1493,8 +1493,8 @@ static int expo_render_textline(struct unit_test_state *uts) ut_assertok(expo_send_key(exp, CTL_CH('b'))); /* check cursor moved back three more positions, before 'i' */ - ut_asserteq(11, scn->cls.num); - ut_asserteq(15, scn->cls.eol_num); + ut_asserteq(11, tline->tin.cls.num); + ut_asserteq(15, tline->tin.cls.eol_num); ut_asserteq_str("sample hopwinda", abuf_data(&tline->tin.buf)); ut_assertok(scene_arrange(scn)); ut_assertok(expo_render(exp)); @@ -1504,8 +1504,8 @@ static int expo_render_textline(struct unit_test_state *uts) ut_assertok(expo_send_key(exp, CTL_CH('d'))); /* check character deleted at cursor position */ - ut_asserteq(11, scn->cls.num); - ut_asserteq(14, scn->cls.eol_num); + ut_asserteq(11, tline->tin.cls.num); + ut_asserteq(14, tline->tin.cls.eol_num); ut_asserteq_str("sample hopwnda", abuf_data(&tline->tin.buf)); ut_assertok(scene_arrange(scn)); ut_assertok(expo_render(exp)); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The backspace() driver method currently uses the default context. Update it to accept a context parameter so callers can specify which context to use for the backspace operation. This is needed for text-input objects which have their own vidconsole context. 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 | 10 ++++------ include/video_console.h | 3 ++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 106da0e086d..519b8f88843 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -660,12 +660,13 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, * not been entered. * * @dev: Device to update + * @vctx: Vidconsole context to use * Return: 0 if OK, -ENOSYS if not supported */ -static int console_truetype_backspace(struct udevice *dev) +static int console_truetype_backspace(struct udevice *dev, void *vctx) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vctx; struct vidconsole_ctx *com = &ctx->com; struct pos_info *pos; int xend; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index ca21cb8154f..8590219ae64 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -61,16 +61,14 @@ int vidconsole_entry_start(struct udevice *dev, void *ctx) return ops->entry_start(dev, ctx); } -/* Move backwards one space */ -static int vidconsole_back(struct udevice *dev) +/* Move backwards one space, ctx must be non-NULL */ +static int vidconsole_back(struct udevice *dev, struct vidconsole_ctx *ctx) { - 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); int ret; if (ops->backspace) { - ret = ops->backspace(dev); + ret = ops->backspace(dev, ctx); if (ret != -ENOSYS) return ret; } @@ -523,7 +521,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) vidconsole_newline(dev); break; case '\b': - vidconsole_back(dev); + vidconsole_back(dev, ctx); ctx->last_ch = 0; break; default: diff --git a/include/video_console.h b/include/video_console.h index c6cc050e054..3390d4fe1a7 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -294,6 +294,7 @@ struct vidconsole_ops { * backspace() - Handle erasing the last character * * @dev: Device to adjust + * @ctx: Vidconsole context to use * Returns: 0 on success, -ve on error * * With proportional fonts the vidconsole uclass cannot itself erase @@ -305,7 +306,7 @@ struct vidconsole_ops { * If not implement, default behaviour will work for fixed-width * characters. */ - int (*backspace)(struct udevice *dev); + int (*backspace)(struct udevice *dev, void *ctx); /** * get_font() - Obtain information about a font (optional) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to the internal vidconsole_newline() and vidconsole_back() functions to allow passing in a specific vidconsole context. This prepares for supporting per-object contexts in the expo text-input code. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/vidconsole-uclass.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 8590219ae64..29a1accb64c 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -90,11 +90,12 @@ static int vidconsole_back(struct udevice *dev, struct vidconsole_ctx *ctx) return video_sync(dev->parent, false); } -/* Move to a newline, scrolling the display if necessary */ -static void vidconsole_newline(struct udevice *dev) +/* + * Move to a newline, scrolling the display if necessary. + * ctx must be non-NULL + */ +static void vidconsole_newline(struct udevice *dev, struct vidconsole_ctx *ctx) { - struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); struct udevice *vid_dev = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); const int rows = CONFIG_VAL(CONSOLE_SCROLL_LINES); @@ -469,7 +470,7 @@ static int vidconsole_output_glyph(struct udevice *dev, int ch) */ ret = vidconsole_putc_xy(dev, ctx->xcur_frac, ctx->ycur, ch); if (ret == -EAGAIN) { - vidconsole_newline(dev); + vidconsole_newline(dev, ctx); ret = vidconsole_putc_xy(dev, ctx->xcur_frac, ctx->ycur, ch); } if (ret < 0) @@ -477,7 +478,7 @@ static int vidconsole_output_glyph(struct udevice *dev, int ch) ctx->xcur_frac += ret; ctx->last_ch = ch; if (ctx->xcur_frac >= ctx->xsize_frac) - vidconsole_newline(dev); + vidconsole_newline(dev, ctx); cli_index_adjust(ctx, 1); return 0; @@ -510,7 +511,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) ctx->xcur_frac = ctx->xstart_frac; break; case '\n': - vidconsole_newline(dev); + vidconsole_newline(dev, ctx); vidconsole_entry_start(dev, NULL); break; case '\t': /* Tab (8 chars alignment) */ @@ -518,7 +519,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) + 1) * ctx->tab_width_frac; if (ctx->xcur_frac >= ctx->xsize_frac) - vidconsole_newline(dev); + vidconsole_newline(dev, ctx); break; case '\b': vidconsole_back(dev, ctx); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a vctx parameter to console_fixed_putc_xy() to allow passing in a specific vidconsole context. If NULL, the default context from priv is used. 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/console_core.c | 7 +++---- drivers/video/console_normal.c | 4 +++- drivers/video/console_truetype.c | 3 ++- drivers/video/vidconsole_internal.h | 5 +++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 18edc14bcd7..ecb0b9dab89 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -336,11 +336,10 @@ int console_simple_get_font(struct udevice *dev, int seq, struct vidfont_info *i return info->name ? 0 : -ENOENT; } -int console_fixed_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp, - struct video_fontdata *fontdata) +int console_fixed_putc_xy(struct udevice *dev, void *vctx, uint x_frac, uint y, + int cp, 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 vidconsole_ctx *ctx = vctx; struct udevice *vid = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid); int pbytes = VNBYTES(vid_priv->bpix); diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index fa9d496ef86..5b6f0f0ce86 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -81,9 +81,11 @@ static int console_move_rows(struct udevice *dev, uint rowdst, int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp) { + struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); struct console_simple_priv *priv = dev_get_priv(dev); - return console_fixed_putc_xy(dev, x_frac, y, cp, priv->fontdata); + return console_fixed_putc_xy(dev, vidconsole_ctx_from_priv(vc_priv), + x_frac, y, cp, priv->fontdata); } static __maybe_unused int console_get_cursor_info(struct udevice *dev) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 519b8f88843..b4b491039ae 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -417,7 +417,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, /* Use fixed font if selected */ if (ctx->cur_fontdata) - return console_fixed_putc_xy(dev, x, y, cp, ctx->cur_fontdata); + return console_fixed_putc_xy(dev, &ctx->com, x, y, cp, + ctx->cur_fontdata); /* Reset scratch buffer for this character */ stbtt_scratch_reset(&priv->scratch); diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index 241be149ac9..ef864a7c858 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -198,14 +198,15 @@ int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp); * Fixed font putc_xy function that can be called with explicit font data * * @param dev console device + * @param vctx vidconsole context to use (cannot be NULL) * @param x_frac fractional X position * @param y Y position in pixels * @param cp Unicode code point * @param fontdata font data to use for rendering * @returns width in fractional pixels, or -ve on error */ -int console_fixed_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp, - struct video_fontdata *fontdata); +int console_fixed_putc_xy(struct udevice *dev, void *vctx, uint x_frac, uint y, + int cp, struct video_fontdata *fontdata); /** * Internal function to convert Unicode code points to code page 437. -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a vctx parameter to vidconsole_putc_xy() and its driver method to allow passing in a specific vidconsole context. If NULL, the default context from priv is used. Update all driver implementations and callers accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_normal.c | 12 ++++++------ drivers/video/console_rotate.c | 18 +++++++++--------- drivers/video/console_truetype.c | 6 +++--- drivers/video/vidconsole-uclass.c | 10 ++++++---- drivers/video/vidconsole_internal.h | 4 +++- include/video_console.h | 7 +++++-- test/dm/video.c | 18 +++++++++--------- 7 files changed, 41 insertions(+), 34 deletions(-) diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 5b6f0f0ce86..5f84896699d 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -79,13 +79,12 @@ static int console_move_rows(struct udevice *dev, uint rowdst, return 0; } -int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp) +int console_normal_putc_xy(struct udevice *dev, void *vctx, uint x_frac, + uint y, int cp) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); struct console_simple_priv *priv = dev_get_priv(dev); - return console_fixed_putc_xy(dev, vidconsole_ctx_from_priv(vc_priv), - x_frac, y, cp, priv->fontdata); + return console_fixed_putc_xy(dev, vctx, x_frac, y, cp, priv->fontdata); } static __maybe_unused int console_get_cursor_info(struct udevice *dev) @@ -172,9 +171,10 @@ static __maybe_unused int normal_entry_restore(struct udevice *dev, return 0; } -static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp) +static int console_putc_xy(struct udevice *dev, void *vctx, uint x_frac, + uint y, int cp) { - return console_normal_putc_xy(dev, x_frac, y, cp); + return console_normal_putc_xy(dev, vctx, x_frac, y, cp); } static int console_simple_ctx_new(struct udevice *dev, void **ctxp) diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c index 378c7ec6fc7..42c9de888d8 100644 --- a/drivers/video/console_rotate.c +++ b/drivers/video/console_rotate.c @@ -72,10 +72,10 @@ static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc, return 0; } -static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp) +static int console_putc_xy_1(struct udevice *dev, void *vctx, uint x_frac, + uint y, int cp) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); + struct vidconsole_ctx *ctx = vctx; struct udevice *vid = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid); struct console_simple_priv *priv = dev_get_priv(dev); @@ -161,10 +161,10 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc, return 0; } -static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp) +static int console_putc_xy_2(struct udevice *dev, void *vctx, uint x_frac, + uint y, int cp) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); + struct vidconsole_ctx *ctx = vctx; struct udevice *vid = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid); struct console_simple_priv *priv = dev_get_priv(dev); @@ -252,10 +252,10 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc, return 0; } -static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp) +static int console_putc_xy_3(struct udevice *dev, void *vctx, uint x_frac, + uint y, int cp) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); + struct vidconsole_ctx *ctx = vctx; struct udevice *vid = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid); struct console_simple_priv *priv = dev_get_priv(dev); diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index b4b491039ae..a72e2342010 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -395,11 +395,11 @@ static void clear_from(struct udevice *dev, int index) } } -static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, - int cp) +static int console_truetype_putc_xy(struct udevice *dev, void *vctx, uint x, + uint y, int cp) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); - struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vctx; struct vidconsole_ctx *com = &ctx->com; struct console_tt_priv *priv = dev_get_priv(dev); struct console_tt_metrics *met = ctx->cur_met; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 29a1accb64c..ec78068f734 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -22,13 +22,15 @@ #include <video_font.h> /* Bitmap font for code page 437 */ #include <linux/ctype.h> -int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, int ch) +int vidconsole_putc_xy(struct udevice *dev, void *vctx, uint x, uint y, int ch) { + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_ops *ops = vidconsole_get_ops(dev); if (!ops->putc_xy) return -ENOSYS; - return ops->putc_xy(dev, x, y, ch); + return ops->putc_xy(dev, vctx ?: vidconsole_ctx_from_priv(priv), x, y, + ch); } int vidconsole_move_rows(struct udevice *dev, uint rowdst, uint rowsrc, @@ -468,10 +470,10 @@ 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, ctx->xcur_frac, ctx->ycur, ch); + ret = vidconsole_putc_xy(dev, ctx, ctx->xcur_frac, ctx->ycur, ch); if (ret == -EAGAIN) { vidconsole_newline(dev, ctx); - ret = vidconsole_putc_xy(dev, ctx->xcur_frac, ctx->ycur, ch); + ret = vidconsole_putc_xy(dev, ctx, ctx->xcur_frac, ctx->ycur, ch); } if (ret < 0) return ret; diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index ef864a7c858..8b598b26b13 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -187,12 +187,14 @@ int console_simple_select_font(struct udevice *dev, const char *name, uint size) * Normal console putc_xy function that can be called by other console drivers * * @param dev console device + * @param ctx vidconsole context to use, or NULL for default * @param x_frac fractional X position * @param y Y position in pixels * @param cp Unicode code point * @returns width in fractional pixels, or -ve on error */ -int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp); +int console_normal_putc_xy(struct udevice *dev, void *ctx, uint x_frac, + uint y, int cp); /** * Fixed font putc_xy function that can be called with explicit font data diff --git a/include/video_console.h b/include/video_console.h index 3390d4fe1a7..9627d645189 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -240,6 +240,7 @@ struct vidconsole_ops { * putc_xy() - write a single character to a position * * @dev: Device to write to + * @ctx: Vidconsole context to use (cannot be NULL) * @x_frac: Fractional pixel X position (0=left-most pixel) which * is the X position multipled by VID_FRAC_DIV. * @y: Pixel Y position (0=top-most pixel) @@ -248,7 +249,8 @@ struct vidconsole_ops { * if all is OK, -EAGAIN if we ran out of space on this line, other -ve * on error */ - int (*putc_xy)(struct udevice *dev, uint x_frac, uint y, int cp); + int (*putc_xy)(struct udevice *dev, void *ctx, uint x_frac, uint y, + int cp); /** * move_rows() - Move text rows from one place to another @@ -687,6 +689,7 @@ void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old); * vidconsole_putc_xy() - write a single character to a position * * @dev: Device to write to + * @ctx: Vidconsole context to use, or NULL to use default * @x_frac: Fractional pixel X position (0=left-most pixel) which * is the X position multipled by VID_FRAC_DIV. * @y: Pixel Y position (0=top-most pixel) @@ -695,7 +698,7 @@ void vidconsole_pop_colour(struct udevice *dev, struct vidconsole_colour *old); * if all is OK, -EAGAIN if we ran out of space on this line, other -ve * on error */ -int vidconsole_putc_xy(struct udevice *dev, uint x, uint y, int cp); +int vidconsole_putc_xy(struct udevice *dev, void *ctx, uint x, uint y, int cp); /** * vidconsole_move_rows() - Move text rows from one place to another diff --git a/test/dm/video.c b/test/dm/video.c index 97778a70559..e4599be30a8 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -264,16 +264,16 @@ static int dm_test_video_text(struct unit_test_state *uts) ut_assertok(video_check_copy_fb(uts, dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_putc_xy(con, 0, 0, 'a'); + vidconsole_putc_xy(con, NULL, 0, 0, 'a'); ut_asserteq(79, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); - vidconsole_putc_xy(con, 0, 0, ' '); + vidconsole_putc_xy(con, NULL, 0, 0, ' '); ut_asserteq(46, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); + vidconsole_putc_xy(con, NULL, VID_TO_POS(i * 8), 0, ' ' + i); ut_asserteq(273, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -282,7 +282,7 @@ static int dm_test_video_text(struct unit_test_state *uts) ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); + vidconsole_putc_xy(con, NULL, VID_TO_POS(i * 8), 0, ' ' + i); ut_asserteq(273, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -306,16 +306,16 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts) ut_assertok(video_check_copy_fb(uts, dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_putc_xy(con, 0, 0, 'a'); + vidconsole_putc_xy(con, NULL, 0, 0, 'a'); ut_asserteq(89, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); - vidconsole_putc_xy(con, 0, 0, ' '); + vidconsole_putc_xy(con, NULL, 0, 0, ' '); ut_asserteq(46, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); + vidconsole_putc_xy(con, NULL, VID_TO_POS(i * 8), 0, ' ' + i); ut_asserteq(363, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -324,7 +324,7 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts) ut_assertok(video_check_copy_fb(uts, dev)); for (i = 0; i < 20; i++) - vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i); + vidconsole_putc_xy(con, NULL, VID_TO_POS(i * 8), 0, ' ' + i); ut_asserteq(363, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -1442,7 +1442,7 @@ static int dm_test_video_sync_damage(struct unit_test_state *uts) ut_assert(!vid_bbox_valid(&priv->damage)); /* Write a small piece of text at a specific position */ - vidconsole_putc_xy(con, VID_TO_POS(400), 67, 'T'); + vidconsole_putc_xy(con, NULL, VID_TO_POS(400), 67, 'T'); /* Check priv->damage before sync - should have text damage */ ut_assert(vid_bbox_valid(&priv->damage)); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to the internal vidconsole_output_glyph() function to allow passing in a specific vidconsole context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/vidconsole-uclass.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index ec78068f734..cc244a3aad7 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -454,10 +454,9 @@ error: } /* Put that actual character on the screen (using the UTF-32 code points). */ -static int vidconsole_output_glyph(struct udevice *dev, int ch) +static int vidconsole_output_glyph(struct udevice *dev, + struct vidconsole_ctx *ctx, int ch) { - struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); int ret; if (_DEBUG) { @@ -473,7 +472,8 @@ static int vidconsole_output_glyph(struct udevice *dev, int ch) ret = vidconsole_putc_xy(dev, ctx, ctx->xcur_frac, ctx->ycur, ch); if (ret == -EAGAIN) { vidconsole_newline(dev, ctx); - ret = vidconsole_putc_xy(dev, ctx, ctx->xcur_frac, ctx->ycur, ch); + ret = vidconsole_putc_xy(dev, ctx, ctx->xcur_frac, ctx->ycur, + ch); } if (ret < 0) return ret; @@ -535,7 +535,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) } else { cp = ch; } - ret = vidconsole_output_glyph(dev, cp); + ret = vidconsole_output_glyph(dev, ctx, cp); if (ret < 0) return ret; break; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to the internal vidconsole_escape_char() function to allow passing in a specific vidconsole context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/vidconsole-uclass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index cc244a3aad7..51db3200e86 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -194,10 +194,10 @@ static void get_cursor_position(struct vidconsole_priv *priv, * accumulated into escape_buf until the end of escape sequence is * found, at which point the sequence is parsed and processed. */ -static void vidconsole_escape_char(struct udevice *dev, char ch) +static void vidconsole_escape_char(struct udevice *dev, + struct vidconsole_ctx *ctx, char ch) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); struct vidconsole_ansi *ansi = &ctx->ansi; if (!IS_ENABLED(CONFIG_VIDEO_ANSI)) @@ -497,7 +497,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) vidconsole_hide_cursor(dev); if (ansi->escape) { - vidconsole_escape_char(dev, ch); + vidconsole_escape_char(dev, ctx, ch); return 0; } -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The get_cursor_info() driver method currently uses the default context. Update it to accept a context parameter so callers can specify which context to use for obtaining cursor position info. This is needed for text-input objects which have their own vidconsole context. 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 | 4 ++-- drivers/video/vidconsole-uclass.c | 2 +- include/video_console.h | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 5f84896699d..5f57b3403f1 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -87,10 +87,10 @@ int console_normal_putc_xy(struct udevice *dev, void *vctx, uint x_frac, return console_fixed_putc_xy(dev, vctx, x_frac, y, cp, priv->fontdata); } -static __maybe_unused int console_get_cursor_info(struct udevice *dev) +static __maybe_unused int console_get_cursor_info(struct udevice *dev, + void *vctx) { - struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(vc_priv); + struct vidconsole_ctx *ctx = vctx; struct console_simple_priv *priv = dev_get_priv(dev); struct video_fontdata *fontdata = priv->fontdata; struct vidconsole_cursor *curs = &ctx->curs; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index a72e2342010..5453e5d9776 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1192,9 +1192,9 @@ static int truetype_entry_restore(struct udevice *dev, struct abuf *buf) return 0; } -static int truetype_get_cursor_info(struct udevice *dev) +static int truetype_get_cursor_info(struct udevice *dev, void *vctx) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vctx; struct vidconsole_ctx *com = &ctx->com; struct vidconsole_cursor *curs = &com->curs; int x, y, index; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 51db3200e86..6258513b07e 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -779,7 +779,7 @@ int vidconsole_show_cursor(struct udevice *dev) if (!ops->get_cursor_info) return -ENOSYS; - ret = ops->get_cursor_info(dev); + ret = ops->get_cursor_info(dev, ctx); if (ret) return ret; diff --git a/include/video_console.h b/include/video_console.h index 9627d645189..2b299661e1b 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -431,9 +431,10 @@ struct vidconsole_ops { * @xmark_frac, @ymark and @index * * @dev: Console device to use + * @ctx: Vidconsole context to use (cannot be NULL) * Return: 0 if OK, -ve on error */ - int (*get_cursor_info)(struct udevice *dev); + int (*get_cursor_info)(struct udevice *dev, void *ctx); /** * mark_start() - Mark the current position as the state of CLI entry -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a vctx parameter to vidconsole_show_cursor() and vidconsole_hide_cursor() to allow passing in a specific vidconsole context. If NULL, the default context from priv is used. Update all callers accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene_txtin.c | 2 +- drivers/video/vidconsole-uclass.c | 20 ++++++++++---------- include/video_console.h | 10 ++++++---- test/dm/video.c | 4 ++-- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index 296b2fb1a1b..007f827f776 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -84,7 +84,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj, if (ret) return log_msg_ret("sav", ret); - vidconsole_show_cursor(cons); + vidconsole_show_cursor(cons, NULL); } return 0; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 6258513b07e..7b23a0a68ac 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -76,7 +76,7 @@ static int vidconsole_back(struct udevice *dev, struct vidconsole_ctx *ctx) } /* Hide cursor at old position if it's visible */ - vidconsole_hide_cursor(dev); + vidconsole_hide_cursor(dev, ctx); ctx->xcur_frac -= VID_TO_POS(ctx->x_charsize); if (ctx->xcur_frac < ctx->xstart_frac) { @@ -136,10 +136,10 @@ static char *parsenum(char *s, int *num) void vidconsole_set_cursor_pos(struct udevice *dev, void *vctx, int x, int y) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vctx ? vctx : vidconsole_ctx_from_priv(priv); + struct vidconsole_ctx *ctx = vctx ?: vidconsole_ctx_from_priv(priv); /* Hide cursor at old position if it's visible */ - vidconsole_hide_cursor(dev); + vidconsole_hide_cursor(dev, ctx); ctx->xcur_frac = VID_TO_POS(x); ctx->xstart_frac = ctx->xcur_frac; @@ -147,7 +147,7 @@ void vidconsole_set_cursor_pos(struct udevice *dev, void *vctx, int x, int y) /* make sure not to kern against the previous character */ ctx->last_ch = 0; - vidconsole_entry_start(dev, NULL); + vidconsole_entry_start(dev, ctx); } /** @@ -494,7 +494,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) int cp, ret; /* Hide cursor to avoid artifacts */ - vidconsole_hide_cursor(dev); + vidconsole_hide_cursor(dev, ctx); if (ansi->escape) { vidconsole_escape_char(dev, ctx, ch); @@ -767,10 +767,10 @@ int vidconsole_entry_restore(struct udevice *dev, struct abuf *buf) } #ifdef CONFIG_CURSOR -int vidconsole_show_cursor(struct udevice *dev) +int vidconsole_show_cursor(struct udevice *dev, void *vctx) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); + struct vidconsole_ctx *ctx = vctx ?: vidconsole_ctx_from_priv(priv); struct vidconsole_ops *ops = vidconsole_get_ops(dev); struct vidconsole_cursor *curs = &ctx->curs; int ret; @@ -808,10 +808,10 @@ int vidconsole_show_cursor(struct udevice *dev) return 0; } -int vidconsole_hide_cursor(struct udevice *dev) +int vidconsole_hide_cursor(struct udevice *dev, void *vctx) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); + struct vidconsole_ctx *ctx = vctx ?: vidconsole_ctx_from_priv(priv); struct vidconsole_cursor *curs = &ctx->curs; int ret; @@ -1015,7 +1015,7 @@ void vidconsole_idle(struct udevice *dev) * but vidconsole_show_cursor() calls get_cursor_info() to * recalc the position anyway. */ - vidconsole_show_cursor(dev); + vidconsole_show_cursor(dev, ctx); } } diff --git a/include/video_console.h b/include/video_console.h index 2b299661e1b..6b8278123da 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -580,9 +580,10 @@ int vidconsole_entry_restore(struct udevice *dev, struct abuf *buf); * Shows a cursor at the current position. * * @dev: Console device to use + * @vctx: Vidconsole context to use, or NULL to use default * Return: 0 if OK, -ve on error */ -int vidconsole_show_cursor(struct udevice *dev); +int vidconsole_show_cursor(struct udevice *dev, void *vctx); /** * vidconsole_hide_cursor() - Hide the cursor @@ -590,9 +591,10 @@ int vidconsole_show_cursor(struct udevice *dev); * Hides the cursor if it's currently visible * * @dev: Console device to use + * @vctx: Vidconsole context to use, or NULL to use default * Return: 0 if OK, -ve on error */ -int vidconsole_hide_cursor(struct udevice *dev); +int vidconsole_hide_cursor(struct udevice *dev, void *vctx); /** * vidconsole_readline_start() - Enable cursor for a video console @@ -633,12 +635,12 @@ void vidconsole_readline_start_all(bool indent); */ void vidconsole_readline_end_all(void); #else -static inline int vidconsole_show_cursor(struct udevice *dev) +static inline int vidconsole_show_cursor(struct udevice *dev, void *vctx) { return 0; } -static inline int vidconsole_hide_cursor(struct udevice *dev) +static inline int vidconsole_hide_cursor(struct udevice *dev, void *vctx) { return 0; } diff --git a/test/dm/video.c b/test/dm/video.c index e4599be30a8..ef0c0c5265b 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -1198,7 +1198,7 @@ static int check_cursor_backspace(struct unit_test_state *uts, with_a = video_compress_fb(uts, dev, false); /* Show cursor at current position (after 'a') */ - ut_assertok(vidconsole_show_cursor(con)); + ut_assertok(vidconsole_show_cursor(con, NULL)); ut_assert(curs->visible); ut_assert(curs->saved); ut_asserteq(exp_height, curs->height); @@ -1223,7 +1223,7 @@ static int check_cursor_backspace(struct unit_test_state *uts, ut_assert(after_idle != with_a); /* Hide the cursor */ - ut_assertok(vidconsole_hide_cursor(con)); + ut_assertok(vidconsole_hide_cursor(con, NULL)); ut_assert(curs->enabled); ut_assert(!curs->visible); ut_assert(!curs->saved); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a vctx parameter to vidconsole_put_char() to allow passing in a specific vidconsole context. If NULL, the default context from priv is used. Update all callers accordingly. 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 | 2 +- boot/scene.c | 2 +- boot/scene_txtin.c | 4 ++-- drivers/video/vidconsole-uclass.c | 10 +++++----- include/video_console.h | 3 ++- test/dm/video.c | 14 +++++++------- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/board/atmel/common/video_display.c b/board/atmel/common/video_display.c index 55a49b45f16..5d87d456399 100644 --- a/board/atmel/common/video_display.c +++ b/board/atmel/common/video_display.c @@ -71,7 +71,7 @@ int at91_video_show_board_info(void) priv->ctx->y_charsize - 1) / priv->ctx->y_charsize); for (s = buf, i = 0; i < len; s++, i++) - vidconsole_put_char(con, *s); + vidconsole_put_char(con, NULL, *s); return 0; } diff --git a/boot/scene.c b/boot/scene.c index 2627335c0e8..ed25ffdffa3 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -623,7 +623,7 @@ static void draw_string(struct udevice *cons, const char *str, int len, int i; for (i = 0; i < len; i++) - vidconsole_put_char(cons, '*'); + vidconsole_put_char(cons, NULL, '*'); } else { vidconsole_put_stringn(cons, str, len); } diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index 007f827f776..da42f364f39 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -79,7 +79,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj, /* move cursor back to the correct position */ for (i = cls->num; i < cls->eol_num; i++) - vidconsole_put_char(cons, '\b'); + vidconsole_put_char(cons, NULL, '\b'); ret = vidconsole_entry_save(cons, &scn->entry_save); if (ret) return log_msg_ret("sav", ret); @@ -103,7 +103,7 @@ static void scene_txtin_putch(struct cli_line_state *cls, int ch) { struct scene *scn = cls->priv; - vidconsole_put_char(scn->expo->cons, ch); + vidconsole_put_char(scn->expo->cons, NULL, ch); } void scene_txtin_close(struct scene *scn) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 7b23a0a68ac..45f39db99b0 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -486,10 +486,10 @@ static int vidconsole_output_glyph(struct udevice *dev, return 0; } -int vidconsole_put_char(struct udevice *dev, char ch) +int vidconsole_put_char(struct udevice *dev, void *vctx, char ch) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); + struct vidconsole_ctx *ctx = vctx ?: vidconsole_ctx_from_priv(priv); struct vidconsole_ansi *ansi = &ctx->ansi; int cp, ret; @@ -514,7 +514,7 @@ int vidconsole_put_char(struct udevice *dev, char ch) break; case '\n': vidconsole_newline(dev, ctx); - vidconsole_entry_start(dev, NULL); + vidconsole_entry_start(dev, ctx); break; case '\t': /* Tab (8 chars alignment) */ ctx->xcur_frac = ((ctx->xcur_frac / ctx->tab_width_frac) @@ -552,7 +552,7 @@ int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen) if (maxlen != -1) end = str + maxlen; for (s = str; *s && (maxlen == -1 || s < end); s++) { - ret = vidconsole_put_char(dev, *s); + ret = vidconsole_put_char(dev, NULL, *s); if (ret) return ret; } @@ -573,7 +573,7 @@ static void vidconsole_putc(struct stdio_dev *sdev, const char ch) if (priv->quiet) return; - ret = vidconsole_put_char(dev, ch); + ret = vidconsole_put_char(dev, NULL, ch); if (ret) { #ifdef DEBUG console_puts_select_stderr(true, "[vc err: putc]"); diff --git a/include/video_console.h b/include/video_console.h index 6b8278123da..16c01718bd9 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -748,10 +748,11 @@ int vidconsole_entry_start(struct udevice *dev, void *ctx); * can be adjusted manually using vidconsole_position_cursor(). * * @dev: Device to adjust + * @vctx: Vidconsole context to use, or NULL to use default * @ch: Character to write * Return: 0 if OK, -ve on error */ -int vidconsole_put_char(struct udevice *dev, char ch); +int vidconsole_put_char(struct udevice *dev, void *vctx, char ch); /** * vidconsole_put_stringn() - Output part of a string to the current console pos diff --git a/test/dm/video.c b/test/dm/video.c index ef0c0c5265b..ede09a432a2 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -420,21 +420,21 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, /* Check display wrap */ for (i = 0; i < 120; i++) - vidconsole_put_char(con, 'A' + i % 50); + vidconsole_put_char(con, NULL, 'A' + i % 50); ut_asserteq(wrap_size, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); /* Check display scrolling */ for (i = 0; i < SCROLL_LINES; i++) { - vidconsole_put_char(con, 'A' + i % 50); - vidconsole_put_char(con, '\n'); + vidconsole_put_char(con, NULL, 'A' + i % 50); + vidconsole_put_char(con, NULL, '\n'); } ut_asserteq(scroll_size, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); /* If we scroll enough, the screen becomes blank again */ for (i = 0; i < SCROLL_LINES; i++) - vidconsole_put_char(con, '\n'); + vidconsole_put_char(con, NULL, '\n'); ut_asserteq(46, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -1193,8 +1193,8 @@ static int check_cursor_backspace(struct unit_test_state *uts, ut_assert(!curs->enabled); ut_assert(!curs->saved); ut_assert(!curs->height); - ut_assertok(vidconsole_put_char(con, ' ')); - ut_assertok(vidconsole_put_char(con, 'a')); + ut_assertok(vidconsole_put_char(con, NULL, ' ')); + ut_assertok(vidconsole_put_char(con, NULL, 'a')); with_a = video_compress_fb(uts, dev, false); /* Show cursor at current position (after 'a') */ @@ -1208,7 +1208,7 @@ static int check_cursor_backspace(struct unit_test_state *uts, curs->enabled = true; /* Do backspace - the cursor will be hidden */ - ut_assertok(vidconsole_put_char(con, '\b')); + ut_assertok(vidconsole_put_char(con, NULL, '\b')); ut_assert(!curs->visible); ut_assert(!curs->saved); after_backspace = video_compress_fb(uts, dev, false); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to vidconsole_put_stringn() and vidconsole_put_string() to allow passing in a specific vidconsole context. If NULL, the default context from priv is used. Update all callers accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- board/kosagi/novena/novena.c | 2 +- boot/expo_test.c | 10 +++--- boot/scene.c | 2 +- cmd/video.c | 4 +-- common/splash.c | 2 +- drivers/video/vidconsole-uclass.c | 11 ++++--- include/video_console.h | 7 +++-- test/dm/video.c | 52 +++++++++++++++---------------- 8 files changed, 47 insertions(+), 43 deletions(-) diff --git a/board/kosagi/novena/novena.c b/board/kosagi/novena/novena.c index f65551ece5e..a1f177265cb 100644 --- a/board/kosagi/novena/novena.c +++ b/board/kosagi/novena/novena.c @@ -79,7 +79,7 @@ int board_late_init(void) display_options_get_banner(false, buf, sizeof(buf)); vidconsole_position_cursor(con, 0, 0); - vidconsole_put_string(con, buf); + vidconsole_put_string(con, NULL, buf); #endif return 0; } diff --git a/boot/expo_test.c b/boot/expo_test.c index ae4e70ceede..2d5ba7c0f4c 100644 --- a/boot/expo_test.c +++ b/boot/expo_test.c @@ -181,14 +181,14 @@ int expo_test_render(struct expo *exp) x = vid_priv->xsize - 18 * ctx->x_charsize; y = 10; vidconsole_set_cursor_pos(exp->cons, NULL, x, y); - vidconsole_put_string(exp->cons, buf); + vidconsole_put_string(exp->cons, NULL, buf); /* Display FPS on next line (only if non-zero) */ if (test->fps_last > 0) { snprintf(buf, sizeof(buf), "fps %6d", test->fps_last); y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, NULL, x, y); - vidconsole_put_string(exp->cons, buf); + vidconsole_put_string(exp->cons, NULL, buf); } /* Display average render time in milliseconds on next line */ @@ -197,7 +197,7 @@ int expo_test_render(struct expo *exp) (test->render_avg_us % 1000) / 100); y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, NULL, x, y); - vidconsole_put_string(exp->cons, buf); + vidconsole_put_string(exp->cons, NULL, buf); /* Display average sync time in milliseconds on next line */ snprintf(buf, sizeof(buf), "sync %6lu.%01lums", @@ -205,7 +205,7 @@ int expo_test_render(struct expo *exp) (test->sync_avg_us % 1000) / 100); y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, NULL, x, y); - vidconsole_put_string(exp->cons, buf); + vidconsole_put_string(exp->cons, NULL, buf); /* Display average poll time in milliseconds on next line */ snprintf(buf, sizeof(buf), "poll %6lu.%01lums", @@ -213,7 +213,7 @@ int expo_test_render(struct expo *exp) (test->poll_avg_us % 1000) / 100); y += ctx->y_charsize; vidconsole_set_cursor_pos(exp->cons, NULL, x, y); - vidconsole_put_string(exp->cons, buf); + vidconsole_put_string(exp->cons, NULL, buf); return 0; } diff --git a/boot/scene.c b/boot/scene.c index ed25ffdffa3..e504cb29d51 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -625,7 +625,7 @@ static void draw_string(struct udevice *cons, const char *str, int len, for (i = 0; i < len; i++) vidconsole_put_char(cons, NULL, '*'); } else { - vidconsole_put_stringn(cons, str, len); + vidconsole_put_stringn(cons, NULL, str, len); } } diff --git a/cmd/video.c b/cmd/video.c index 5c228b48058..cdd5804a172 100644 --- a/cmd/video.c +++ b/cmd/video.c @@ -41,7 +41,7 @@ static int do_video_puts(struct cmd_tbl *cmdtp, int flag, int argc, if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev)) return CMD_RET_FAILURE; - ret = vidconsole_put_string(dev, argv[1]); + ret = vidconsole_put_string(dev, NULL, argv[1]); if (!ret) ret = video_sync(dev->parent, false); @@ -89,7 +89,7 @@ static int do_video_write(struct cmd_tbl *cmdtp, int flag, int argc, else vidconsole_position_cursor(dev, col, row); - ret = vidconsole_put_string(dev, argv[i + 1]); + ret = vidconsole_put_string(dev, NULL, argv[i + 1]); if (ret) return CMD_RET_FAILURE; } diff --git a/common/splash.c b/common/splash.c index c5591293634..7bdf2927d1e 100644 --- a/common/splash.c +++ b/common/splash.c @@ -149,7 +149,7 @@ void splash_display_banner(void) display_options_get_banner(false, buf, sizeof(buf)); vidconsole_position_cursor(dev, col, 1); - vidconsole_put_string(dev, buf); + vidconsole_put_string(dev, NULL, buf); vidconsole_position_cursor(dev, 0, row); } #endif /* CONFIG_VIDEO && !CONFIG_HIDE_LOGO_VERSION */ diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 45f39db99b0..9b29b742740 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -544,7 +544,8 @@ int vidconsole_put_char(struct udevice *dev, void *vctx, char ch) return 0; } -int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen) +int vidconsole_put_stringn(struct udevice *dev, void *ctx, const char *str, + int maxlen) { const char *s, *end = NULL; int ret; @@ -552,7 +553,7 @@ int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen) if (maxlen != -1) end = str + maxlen; for (s = str; *s && (maxlen == -1 || s < end); s++) { - ret = vidconsole_put_char(dev, NULL, *s); + ret = vidconsole_put_char(dev, ctx, *s); if (ret) return ret; } @@ -560,9 +561,9 @@ int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen) return 0; } -int vidconsole_put_string(struct udevice *dev, const char *str) +int vidconsole_put_string(struct udevice *dev, void *ctx, const char *str) { - return vidconsole_put_stringn(dev, str, -1); + return vidconsole_put_stringn(dev, ctx, str, -1); } static void vidconsole_putc(struct stdio_dev *sdev, const char ch) @@ -595,7 +596,7 @@ static void vidconsole_puts(struct stdio_dev *sdev, const char *s) if (priv->quiet) return; - ret = vidconsole_put_string(dev, s); + ret = vidconsole_put_string(dev, NULL, s); if (ret) { #ifdef DEBUG char str[30]; diff --git a/include/video_console.h b/include/video_console.h index 16c01718bd9..4bb6974edcc 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -765,11 +765,13 @@ int vidconsole_put_char(struct udevice *dev, void *vctx, char ch); * can be adjusted manually using vidconsole_position_cursor(). * * @dev: Device to adjust + * @ctx: Vidconsole context, or NULL to use default * @str: String to write * @maxlen: Maximum chars to output, or -1 for all * Return: 0 if OK, -ve on error */ -int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen); +int vidconsole_put_stringn(struct udevice *dev, void *ctx, const char *str, + int maxlen); /** * vidconsole_put_string() - Output a string to the current console position @@ -782,10 +784,11 @@ int vidconsole_put_stringn(struct udevice *dev, const char *str, int maxlen); * can be adjusted manually using vidconsole_position_cursor(). * * @dev: Device to adjust + * @ctx: Vidconsole context, or NULL to use default * @str: String to write * Return: 0 if OK, -ve on error */ -int vidconsole_put_string(struct udevice *dev, const char *str); +int vidconsole_put_string(struct udevice *dev, void *ctx, const char *str); /** * vidconsole_position_cursor() - Move the text cursor diff --git a/test/dm/video.c b/test/dm/video.c index ede09a432a2..7a58a64c0f9 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -343,7 +343,7 @@ static int dm_test_video_chars(struct unit_test_state *uts) 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)); - vidconsole_put_string(con, test_string); + vidconsole_put_string(con, NULL, test_string); ut_asserteq(466, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -370,18 +370,18 @@ static int dm_test_video_ansi(struct unit_test_state *uts) ut_assertok(video_check_copy_fb(uts, dev)); /* test clear escape sequence: [2J */ - vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J"); + vidconsole_put_string(con, NULL, "A\tB\tC" ANSI_ESC "[2J"); ut_asserteq(46, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); /* test set-cursor: [%d;%df */ - vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd"); + vidconsole_put_string(con, NULL, "abc" ANSI_ESC "[2;2fab" ANSI_ESC "[4;4fcd"); ut_asserteq(143, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); /* test colors (30-37 fg color, 40-47 bg color) */ - vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */ - vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */ + vidconsole_put_string(con, NULL, ANSI_ESC "[30;41mfoo"); /* black on red */ + vidconsole_put_string(con, NULL, ANSI_ESC "[33;44mbar"); /* yellow on blue */ ut_asserteq(272, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -770,8 +770,8 @@ static int dm_test_video_truetype(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); - vidconsole_put_stringn(con, test_string, 30); + vidconsole_put_string(con, NULL, test_string); + vidconsole_put_stringn(con, NULL, test_string, 30); ut_asserteq(13073, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -799,7 +799,7 @@ static int dm_test_video_truetype_scroll(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); + vidconsole_put_string(con, NULL, test_string); ut_asserteq(34248, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -825,7 +825,7 @@ static int dm_test_video_truetype_bs(struct unit_test_state *uts) ut_assertok(video_get_nologo(uts, &dev)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, test_string); + vidconsole_put_string(con, NULL, test_string); ut_asserteq(29310, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -862,9 +862,9 @@ static int dm_test_video_copy(struct unit_test_state *uts) ut_assertok(video_bmp_display(dev, addr, 0, 0, false)); ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); - vidconsole_put_string(con, "\n\n\n\n\n"); - vidconsole_put_string(con, test_string); - vidconsole_put_string(con, test_string); + vidconsole_put_string(con, NULL, "\n\n\n\n\n"); + vidconsole_put_string(con, NULL, test_string); + vidconsole_put_string(con, NULL, test_string); ut_asserteq(6884, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -888,8 +888,8 @@ static int dm_test_video_copy(struct unit_test_state *uts) * ./u-boot -Tl * ut dm dm_test_video_copy */ - vidconsole_put_string(con, test_string); - vidconsole_put_string(con, test_string); + vidconsole_put_string(con, NULL, test_string); + vidconsole_put_string(con, NULL, test_string); video_sync(dev, true); ut_asserteq(7621, video_compress_fb(uts, dev, false)); ut_asserteq(7741, video_compress_fb(uts, dev, true)); @@ -925,21 +925,21 @@ static int dm_test_video_damage(struct unit_test_state *uts) damage = &priv->damage; vidconsole_position_cursor(con, 14, 10); - vidconsole_put_string(con, test_string_2); + vidconsole_put_string(con, NULL, test_string_2); ut_asserteq(449, damage->x0); ut_asserteq(325, damage->y0); ut_asserteq(661, damage->x1); ut_asserteq(350, damage->y1); vidconsole_position_cursor(con, 7, 5); - vidconsole_put_string(con, test_string_1); + vidconsole_put_string(con, NULL, test_string_1); ut_asserteq(225, damage->x0); ut_asserteq(164, damage->y0); ut_asserteq(661, damage->x1); ut_asserteq(350, damage->y1); vidconsole_position_cursor(con, 21, 15); - vidconsole_put_string(con, test_string_3); + vidconsole_put_string(con, NULL, test_string_3); ut_asserteq(225, damage->x0); ut_asserteq(164, damage->y0); ut_asserteq(1280, damage->x1); @@ -1091,15 +1091,15 @@ static int dm_test_video_silence(struct unit_test_state *uts) ut_unsilence_console(uts); printf("message 1: console\n"); - vidconsole_put_string(con, "message 1: video\n"); + vidconsole_put_string(con, NULL, "message 1: video\n"); vidconsole_set_quiet(con, true); printf("second message: console\n"); - vidconsole_put_string(con, "second message: video\n"); + vidconsole_put_string(con, NULL, "second message: video\n"); vidconsole_set_quiet(con, false); printf("final message: console\n"); - vidconsole_put_string(con, "final message: video\n"); + vidconsole_put_string(con, NULL, "final message: video\n"); ut_asserteq(3944, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -1162,15 +1162,15 @@ static int dm_test_video_font_switch(struct unit_test_state *uts) ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con)); /* Start with TrueType font and write multi-line text */ - vidconsole_put_string(con, truetype_text); + vidconsole_put_string(con, NULL, truetype_text); /* Switch to bitmap font */ ut_assertok(vidconsole_select_font(con, "8x16", 0)); - vidconsole_put_string(con, bitmap_text); + vidconsole_put_string(con, NULL, bitmap_text); /* Switch back to TrueType font */ ut_assertok(vidconsole_select_font(con, NULL, 0)); - vidconsole_put_string(con, final_truetype_text); + vidconsole_put_string(con, NULL, final_truetype_text); ut_asserteq(14892, video_compress_fb(uts, dev, false)); @@ -1332,7 +1332,7 @@ static int dm_test_video_manual_sync(struct unit_test_state *uts) priv = dev_get_uclass_priv(dev); /* Write some text and verify it appears in the framebuffer */ - vidconsole_put_string(con, "Test"); + vidconsole_put_string(con, NULL, "Test"); ut_asserteq(118, video_compress_fb(uts, dev, false)); /* Sync to copy buffer before enabling manual-sync mode */ @@ -1343,7 +1343,7 @@ static int dm_test_video_manual_sync(struct unit_test_state *uts) /* Clear and write new text - auto-sync should not happen */ video_clear(dev); - vidconsole_put_string(con, "Manual Sync"); + vidconsole_put_string(con, NULL, "Manual Sync"); /* should do nothing in manual-sync mode */ ut_assertok(video_sync(dev, false)); @@ -1377,7 +1377,7 @@ static int dm_test_video_manual_sync(struct unit_test_state *uts) ut_assertok(video_check_copy_fb(uts, dev)); /* Write new text again */ - vidconsole_put_string(con, "Test2"); + vidconsole_put_string(con, NULL, "Test2"); /* without VIDSYNC_FLUSH or COPY - should do nothing */ ut_assertok(video_manual_sync(dev, 0)); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> The mark_start() driver method currently uses the default context. Update it to accept a context parameter so callers can specify which context to use for marking the start position. This is needed for text-input objects which have their own vidconsole context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 4 ++-- drivers/video/vidconsole-uclass.c | 8 ++++---- include/video_console.h | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 5453e5d9776..b3884bddd72 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1251,9 +1251,9 @@ const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep) } } -static int truetype_mark_start(struct udevice *dev) +static int truetype_mark_start(struct udevice *dev, void *vctx) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vctx; ctx->pos_start = ctx->pos_ptr; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 9b29b742740..6ef86abc4ce 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -839,10 +839,10 @@ int vidconsole_hide_cursor(struct udevice *dev, void *vctx) } #endif /* CONFIG_CURSOR */ -int vidconsole_mark_start(struct udevice *dev) +int vidconsole_mark_start(struct udevice *dev, void *vctx) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); + struct vidconsole_ctx *ctx = vctx ?: vidconsole_ctx_from_priv(priv); struct vidconsole_ops *ops = vidconsole_get_ops(dev); ctx->xmark_frac = ctx->xcur_frac; @@ -851,7 +851,7 @@ int vidconsole_mark_start(struct udevice *dev) if (ops->mark_start) { int ret; - ret = ops->mark_start(dev); + ret = ops->mark_start(dev, ctx); if (ret != -ENOSYS) return ret; } @@ -1027,7 +1027,7 @@ void vidconsole_readline_start(struct udevice *dev, void *vctx, bool indent) ctx->curs.indent = indent; ctx->curs.enabled = true; - vidconsole_mark_start(dev); + vidconsole_mark_start(dev, ctx); } void vidconsole_readline_end(struct udevice *dev, void *vctx) diff --git a/include/video_console.h b/include/video_console.h index 4bb6974edcc..297049cb851 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -444,8 +444,9 @@ struct vidconsole_ops { * the beginning point for the cursor. * * @dev: Console device to use + * @ctx: Vidconsole context to use (cannot be NULL) */ - int (*mark_start)(struct udevice *dev); + int (*mark_start)(struct udevice *dev, void *ctx); }; /* Get a pointer to the driver operations for a video console device */ -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a context parameter to the select_font() method so that font selection can be done for a specific context rather than always using the default. The vidconsole_select_font() wrapper handles NULL by using the default context, so callers can pass NULL if they don't have a specific context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/expo_test.c | 2 +- boot/scene.c | 4 ++-- cmd/font.c | 4 ++-- drivers/video/console_core.c | 3 ++- drivers/video/console_truetype.c | 6 +++--- drivers/video/vidconsole-uclass.c | 7 +++++-- drivers/video/vidconsole_internal.h | 3 ++- include/video_console.h | 8 ++++++-- test/dm/video.c | 26 +++++++++++++------------- 9 files changed, 36 insertions(+), 27 deletions(-) diff --git a/boot/expo_test.c b/boot/expo_test.c index 2d5ba7c0f4c..1de597ea603 100644 --- a/boot/expo_test.c +++ b/boot/expo_test.c @@ -135,7 +135,7 @@ int expo_test_render(struct expo *exp) test->render_delta_us = get_timer_us(test->base_time_us); /* Select 8x16 font for test display */ - ret = vidconsole_select_font(exp->cons, "8x16", 0); + ret = vidconsole_select_font(exp->cons, NULL, "8x16", 0); if (ret && ret != -ENOSYS) return log_msg_ret("font", ret); diff --git a/boot/scene.c b/boot/scene.c index e504cb29d51..58be46cb7ee 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -647,10 +647,10 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, return -ENOTSUPP; if (gen->font_name || gen->font_size) { - ret = vidconsole_select_font(cons, gen->font_name, + ret = vidconsole_select_font(cons, NULL, gen->font_name, gen->font_size); } else { - ret = vidconsole_select_font(cons, NULL, 0); + ret = vidconsole_select_font(cons, NULL, NULL, 0); } if (ret && ret != -ENOSYS) return log_msg_ret("font", ret); diff --git a/cmd/font.c b/cmd/font.c index 79218779a2d..ca759df79a3 100644 --- a/cmd/font.c +++ b/cmd/font.c @@ -46,7 +46,7 @@ static int do_font_select(struct cmd_tbl *cmdtp, int flag, int argc, name = argv[1]; if (argc == 3) size = dectoul(argv[2], NULL); - ret = vidconsole_select_font(dev, name, size); + ret = vidconsole_select_font(dev, NULL, name, size); if (ret) { printf("Failed (error %d)\n", ret); return CMD_RET_FAILURE; @@ -75,7 +75,7 @@ static int do_font_size(struct cmd_tbl *cmdtp, int flag, int argc, } else { size = dectoul(argv[1], NULL); - ret = vidconsole_select_font(dev, font_name, size); + ret = vidconsole_select_font(dev, NULL, font_name, size); if (ret) { printf("Failed (error %d)\n", ret); return CMD_RET_FAILURE; diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index ecb0b9dab89..5cb1b3fb2b7 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -369,7 +369,8 @@ int console_fixed_putc_xy(struct udevice *dev, void *vctx, uint x_frac, uint y, return VID_TO_POS(fontdata->width); } -int console_simple_select_font(struct udevice *dev, const char *name, uint size) +int console_simple_select_font(struct udevice *dev, void *ctx, const char *name, + uint size) { struct video_fontdata *font; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index b3884bddd72..af880ad5597 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -973,10 +973,10 @@ static int get_metrics(struct udevice *dev, const char *name, uint size, return 0; } -static int truetype_select_font(struct udevice *dev, const char *name, - uint size) +static int truetype_select_font(struct udevice *dev, void *vctx, + const char *name, uint size) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vctx; struct console_tt_metrics *met; struct video_fontdata *fontdata; int ret; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 6ef86abc4ce..c0eee7d75fd 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -647,14 +647,17 @@ int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep return 0; } -int vidconsole_select_font(struct udevice *dev, const char *name, uint size) +int vidconsole_select_font(struct udevice *dev, void *ctx, const char *name, + uint size) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); + if (!ctx) + ctx = vidconsole_ctx(dev); if (!ops->select_font) return -ENOSYS; - return ops->select_font(dev, name, size); + return ops->select_font(dev, ctx, name, size); } int vidconsole_measure(struct udevice *dev, const char *name, uint size, diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index 8b598b26b13..e1e89f6524a 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -181,7 +181,8 @@ int console_simple_get_font(struct udevice *dev, int seq, struct vidfont_info *i * Internal function to be used in as ops. * See details in video_console.h select_font function **/ -int console_simple_select_font(struct udevice *dev, const char *name, uint size); +int console_simple_select_font(struct udevice *dev, void *ctx, const char *name, + uint size); /** * Normal console putc_xy function that can be called by other console drivers diff --git a/include/video_console.h b/include/video_console.h index 297049cb851..c5fc0577670 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -334,11 +334,13 @@ struct vidconsole_ops { * select_font() - Select a particular font by name / size * * @dev: Device to adjust + * @ctx: Context to use * @name: Font name to use (NULL to use default) * @size: Font size to use (0 to use default) * Returns: 0 on success, -ENOENT if no such font */ - int (*select_font)(struct udevice *dev, const char *name, uint size); + int (*select_font)(struct udevice *dev, void *ctx, const char *name, + uint size); /** * measure() - Measure the bounding box of some text @@ -487,10 +489,12 @@ int vidconsole_get_font(struct udevice *dev, int seq, * vidconsole_select_font() - Select a particular font by name / size * * @dev: Device to adjust + * @ctx: Context to use (NULL to use default) * @name: Font name to use (NULL to use default) * @size: Font size to use (0 to use default) */ -int vidconsole_select_font(struct udevice *dev, const char *name, uint size); +int vidconsole_select_font(struct udevice *dev, void *ctx, const char *name, + uint size); /** * vidconsole_measure() - Measure the bounding box of some text diff --git a/test/dm/video.c b/test/dm/video.c index 7a58a64c0f9..b4a1200e481 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -259,7 +259,7 @@ static int dm_test_video_text(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, "8x16", 0)); ut_asserteq(46, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -301,7 +301,7 @@ static int dm_test_video_text_12x22(struct unit_test_state *uts) 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, "12x22", 0)); + ut_assertok(vidconsole_select_font(con, NULL, "12x22", 0)); ut_asserteq(46, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -342,7 +342,7 @@ static int dm_test_video_chars(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, "8x16", 0)); vidconsole_put_string(con, NULL, test_string); ut_asserteq(466, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -361,7 +361,7 @@ static int dm_test_video_ansi(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, "8x16", 0)); /* reference clear: */ video_clear(con->parent); @@ -414,7 +414,7 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot, 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(vidconsole_select_font(con, NULL, "8x16", 0)); ut_asserteq(46, video_compress_fb(uts, dev, false)); ut_assertok(video_check_copy_fb(uts, dev)); @@ -1165,11 +1165,11 @@ static int dm_test_video_font_switch(struct unit_test_state *uts) vidconsole_put_string(con, NULL, truetype_text); /* Switch to bitmap font */ - ut_assertok(vidconsole_select_font(con, "8x16", 0)); + ut_assertok(vidconsole_select_font(con, NULL, "8x16", 0)); vidconsole_put_string(con, NULL, bitmap_text); /* Switch back to TrueType font */ - ut_assertok(vidconsole_select_font(con, NULL, 0)); + ut_assertok(vidconsole_select_font(con, NULL, NULL, 0)); vidconsole_put_string(con, NULL, final_truetype_text); ut_asserteq(14892, video_compress_fb(uts, dev, false)); @@ -1242,7 +1242,7 @@ static int dm_test_video_backspace_normal(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, "8x16", 0)); ut_assertok(check_cursor_backspace(uts, dev, con, 16)); return 0; @@ -1256,7 +1256,7 @@ static int dm_test_video_backspace_truetype(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, NULL, 30)); ut_assertok(check_cursor_backspace(uts, dev, con, 30)); return 0; @@ -1271,7 +1271,7 @@ static int dm_test_video_cmd(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, "8x16", 0)); ut_assertok(run_command("setcurs 10 5", 0)); @@ -1412,7 +1412,7 @@ static int dm_test_video_sync_damage(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, "8x16", 0)); priv = dev_get_uclass_priv(dev); /* Use manual sync to prevent interference with the test */ @@ -1561,7 +1561,7 @@ static int dm_test_video_entry_save(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, "8x16", 0)); ut_assertok(check_entry_save(uts, con)); @@ -1576,7 +1576,7 @@ static int dm_test_video_entry_save_tt(struct unit_test_state *uts) 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(vidconsole_select_font(con, NULL, NULL, 30)); ut_assertok(check_entry_save(uts, con)); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update select_metrics() to take a context parameter so it can operate on a specific context rather than always using the default. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index af880ad5597..4dd382055b2 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -913,9 +913,9 @@ static void set_bitmap_font(struct udevice *dev, com->tab_width_frac = VID_TO_POS(fontdata->width) * 8 / 2; } -static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) +static void select_metrics(struct udevice *dev, struct console_tt_ctx *ctx, + struct console_tt_metrics *met) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_ctx *com = &ctx->com; struct udevice *vid_dev = dev_get_parent(dev); struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); @@ -998,7 +998,7 @@ static int truetype_select_font(struct udevice *dev, void *vctx, if (ret) return log_msg_ret("sel", ret); - select_metrics(dev, met); + select_metrics(dev, ctx, met); return 0; } @@ -1297,7 +1297,7 @@ static int console_truetype_probe(struct udevice *dev) return log_msg_ret("add", ret); ctx->cur_met = &priv->metrics[ret]; - select_metrics(dev, &priv->metrics[ret]); + select_metrics(dev, ctx, &priv->metrics[ret]); debug("%s: ready\n", __func__); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update console_alloc_cursor() to take a context parameter so it can allocate cursor memory for a specific context rather than always using the default. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_core.c | 7 ++----- drivers/video/console_truetype.c | 2 +- drivers/video/vidconsole_internal.h | 3 ++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 5cb1b3fb2b7..dba47af4eb5 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -278,9 +278,8 @@ int cursor_hide(struct vidconsole_cursor *curs, struct video_priv *vid_priv, return 0; } -int console_alloc_cursor(struct udevice *dev) +int console_alloc_cursor(struct udevice *dev, struct vidconsole_ctx *ctx) { - struct vidconsole_ctx *ctx; struct vidconsole_cursor *curs; struct video_priv *vid_priv; struct udevice *vid; @@ -288,8 +287,6 @@ int console_alloc_cursor(struct udevice *dev) if (!CONFIG_IS_ENABLED(CURSOR) || xpl_phase() < PHASE_BOARD_R) return 0; - - ctx = vidconsole_ctx(dev); vid = dev_get_parent(dev); vid_priv = dev_get_uclass_priv(vid); curs = &ctx->curs; @@ -312,7 +309,7 @@ int console_probe(struct udevice *dev) return ret; if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { - ret = console_alloc_cursor(dev); + ret = console_alloc_cursor(dev, vidconsole_ctx(dev)); if (ret) return ret; } diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 4dd382055b2..9b835437031 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1301,7 +1301,7 @@ static int console_truetype_probe(struct udevice *dev) debug("%s: ready\n", __func__); - ret = console_alloc_cursor(dev); + ret = console_alloc_cursor(dev, &ctx->com); if (ret) return ret; diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index e1e89f6524a..60ff7bed758 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -152,9 +152,10 @@ int cursor_hide(struct vidconsole_cursor *curs, struct video_priv *vid_priv, * Allocates memory for saving pixels under the cursor * * @dev: vidconsole device + * @ctx: vidconsole context * Return: 0 if success, -ENOMEM if allocation fails */ -int console_alloc_cursor(struct udevice *dev); +int console_alloc_cursor(struct udevice *dev, struct vidconsole_ctx *ctx); /** * console probe function. -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update vidconsole_set_bitmap_font() to take a context parameter so it can set font properties for a specific context rather than always using the default. 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_truetype.c | 2 +- drivers/video/vidconsole-uclass.c | 4 +--- include/video_console.h | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index dba47af4eb5..ff5d9f5964a 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -25,7 +25,7 @@ static int console_set_font(struct udevice *dev, struct video_fontdata *fontdata struct console_simple_priv *priv = dev_get_priv(dev); priv->fontdata = fontdata; - vidconsole_set_bitmap_font(dev, fontdata); + vidconsole_set_bitmap_font(dev, vidconsole_ctx(dev), fontdata); return 0; } diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 9b835437031..7a5588bf419 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -908,7 +908,7 @@ static void set_bitmap_font(struct udevice *dev, ctx->cur_fontdata = fontdata; ctx->cur_met = NULL; - vidconsole_set_bitmap_font(dev, fontdata); + vidconsole_set_bitmap_font(dev, com, fontdata); com->tab_width_frac = VID_TO_POS(fontdata->width) * 8 / 2; } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index c0eee7d75fd..b5a129d82b7 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -981,11 +981,9 @@ void vidconsole_set_quiet(struct udevice *dev, bool quiet) priv->quiet = quiet; } -void vidconsole_set_bitmap_font(struct udevice *dev, +void vidconsole_set_bitmap_font(struct udevice *dev, struct vidconsole_ctx *ctx, 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 video_priv *vid_priv = dev_get_uclass_priv(dev->parent); log_debug("console_simple: setting %s font\n", fontdata->name); diff --git a/include/video_console.h b/include/video_console.h index c5fc0577670..500a5974a57 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -860,9 +860,10 @@ void vidconsole_set_quiet(struct udevice *dev, bool quiet); * vidconsole_set_bitmap_font() - prepare vidconsole for chosen bitmap font * * @dev vidconsole device + * @ctx vidconsole context * @fontdata pointer to font data struct */ -void vidconsole_set_bitmap_font(struct udevice *dev, +void vidconsole_set_bitmap_font(struct udevice *dev, struct vidconsole_ctx *ctx, struct video_fontdata *fontdata); /* -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update set_bitmap_font() to take a context parameter so it can set bitmap font properties for a specific context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_truetype.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 7a5588bf419..de2992ec748 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -896,13 +896,13 @@ static struct console_tt_metrics *find_metrics(struct udevice *dev, * set_bitmap_font() - Set up console to use a fixed font * * @dev: Console device + * @ctx: Console context * @fontdata: Fixed font data to use * Return: 0 if OK, -ve on error */ -static void set_bitmap_font(struct udevice *dev, +static void set_bitmap_font(struct udevice *dev, struct console_tt_ctx *ctx, struct video_fontdata *fontdata) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); struct vidconsole_ctx *com = &ctx->com; ctx->cur_fontdata = fontdata; @@ -986,7 +986,7 @@ static int truetype_select_font(struct udevice *dev, void *vctx, for (fontdata = fonts; fontdata->name; fontdata++) { if (!strcmp(name, fontdata->name)) { /* Switch to fixed-font mode */ - set_bitmap_font(dev, fontdata); + set_bitmap_font(dev, ctx, fontdata); return 0; } } -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update console_set_font() to take a context parameter so it can set font properties for a specific context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index ff5d9f5964a..483639e65c4 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -18,14 +18,16 @@ * console_set_font() - prepare vidconsole for chosen font. * * @dev vidconsole device + * @ctx vidconsole context * @fontdata pointer to font data struct */ -static int console_set_font(struct udevice *dev, struct video_fontdata *fontdata) +static int console_set_font(struct udevice *dev, struct vidconsole_ctx *ctx, + struct video_fontdata *fontdata) { struct console_simple_priv *priv = dev_get_priv(dev); priv->fontdata = fontdata; - vidconsole_set_bitmap_font(dev, vidconsole_ctx(dev), fontdata); + vidconsole_set_bitmap_font(dev, ctx, fontdata); return 0; } @@ -304,7 +306,7 @@ int console_probe(struct udevice *dev) { int ret; - ret = console_set_font(dev, fonts); + ret = console_set_font(dev, vidconsole_ctx(dev), fonts); if (ret) return ret; @@ -373,13 +375,13 @@ int console_simple_select_font(struct udevice *dev, void *ctx, const char *name, if (!name) { if (fonts->name) - console_set_font(dev, fonts); + console_set_font(dev, ctx, fonts); return 0; } for (font = fonts; font->name; font++) { if (!strcmp(name, font->name)) { - console_set_font(dev, font); + console_set_font(dev, ctx, font); return 0; } }; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Update the get_font_size() ops method and vidconsole_get_font_size() wrapper to take a context parameter. This allows callers to query the font size for a specific context rather than always using the default. The wrapper gets the default context if NULL is passed, while the driver implementations expect a valid context. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- cmd/font.c | 2 +- drivers/video/console_core.c | 3 ++- drivers/video/console_truetype.c | 5 +++-- drivers/video/vidconsole-uclass.c | 7 +++++-- drivers/video/vidconsole_internal.h | 3 ++- include/video_console.h | 8 ++++++-- test/cmd/font.c | 6 +++--- 7 files changed, 22 insertions(+), 12 deletions(-) diff --git a/cmd/font.c b/cmd/font.c index ca759df79a3..6607fcc1373 100644 --- a/cmd/font.c +++ b/cmd/font.c @@ -64,7 +64,7 @@ static int do_font_size(struct cmd_tbl *cmdtp, int flag, int argc, if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev)) return CMD_RET_FAILURE; - ret = vidconsole_get_font_size(dev, &font_name, &size); + ret = vidconsole_get_font_size(dev, NULL, &font_name, &size); if (ret) { printf("Failed (error %d)\n", ret); return CMD_RET_FAILURE; diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 483639e65c4..c26a35e435d 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -319,7 +319,8 @@ int console_probe(struct udevice *dev) return 0; } -const char *console_simple_get_font_size(struct udevice *dev, uint *sizep) +const char *console_simple_get_font_size(struct udevice *dev, void *ctx, + uint *sizep) { struct console_simple_priv *priv = dev_get_priv(dev); diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index de2992ec748..f797dbe16f9 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1234,9 +1234,10 @@ static int truetype_get_cursor_info(struct udevice *dev, void *vctx) return 0; } -const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep) +const char *console_truetype_get_font_size(struct udevice *dev, void *vctx, + uint *sizep) { - struct console_tt_ctx *ctx = vidconsole_ctx(dev); + struct console_tt_ctx *ctx = vctx; if (ctx->cur_fontdata) { /* Using fixed font */ diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index b5a129d82b7..83872b54b5d 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -636,14 +636,17 @@ int vidconsole_get_font(struct udevice *dev, int seq, return ops->get_font(dev, seq, info); } -int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep) +int vidconsole_get_font_size(struct udevice *dev, void *ctx, const char **name, + uint *sizep) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); + if (!ctx) + ctx = vidconsole_ctx(dev); if (!ops->get_font_size) return -ENOSYS; - *name = ops->get_font_size(dev, sizep); + *name = ops->get_font_size(dev, ctx, sizep); return 0; } diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index 60ff7bed758..23d29fea081 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -170,7 +170,8 @@ int console_probe(struct udevice *dev); * Internal function to be used in as ops. * See details in video_console.h get_font_size function **/ -const char *console_simple_get_font_size(struct udevice *dev, uint *sizep); +const char *console_simple_get_font_size(struct udevice *dev, void *ctx, + uint *sizep); /** * Internal function to be used in as ops. diff --git a/include/video_console.h b/include/video_console.h index 500a5974a57..6d635fd5971 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -325,10 +325,12 @@ struct vidconsole_ops { * get_font_size() - get the current font name and size * * @dev: vidconsole device + * @ctx: vidconsole context to use (cannot be NULL) * @sizep: Place to put the font size (nominal height in pixels) * Returns: Current font name */ - const char *(*get_font_size)(struct udevice *dev, uint *sizep); + const char *(*get_font_size)(struct udevice *dev, void *ctx, + uint *sizep); /** * select_font() - Select a particular font by name / size @@ -842,11 +844,13 @@ void vidconsole_list_fonts(struct udevice *dev); * vidconsole_get_font_size() - get the current font name and size * * @dev: vidconsole device + * @ctx: vidconsole context to use (NULL to use default) * @sizep: Place to put the font size (nominal height in pixels) * @name: pointer to font name, a placeholder for result * Return: 0 if OK, -ENOSYS if not implemented in driver */ -int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep); +int vidconsole_get_font_size(struct udevice *dev, void *ctx, const char **name, + uint *sizep); /** * vidconsole_set_quiet() - Select whether the console should output stdio diff --git a/test/cmd/font.c b/test/cmd/font.c index 4991608e267..eab832347cb 100644 --- a/test/cmd/font.c +++ b/test/cmd/font.c @@ -43,7 +43,7 @@ static int font_test_base(struct unit_test_state *uts) ut_assert_console_end(); - ut_assertok(vidconsole_get_font_size(dev, &name, &size)); + ut_assertok(vidconsole_get_font_size(dev, NULL, &name, &size)); if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_ANKACODER)) ut_asserteq_str("ankacoder_c75_r", name); else if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE_NIMBUS)) @@ -71,7 +71,7 @@ static int font_test_base(struct unit_test_state *uts) ut_assertok(ret); ut_assert_console_end(); - ut_assertok(vidconsole_get_font_size(dev, &name, &size)); + ut_assertok(vidconsole_get_font_size(dev, NULL, &name, &size)); ut_asserteq_str("cantoraone_regular", name); ut_asserteq(40, size); ut_assertok(ut_check_console_end(uts)); @@ -90,7 +90,7 @@ static int font_test_base(struct unit_test_state *uts) ut_assertok(run_command("font select", 0)); ut_assertok(ut_check_console_end(uts)); - ut_assertok(vidconsole_get_font_size(dev, &name, &size)); + ut_assertok(vidconsole_get_font_size(dev, NULL, &name, &size)); ut_asserteq_str("nimbus_sans_l_regular", name); ut_asserteq(CONFIG_CONSOLE_TRUETYPE_SIZE, size); -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to draw_string() to allow passing in a specific vidconsole context. If NULL, the default context is used. Update all callers accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index 58be46cb7ee..6c70bd9038c 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -616,16 +616,25 @@ static void scene_render_background(struct scene_obj *obj, bool box_only, } } -static void draw_string(struct udevice *cons, const char *str, int len, - bool password) +/** + * draw_string() - Draw a string to the vidconsole + * + * @cons: Vidconsole device to draw to + * @ctx: Vidconsole context, or NULL to use default + * @str: String to draw + * @len: Length of string to draw + * @password: true to draw asterisks instead of actual characters + */ +static void draw_string(struct udevice *cons, void *ctx, const char *str, + int len, bool password) { if (password) { int i; for (i = 0; i < len; i++) - vidconsole_put_char(cons, NULL, '*'); + vidconsole_put_char(cons, ctx, '*'); } else { - vidconsole_put_stringn(cons, NULL, str, len); + vidconsole_put_stringn(cons, ctx, str, len); } } @@ -686,7 +695,7 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, if (!mline) { vidconsole_set_cursor_pos(cons, NULL, x, y); - draw_string(cons, str, strlen(str), + draw_string(cons, NULL, str, strlen(str), obj->flags & SCENEOF_PASSWORD); } @@ -705,7 +714,7 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, if (y > bbox.y1) break; /* clip this line and any following */ vidconsole_set_cursor_pos(cons, NULL, x, y); - draw_string(cons, str + mline->start, mline->len, + draw_string(cons, NULL, str + mline->start, mline->len, obj->flags & SCENEOF_PASSWORD); } if (obj->flags & SCENEOF_POINT) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to scene_txt_render() to allow passing in a specific vidconsole context. If NULL, the default context is used. Update the caller accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index 6c70bd9038c..b6879315563 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -638,8 +638,23 @@ static void draw_string(struct udevice *cons, void *ctx, const char *str, } } +/** + * scene_txt_render() - Render text to the vidconsole + * + * @exp: Expo to use + * @dev: Video device + * @cons: Vidconsole device + * @ctx: Vidconsole context, or NULL to use default + * @obj: Object to render + * @gen: Generic text info + * @x: X position in pixels + * @y: Y position in pixels + * @menu_inset: Inset for menu items + * Return: 0 if OK, -ve on error + */ static int scene_txt_render(struct expo *exp, struct udevice *dev, - struct udevice *cons, struct scene_obj *obj, + struct udevice *cons, void *ctx, + struct scene_obj *obj, struct scene_txt_generic *gen, int x, int y, int menu_inset) { @@ -656,10 +671,10 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, return -ENOTSUPP; if (gen->font_name || gen->font_size) { - ret = vidconsole_select_font(cons, NULL, gen->font_name, + ret = vidconsole_select_font(cons, ctx, gen->font_name, gen->font_size); } else { - ret = vidconsole_select_font(cons, NULL, NULL, 0); + ret = vidconsole_select_font(cons, ctx, NULL, 0); } if (ret && ret != -ENOSYS) return log_msg_ret("font", ret); @@ -694,8 +709,8 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, bbox.y1 = obj->bbox.y1; if (!mline) { - vidconsole_set_cursor_pos(cons, NULL, x, y); - draw_string(cons, NULL, str, strlen(str), + vidconsole_set_cursor_pos(cons, ctx, x, y); + draw_string(cons, ctx, str, strlen(str), obj->flags & SCENEOF_PASSWORD); } @@ -713,8 +728,8 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, y = obj->bbox.y0 + offset.yofs + mline->bbox.y0; if (y > bbox.y1) break; /* clip this line and any following */ - vidconsole_set_cursor_pos(cons, NULL, x, y); - draw_string(cons, NULL, str + mline->start, mline->len, + vidconsole_set_cursor_pos(cons, ctx, x, y); + draw_string(cons, ctx, str + mline->start, mline->len, obj->flags & SCENEOF_PASSWORD); } if (obj->flags & SCENEOF_POINT) @@ -761,8 +776,8 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) case SCENEOBJT_TEXT: { struct scene_obj_txt *txt = (struct scene_obj_txt *)obj; - ret = scene_txt_render(exp, dev, cons, obj, &txt->gen, x, y, - theme->menu_inset); + ret = scene_txt_render(exp, dev, cons, NULL, obj, &txt->gen, + x, y, theme->menu_inset); break; } case SCENEOBJT_MENU: { -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to scene_obj_render() to allow passing in a specific vidconsole context. If NULL, the default context is used. Update all callers accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index b6879315563..45550326d07 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -742,10 +742,11 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev, * scene_obj_render() - Render an object * * @obj: Object to render + * @ctx: Vidconsole context, or NULL to use default * @text_mode: true to use text mode * Return: 0 if OK, -ve on error */ -static int scene_obj_render(struct scene_obj *obj, bool text_mode) +static int scene_obj_render(struct scene_obj *obj, void *ctx, bool text_mode) { struct scene *scn = obj->scene; struct expo *exp = scn->expo; @@ -776,7 +777,7 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) case SCENEOBJT_TEXT: { struct scene_obj_txt *txt = (struct scene_obj_txt *)obj; - ret = scene_txt_render(exp, dev, cons, NULL, obj, &txt->gen, + ret = scene_txt_render(exp, dev, cons, ctx, obj, &txt->gen, x, y, theme->menu_inset); break; } @@ -978,7 +979,7 @@ int scene_render_obj(struct scene *scn, uint id) return log_msg_ret("obj", -ENOENT); if (!(obj->flags & SCENEOF_HIDE)) { - ret = scene_obj_render(obj, false); + ret = scene_obj_render(obj, NULL, false); if (ret && ret != -ENOTSUPP) return log_msg_ret("ren", ret); } @@ -998,7 +999,7 @@ int scene_render_deps(struct scene *scn, uint id) return log_msg_ret("obj", -ENOENT); if (!(obj->flags & SCENEOF_HIDE)) { - ret = scene_obj_render(obj, false); + ret = scene_obj_render(obj, NULL, false); if (ret && ret != -ENOTSUPP) return log_msg_ret("ren", ret); @@ -1094,7 +1095,7 @@ int scene_render(struct scene *scn, bool dirty_only) render = bbox_intersects(&obj->bbox, &dirty_bbox); if (render) { - ret = scene_obj_render(obj, exp->text_mode); + ret = scene_obj_render(obj, NULL, exp->text_mode); if (ret && ret != -ENOTSUPP) return log_msg_ret("ren", ret); } -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add a ctx parameter to scene_render_obj() to allow passing in a specific vidconsole context. If NULL, the default context is used. Update the caller accordingly. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene.c | 4 ++-- boot/scene_internal.h | 3 ++- boot/scene_txtin.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index 45550326d07..7cef20dbb1b 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -969,7 +969,7 @@ int scene_arrange(struct scene *scn) return 0; } -int scene_render_obj(struct scene *scn, uint id) +int scene_render_obj(struct scene *scn, uint id, void *ctx) { struct scene_obj *obj; int ret; @@ -979,7 +979,7 @@ int scene_render_obj(struct scene *scn, uint id) return log_msg_ret("obj", -ENOENT); if (!(obj->flags & SCENEOF_HIDE)) { - ret = scene_obj_render(obj, NULL, false); + ret = scene_obj_render(obj, ctx, false); if (ret && ret != -ENOTSUPP) return log_msg_ret("ren", ret); } diff --git a/boot/scene_internal.h b/boot/scene_internal.h index 733f0c0f6ca..d9ca1fef90e 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -348,9 +348,10 @@ int scene_send_click(struct scene *scn, int x, int y, struct expo_action *event) * * @scn: Scene containing the object * @id: Object ID to render + * @ctx: Vidconsole context, or NULL to use default * Returns: 0 if OK, -ENOENT if object not found, -ve on other error */ -int scene_render_obj(struct scene *scn, uint id); +int scene_render_obj(struct scene *scn, uint id, void *ctx); /** * scene_render_deps() - Render an object and its dependencies diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index da42f364f39..9b8edcc6439 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -75,7 +75,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj, ret = vidconsole_entry_restore(cons, &scn->entry_save); if (ret) return log_msg_ret("sav", ret); - scene_render_obj(scn, tin->edit_id); + scene_render_obj(scn, tin->edit_id, NULL); /* move cursor back to the correct position */ for (i = cls->num; i < cls->eol_num; i++) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Add an alist to track all client-allocated contexts in the vidconsole. This ensures that contexts can be properly cleaned up when the device is removed. Update vidconsole_ctx_new() to add newly created contexts to the list and vidconsole_ctx_dispose() to remove them. Init the list in vidconsole_pre_probe() and dispose of any remaining contexts in vidconsole_pre_remove() Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/vidconsole-uclass.c | 65 ++++++++++++++++++++++++------- include/video_console.h | 2 + 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 83872b54b5d..4433920ecb6 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -712,32 +712,64 @@ int vidconsole_nominal(struct udevice *dev, const char *name, uint size, int vidconsole_ctx_new(struct udevice *dev, void **ctxp) { + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_ops *ops = vidconsole_get_ops(dev); - void *ctx; + void **ptr; int ret; if (!ops->ctx_new) return -ENOSYS; - ret = ops->ctx_new(dev, &ctx); - if (ret) + /* reserve space first so ctx_new failure doesn't need cleanup */ + ptr = alist_add_placeholder(&priv->ctx_list); + if (!ptr) + return -ENOMEM; + + ret = ops->ctx_new(dev, ptr); + if (ret) { + priv->ctx_list.count--; return ret; - *ctxp = ctx; + } + *ctxp = *ptr; return 0; } -int vidconsole_ctx_dispose(struct udevice *dev, void *ctx) +/** + * vidconsole_free_ctx() - Free a context without removing it from the list + * + * This calls the driver's ctx_dispose method and frees the save_data, but + * does not remove the context from the alist. + * + * @dev: Vidconsole device + * @ctx: Context to free + */ +static void vidconsole_free_ctx(struct udevice *dev, struct vidconsole_ctx *ctx) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); - int ret; - if (!ops->ctx_dispose) - return -ENOSYS; + if (ops->ctx_dispose) + ops->ctx_dispose(dev, ctx); + free(ctx->curs.save_data); +} - ret = ops->ctx_dispose(dev, ctx); - if (ret) - return ret; +int vidconsole_ctx_dispose(struct udevice *dev, void *vctx) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + struct vidconsole_ctx *ctx = vctx; + void **ptr, **from; + + if (!ctx) + return 0; + + /* remove the context from the list */ + alist_for_each_filter(ptr, from, &priv->ctx_list) { + if (*ptr != ctx) + *from++ = *ptr; + } + alist_update_end(&priv->ctx_list, from); + + vidconsole_free_ctx(dev, ctx); return 0; } @@ -903,6 +935,9 @@ static int vidconsole_pre_probe(struct udevice *dev) ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); + alist_init_struct(&priv->ctx_list, void *); + alist_add(&priv->ctx_list, ctx); + return 0; } @@ -934,10 +969,12 @@ static int vidconsole_post_probe(struct udevice *dev) static int vidconsole_pre_remove(struct udevice *dev) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = priv->ctx; + void **ptr; - free(ctx->curs.save_data); - free(ctx); + /* free all contexts in the list, including the default ctx */ + alist_for_each(ptr, &priv->ctx_list) + vidconsole_free_ctx(dev, *ptr); + alist_uninit(&priv->ctx_list); priv->ctx = NULL; return 0; diff --git a/include/video_console.h b/include/video_console.h index 6d635fd5971..8d2f0510534 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -166,11 +166,13 @@ struct vidconsole_uc_plat { * * @sdev: stdio device, acting as an output sink * @ctx: Per-client context (allocated by the uclass) + * @ctx_list: List of additional contexts allocated by clients * @quiet: Suppress all output from stdio */ struct vidconsole_priv { struct stdio_dev sdev; struct vidconsole_ctx *ctx; + struct alist ctx_list; bool quiet; }; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Both console_core.c and console_truetype.c call console_alloc_cursor() to set up the cursor-save buffer. This duplication can be avoided by moving the call into vidconsole_post_probe() where it benefits all drivers. Move cursor allocation into the uclass and remove the calls from the individual drivers. Also reorder vidconsole_free_ctx() to free the cursor save_data before calling ctx_dispose(), since the cursor is now owned by the uclass rather than the driver. Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_core.c | 6 ------ drivers/video/console_truetype.c | 4 ---- drivers/video/vidconsole-uclass.c | 12 ++++++++++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index c26a35e435d..0580e2661de 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -310,12 +310,6 @@ int console_probe(struct udevice *dev) if (ret) return ret; - if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { - ret = console_alloc_cursor(dev, vidconsole_ctx(dev)); - if (ret) - return ret; - } - return 0; } diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index f797dbe16f9..ae7e7d0ec58 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1302,10 +1302,6 @@ static int console_truetype_probe(struct udevice *dev) debug("%s: ready\n", __func__); - ret = console_alloc_cursor(dev, &ctx->com); - if (ret) - return ret; - return 0; } diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 4433920ecb6..83cd1651205 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -13,9 +13,10 @@ #include <charset.h> #include <command.h> #include <console.h> +#include <dm.h> #include <log.h> #include <malloc.h> -#include <dm.h> +#include <spl.h> #include <video.h> #include <video_console.h> #include "vidconsole_internal.h" @@ -748,9 +749,9 @@ static void vidconsole_free_ctx(struct udevice *dev, struct vidconsole_ctx *ctx) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); + free(ctx->curs.save_data); if (ops->ctx_dispose) ops->ctx_dispose(dev, ctx); - free(ctx->curs.save_data); } int vidconsole_ctx_dispose(struct udevice *dev, void *vctx) @@ -947,6 +948,13 @@ static int vidconsole_post_probe(struct udevice *dev) struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); struct stdio_dev *sdev = &priv->sdev; + int ret; + + if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { + ret = console_alloc_cursor(dev, ctx); + if (ret) + return ret; + } if (!ctx->tab_width_frac) ctx->tab_width_frac = VID_TO_POS(ctx->x_charsize) * 8; -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Change console_alloc_cursor() to take a struct vidconsole_cursor pointer directly instead of the full context, since that is not needed. This allows the function to be used a cursor embedded in a larger struct. Add a matching console_free_cursor() function to free the cursor's save_data buffer. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_core.c | 9 ++++++--- drivers/video/vidconsole-uclass.c | 4 ++-- drivers/video/vidconsole_internal.h | 13 +++++++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 0580e2661de..6bd7dc263e6 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -280,9 +280,8 @@ int cursor_hide(struct vidconsole_cursor *curs, struct video_priv *vid_priv, return 0; } -int console_alloc_cursor(struct udevice *dev, struct vidconsole_ctx *ctx) +int console_alloc_cursor(struct udevice *dev, struct vidconsole_cursor *curs) { - struct vidconsole_cursor *curs; struct video_priv *vid_priv; struct udevice *vid; int save_count; @@ -291,7 +290,6 @@ int console_alloc_cursor(struct udevice *dev, struct vidconsole_ctx *ctx) return 0; vid = dev_get_parent(dev); vid_priv = dev_get_uclass_priv(vid); - curs = &ctx->curs; /* Allocate cursor save buffer for maximum possible cursor height */ save_count = vid_priv->ysize * VIDCONSOLE_CURSOR_WIDTH; @@ -302,6 +300,11 @@ int console_alloc_cursor(struct udevice *dev, struct vidconsole_ctx *ctx) return 0; } +void console_free_cursor(struct vidconsole_cursor *curs) +{ + free(curs->save_data); +} + int console_probe(struct udevice *dev) { int ret; diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 83cd1651205..b22408dc2a4 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -749,7 +749,7 @@ static void vidconsole_free_ctx(struct udevice *dev, struct vidconsole_ctx *ctx) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); - free(ctx->curs.save_data); + console_free_cursor(&ctx->curs); if (ops->ctx_dispose) ops->ctx_dispose(dev, ctx); } @@ -951,7 +951,7 @@ static int vidconsole_post_probe(struct udevice *dev) int ret; if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { - ret = console_alloc_cursor(dev, ctx); + ret = console_alloc_cursor(dev, &ctx->curs); if (ret) return ret; } diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index 23d29fea081..b5ffdfad4da 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -152,10 +152,19 @@ int cursor_hide(struct vidconsole_cursor *curs, struct video_priv *vid_priv, * Allocates memory for saving pixels under the cursor * * @dev: vidconsole device - * @ctx: vidconsole context + * @curs: cursor to set up * Return: 0 if success, -ENOMEM if allocation fails */ -int console_alloc_cursor(struct udevice *dev, struct vidconsole_ctx *ctx); +int console_alloc_cursor(struct udevice *dev, struct vidconsole_cursor *curs); + +/** + * console_free_cursor() - Free cursor memory + * + * Free the memory used by a cursor + * + * @curs: cursor to set up + */ +void console_free_cursor(struct vidconsole_cursor *curs); /** * console probe function. -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Move the responsibility for freeing context memory from the driver's ctx_dispose() method to the uclass's vidconsole_free_ctx(). This simplifies the drivers since they no longer need to implement ctx_dispose() just to call free(). The ctx_dispose() method is still called if present, but only needs to handle driver-specific cleanup. The uclass handles freeing the cursor and the context memory. Also remove the console_probe() reference from console_normal since the uclass handles all probe setup. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_normal.c | 9 --------- drivers/video/console_truetype.c | 8 -------- drivers/video/vidconsole-uclass.c | 3 ++- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index 5f57b3403f1..c3b7f848b43 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -191,13 +191,6 @@ static int console_simple_ctx_new(struct udevice *dev, void **ctxp) return 0; } -static int console_simple_ctx_dispose(struct udevice *dev, void *ctx) -{ - free(ctx); - - return 0; -} - struct vidconsole_ops console_ops = { .putc_xy = console_putc_xy, .move_rows = console_move_rows, @@ -206,7 +199,6 @@ struct vidconsole_ops console_ops = { .get_font = console_simple_get_font, .select_font = console_simple_select_font, .ctx_new = console_simple_ctx_new, - .ctx_dispose = console_simple_ctx_dispose, #ifdef CONFIG_CURSOR .get_cursor_info = console_get_cursor_info, .entry_save = normal_entry_save, @@ -218,6 +210,5 @@ U_BOOT_DRIVER(vidconsole_normal) = { .name = "vidconsole0", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_ops, - .probe = console_probe, .priv_auto = sizeof(struct console_simple_priv), }; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index ae7e7d0ec58..4cf7ffebef3 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1157,13 +1157,6 @@ static int truetype_ctx_new(struct udevice *dev, void **ctxp) return 0; } -static int truetype_ctx_dispose(struct udevice *dev, void *ctx) -{ - free(ctx); - - return 0; -} - static int truetype_entry_save(struct udevice *dev, struct abuf *buf) { struct console_tt_ctx *ctx = vidconsole_ctx(dev); @@ -1327,7 +1320,6 @@ struct vidconsole_ops console_truetype_ops = { .measure = truetype_measure, .nominal = truetype_nominal, .ctx_new = truetype_ctx_new, - .ctx_dispose = truetype_ctx_dispose, .entry_save = truetype_entry_save, .entry_restore = truetype_entry_restore, .get_cursor_info = truetype_get_cursor_info, diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index b22408dc2a4..147063c4d38 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -749,9 +749,10 @@ static void vidconsole_free_ctx(struct udevice *dev, struct vidconsole_ctx *ctx) { struct vidconsole_ops *ops = vidconsole_get_ops(dev); - console_free_cursor(&ctx->curs); if (ops->ctx_dispose) ops->ctx_dispose(dev, ctx); + console_free_cursor(&ctx->curs); + free(ctx); } int vidconsole_ctx_dispose(struct udevice *dev, void *vctx) -- 2.43.0
From: Simon Glass <simon.glass@canonical.com> Currently each driver allocates its own vidconsole context in its ctx_new() method. This leads to duplication and makes it harder to ensure consistent context setup. Move the responsibility for allocating contexts to the uclass. The ctx_new() ops method now receives an already-allocated context and just needs to initialise driver-specific fields. The uclass now handles: - Allocating memory using plat->ctx_size - Setting up xsize_frac from the video device - Allocating the cursor-save buffer if cursor support is enabled - Calling the driver's ctx_new() for driver-specific initialisation Move the default context creation from vidconsole_pre_probe() to vidconsole_post_probe() using vidconsole_ctx_new(). This allows additional contexts to be set up by calling the same function. For bitmap font drivers, rename console_probe() to console_simple_ctx_new() and move struct console_ctx to vidconsole_internal.h so it can be shared. For the truetype driver, move font selection from console_truetype_probe() to truetype_ctx_new(), using the first font initially. Also fix vidconsole_set_bitmap_font() to always set xsize_frac rather than relying on it being set in vidconsole_pre_probe(). This is a rather large 'flag day' change but it has resisted being broken up further. Signed-off-by: Simon Glass <simon.glass@canonical.com> --- drivers/video/console_core.c | 5 ++- drivers/video/console_normal.c | 22 ---------- drivers/video/console_rotate.c | 6 +-- drivers/video/console_truetype.c | 17 +++----- drivers/video/vidconsole-uclass.c | 64 +++++++++++++++++------------ drivers/video/vidconsole_internal.h | 22 ++++++++++ include/video_console.h | 12 +++--- 7 files changed, 77 insertions(+), 71 deletions(-) diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index 6bd7dc263e6..ee07ffc98e4 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -305,11 +305,12 @@ void console_free_cursor(struct vidconsole_cursor *curs) free(curs->save_data); } -int console_probe(struct udevice *dev) +int console_simple_ctx_new(struct udevice *dev, void *vctx) { + struct console_ctx *ctx = vctx; int ret; - ret = console_set_font(dev, vidconsole_ctx(dev), fonts); + ret = console_set_font(dev, &ctx->com, fonts); if (ret) return ret; diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c index c3b7f848b43..d36a5c0ff8f 100644 --- a/drivers/video/console_normal.c +++ b/drivers/video/console_normal.c @@ -15,14 +15,6 @@ #include <video_font.h> /* Get font data, width and height */ #include "vidconsole_internal.h" -/** - * struct console_ctx - context for the normal console - * - * @com: Common fields from the vidconsole uclass - */ -struct console_ctx { - struct vidconsole_ctx com; -}; static int console_set_row(struct udevice *dev, uint row, int clr) { @@ -177,20 +169,6 @@ static int console_putc_xy(struct udevice *dev, void *vctx, uint x_frac, return console_normal_putc_xy(dev, vctx, x_frac, y, cp); } -static int console_simple_ctx_new(struct udevice *dev, void **ctxp) -{ - struct console_ctx *ctx; - - ctx = malloc(sizeof(*ctx)); - if (!ctx) - return -ENOMEM; - - memset(ctx, '\0', sizeof(*ctx)); - *ctxp = ctx; - - return 0; -} - struct vidconsole_ops console_ops = { .putc_xy = console_putc_xy, .move_rows = console_move_rows, diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c index 42c9de888d8..77c814fa09e 100644 --- a/drivers/video/console_rotate.c +++ b/drivers/video/console_rotate.c @@ -294,6 +294,7 @@ struct vidconsole_ops console_ops_1 = { .get_font_size = console_simple_get_font_size, .get_font = console_simple_get_font, .select_font = console_simple_select_font, + .ctx_new = console_simple_ctx_new, }; struct vidconsole_ops console_ops_2 = { @@ -303,6 +304,7 @@ struct vidconsole_ops console_ops_2 = { .get_font_size = console_simple_get_font_size, .get_font = console_simple_get_font, .select_font = console_simple_select_font, + .ctx_new = console_simple_ctx_new, }; struct vidconsole_ops console_ops_3 = { @@ -312,13 +314,13 @@ struct vidconsole_ops console_ops_3 = { .get_font_size = console_simple_get_font_size, .get_font = console_simple_get_font, .select_font = console_simple_select_font, + .ctx_new = console_simple_ctx_new, }; U_BOOT_DRIVER(vidconsole_1) = { .name = "vidconsole1", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_ops_1, - .probe = console_probe, .priv_auto = sizeof(struct console_simple_priv), }; @@ -326,7 +328,6 @@ U_BOOT_DRIVER(vidconsole_2) = { .name = "vidconsole2", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_ops_2, - .probe = console_probe, .priv_auto = sizeof(struct console_simple_priv), }; @@ -334,6 +335,5 @@ U_BOOT_DRIVER(vidconsole_3) = { .name = "vidconsole3", .id = UCLASS_VIDEO_CONSOLE, .ops = &console_ops_3, - .probe = console_probe, .priv_auto = sizeof(struct console_simple_priv), }; diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 4cf7ffebef3..25cc8241bf7 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -1143,16 +1143,15 @@ static int truetype_nominal(struct udevice *dev, const char *name, uint size, return 0; } -static int truetype_ctx_new(struct udevice *dev, void **ctxp) +static int truetype_ctx_new(struct udevice *dev, void *vctx) { - struct console_tt_ctx *ctx; + struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_ctx *ctx = vctx; - ctx = malloc(sizeof(*ctx)); - if (!ctx) - return -ENOMEM; + /* use the first set of metrics by default */ + ctx->cur_met = &priv->metrics[0]; - memset(ctx, '\0', sizeof(*ctx)); - *ctxp = ctx; + select_metrics(dev, ctx, ctx->cur_met); return 0; } @@ -1256,7 +1255,6 @@ static int truetype_mark_start(struct udevice *dev, void *vctx) 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); @@ -1289,9 +1287,6 @@ 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); - ctx->cur_met = &priv->metrics[ret]; - - select_metrics(dev, ctx, &priv->metrics[ret]); debug("%s: ready\n", __func__); diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 147063c4d38..b6bd3133037 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -713,10 +713,14 @@ int vidconsole_nominal(struct udevice *dev, const char *name, uint size, int vidconsole_ctx_new(struct udevice *dev, void **ctxp) { + struct udevice *vid = dev->parent; + struct video_priv *vid_priv = dev_get_uclass_priv(vid); + struct vidconsole_uc_plat *plat = dev_get_uclass_plat(dev); struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct vidconsole_ops *ops = vidconsole_get_ops(dev); + struct vidconsole_ctx *ctx; + int ret = -ENOMEM, size; void **ptr; - int ret; if (!ops->ctx_new) return -ENOSYS; @@ -726,14 +730,35 @@ int vidconsole_ctx_new(struct udevice *dev, void **ctxp) if (!ptr) return -ENOMEM; - ret = ops->ctx_new(dev, ptr); - if (ret) { - priv->ctx_list.count--; - return ret; + size = plat->ctx_size ?: sizeof(struct vidconsole_ctx); + ctx = calloc(1, size); + if (!ctx) + goto err_alloc; + *ptr = ctx; + + if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { + ret = console_alloc_cursor(dev, &ctx->curs); + if (ret) + goto err_curs; } - *ctxp = *ptr; + + ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); + + ret = ops->ctx_new(dev, ctx); + if (ret) + goto err_new; + *ctxp = ctx; return 0; + +err_new: + console_free_cursor(&ctx->curs); +err_curs: +err_alloc: + priv->ctx_list.count--; + free(ctx); + + return ret; } /** @@ -922,23 +947,9 @@ 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_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); alist_init_struct(&priv->ctx_list, void *); - alist_add(&priv->ctx_list, ctx); return 0; } @@ -947,15 +958,14 @@ static int vidconsole_pre_probe(struct udevice *dev) static int vidconsole_post_probe(struct udevice *dev) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); - struct vidconsole_ctx *ctx = vidconsole_ctx_from_priv(priv); struct stdio_dev *sdev = &priv->sdev; + struct vidconsole_ctx *ctx; int ret; - if (CONFIG_IS_ENABLED(CURSOR) && xpl_phase() == PHASE_BOARD_R) { - ret = console_alloc_cursor(dev, &ctx->curs); - if (ret) - return ret; - } + ret = vidconsole_ctx_new(dev, (void **)&ctx); + if (ret) + return ret; + priv->ctx = ctx; if (!ctx->tab_width_frac) ctx->tab_width_frac = VID_TO_POS(ctx->x_charsize) * 8; @@ -1049,7 +1059,7 @@ void vidconsole_set_bitmap_font(struct udevice *dev, struct vidconsole_ctx *ctx, } else { ctx->cols = vid_priv->xsize / fontdata->width; ctx->rows = vid_priv->ysize / fontdata->height; - /* xsize_frac is set in vidconsole_pre_probe() */ + ctx->xsize_frac = VID_TO_POS(vid_priv->xsize); } ctx->xstart_frac = 0; } diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h index b5ffdfad4da..439192ecc1e 100644 --- a/drivers/video/vidconsole_internal.h +++ b/drivers/video/vidconsole_internal.h @@ -8,6 +8,7 @@ #include <charset.h> #include <config.h> +#include <video_console.h> struct udevice; struct vidconsole_cursor; @@ -25,6 +26,15 @@ struct console_simple_priv { struct video_fontdata *fontdata; }; +/** + * struct console_ctx - context for the normal console + * + * @com: Common fields from the vidconsole uclass + */ +struct console_ctx { + struct vidconsole_ctx com; +}; + /** * Checks if bits per pixel supported. * @@ -237,3 +247,15 @@ static inline u8 console_utf_to_cp437(int codepoint) } return codepoint; } + +/** + * console_simple_ctx_new() - Set up a new context for bitmap-font consoles + * + * Initialises the context with the default bitmap font. This is the ctx_new() + * method for bitmap-font console drivers. + * + * @dev: Vidconsole device + * @ctx: Context to initialise (allocated by the uclass) + * Return: 0 on success, -ve on error + */ +int console_simple_ctx_new(struct udevice *dev, void *ctx); diff --git a/include/video_console.h b/include/video_console.h index 8d2f0510534..c047d45cf53 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -384,16 +384,16 @@ struct vidconsole_ops { uint num_chars, struct vidconsole_bbox *bbox); /** - * ctx_new() - Create a new context for a client + * ctx_new() - Initialise a new context for a client * - * Allocates and initialises a context for a client of the vidconsole. - * The driver determines what information is stored in the context. + * Initialises driver-specific fields of a pre-allocated context. The + * base vidconsole_ctx fields are already initialised by the uclass. * * @dev: Console device to use - * @ctxp: Returns new context, on success - * Return: 0 on success, -ENOMEM if out of memory + * @ctx: Pre-allocated context to initialise + * Return: 0 on success, -ve on error */ - int (*ctx_new)(struct udevice *dev, void **ctxp); + int (*ctx_new)(struct udevice *dev, void *ctx); /** * ctx_dispose() - Dispose of a context -- 2.43.0
participants (1)
-
Simon Glass