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