From: Simon Glass <simon.glass@canonical.com> Currently text-input objects (textline, textedit) use the default vidconsole context (NULL). This causes the cursor state to be shared with other vidconsole operations, leading to interference. Add a dedicated vidconsole context (ctx) to struct scene_txtin and use it for all vidconsole operations. The context is created when the text-input is opened and disposed when the object is destroyed. Also add scene_txtin_destroy() to properly clean up the text buffer and vidconsole context when text-input objects are destroyed. Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com> --- boot/scene.c | 3 +++ boot/scene_internal.h | 10 ++++++++++ boot/scene_txtin.c | 37 ++++++++++++++++++++++++++++--------- include/expo.h | 2 ++ 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index 7cef20dbb1b..1ea0d1b1c46 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -108,6 +108,9 @@ void scene_obj_destroy(struct scene_obj *obj) { if (obj->type == SCENEOBJT_MENU) scene_menu_destroy((struct scene_obj_menu *)obj); + else if (obj->type == SCENEOBJT_TEXTLINE || + obj->type == SCENEOBJT_TEXTEDIT) + scene_txtin_destroy(obj->scene, scene_obj_txtin(obj)); free(obj->name); free(obj); } diff --git a/boot/scene_internal.h b/boot/scene_internal.h index 71cbc85c358..3c22b10c2f4 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -521,6 +521,16 @@ void scene_menu_calc_bbox(struct scene_obj_menu *menu, */ int scene_txtin_init(struct scene_txtin *tin, uint size, uint line_chars); +/** + * scene_txtin_destroy() - Destroy a text-input object's resources + * + * Frees memory allocated for the text buffer and vidconsole context + * + * @scn: Scene containing the object + * @tin: Text-input info to destroy + */ +void scene_txtin_destroy(struct scene *scn, struct scene_txtin *tin); + /** * scene_txtin_arrange() - Arrange common parts of a text-input object * diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c index 1dfa3a02a6a..457d782b4cf 100644 --- a/boot/scene_txtin.c +++ b/boot/scene_txtin.c @@ -14,6 +14,7 @@ #include <menu.h> #include <video_console.h> #include <linux/errno.h> +#include <linux/kernel.h> #include <linux/string.h> #include "scene_internal.h" @@ -30,6 +31,13 @@ int scene_txtin_init(struct scene_txtin *tin, uint size, uint line_chars) return 0; } +void scene_txtin_destroy(struct scene *scn, struct scene_txtin *tin) +{ + abuf_uninit(&tin->buf); + if (tin->ctx && scn->expo->cons) + vidconsole_ctx_dispose(scn->expo->cons, tin->ctx); +} + int scene_txtin_arrange(struct scene *scn, struct expo_arrange_info *arr, struct scene_obj *obj, struct scene_txtin *tin) { @@ -66,6 +74,7 @@ int scene_txtin_render_deps(struct scene *scn, struct scene_obj *obj, struct cli_line_state *cls = &tin->cls; const bool open = obj->flags & SCENEOF_OPEN; struct udevice *cons = scn->expo->cons; + void *ctx = tin->ctx; uint i; /* if open, render the edit text on top of the background */ @@ -75,16 +84,16 @@ 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, NULL); + scene_render_obj(scn, tin->edit_id, ctx); /* move cursor back to the correct position */ for (i = cls->num; i < cls->eol_num; i++) - vidconsole_put_char(cons, NULL, '\b'); + vidconsole_put_char(cons, ctx, '\b'); ret = vidconsole_entry_save(cons, &scn->entry_save); if (ret) return log_msg_ret("sav", ret); - vidconsole_show_cursor(cons, NULL); + vidconsole_show_cursor(cons, ctx); } return 0; @@ -101,15 +110,16 @@ 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_txtin *tin = container_of(cls, struct scene_txtin, cls); struct scene *scn = cls->priv; - vidconsole_put_char(scn->expo->cons, NULL, ch); + vidconsole_put_char(scn->expo->cons, tin->ctx, ch); } void scene_txtin_close(struct scene *scn, struct scene_txtin *tin) { /* cursor is not needed now */ - vidconsole_readline_end(scn->expo->cons, NULL); + vidconsole_readline_end(scn->expo->cons, tin->ctx); } int scene_txtin_open(struct scene *scn, struct scene_obj *obj, @@ -118,8 +128,17 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, struct cli_line_state *cls = &tin->cls; struct udevice *cons = scn->expo->cons; struct scene_obj_txt *txt; + void *ctx; int ret; + ctx = tin->ctx; + if (!ctx) { + ret = vidconsole_ctx_new(cons, &ctx); + if (ret) + return log_msg_ret("ctx", ret); + tin->ctx = ctx; + } + /* Copy the text into the scene buffer in case the edit is cancelled */ memcpy(abuf_data(&scn->buf), abuf_data(&tin->buf), abuf_size(&scn->buf)); @@ -129,8 +148,8 @@ int scene_txtin_open(struct scene *scn, struct scene_obj *obj, if (!txt) return log_msg_ret("cur", -ENOENT); - vidconsole_set_cursor_pos(cons, NULL, txt->obj.bbox.x0, txt->obj.bbox.y0); - vidconsole_entry_start(cons, NULL); + vidconsole_set_cursor_pos(cons, ctx, txt->obj.bbox.x0, txt->obj.bbox.y0); + vidconsole_entry_start(cons, ctx); cli_cread_init(cls, abuf_data(&tin->buf), tin->line_chars); cls->insert = true; cls->putch = scene_txtin_putch; @@ -141,7 +160,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, NULL, true); + vidconsole_readline_start(cons, ctx, true); return 0; } @@ -180,7 +199,7 @@ int scene_txtin_send_key(struct scene_obj *obj, struct scene_txtin *tin, memcpy(abuf_data(&tin->buf), abuf_data(&scn->buf), abuf_size(&scn->buf)); - scene_txtin_close(scn, NULL); + scene_txtin_close(scn, tin); } else { event->type = EXPOACT_QUIT; log_debug("menu quit\n"); diff --git a/include/expo.h b/include/expo.h index afaf1e8d107..adbe02922ab 100644 --- a/include/expo.h +++ b/include/expo.h @@ -509,6 +509,7 @@ 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 + * @ctx: Vidconsole context for this text-input object * @cls: CLI line state for text editing */ struct scene_txtin { @@ -516,6 +517,7 @@ struct scene_txtin { uint edit_id; uint line_chars; struct abuf buf; + void *ctx; struct cli_line_state cls; }; -- 2.43.0