[Concept,14/19] expo: Convert BKEY_UP/DOWN to control characters for text input

Message ID 20260130035849.3580212-15-simon.glass@canonical.com
State New
Headers
Series Enhanced command-line editing with undo/redo support |

Commit Message

Simon Glass Jan. 30, 2026, 3:58 a.m. UTC
  The expo keyboard handling converts arrow keys to BKEY_UP and BKEY_DOWN
before sending them to scene objects. However, cread_line_process_ch()
expects CTL_CH('p') and CTL_CH('n') for line navigation in multiline
text editors.

Add explicit handling for BKEY_UP and BKEY_DOWN in scene_txtin_send_key()
to convert them back to the control characters that cread_line_process_ch()
expects. This fixes arrow key navigation in textedit objects.

Update the editenv_test_video() to use a longer string and a larger font
size so we can test this.

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

 boot/scene_txtin.c  |  6 ++++++
 test/boot/editenv.c | 26 ++++++++++++++++++--------
 2 files changed, 24 insertions(+), 8 deletions(-)
  

Patch

diff --git a/boot/scene_txtin.c b/boot/scene_txtin.c
index 79814891cdc..8b49daddd56 100644
--- a/boot/scene_txtin.c
+++ b/boot/scene_txtin.c
@@ -349,6 +349,12 @@  int scene_txtin_send_key(struct scene_obj *obj, struct scene_txtin *tin,
 		event->select.id = obj->id;
 		scene_txtin_close(scn, tin);
 		break;
+	case BKEY_UP:
+		cread_line_process_ch(cls, CTL_CH('p'));
+		break;
+	case BKEY_DOWN:
+		cread_line_process_ch(cls, CTL_CH('n'));
+		break;
 	default:
 		cread_line_process_ch(cls, key);
 		break;
diff --git a/test/boot/editenv.c b/test/boot/editenv.c
index 62a33f1ba0f..0f9db54474d 100644
--- a/test/boot/editenv.c
+++ b/test/boot/editenv.c
@@ -124,23 +124,33 @@  static int editenv_test_escape(struct unit_test_state *uts)
 }
 BOOTSTD_TEST(editenv_test_escape, UTF_DM | UTF_SCAN_FDT | UTF_CONSOLE);
 
-/* Check expo_editenv() renders correctly */
+/* Check expo_editenv() renders correctly with multiline text and navigation */
 static int editenv_test_video(struct unit_test_state *uts)
 {
-	struct udevice *dev;
-	char buf[256];
+	struct udevice *dev, *con;
+	char buf[512];
 	int ret;
 
 	ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev));
+	ut_assertok(uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &con));
 
-	/* Type "abc" then press Enter */
-	console_in_puts("abc\x0d");
-	ret = expo_editenv("testvar", "initial", buf, sizeof(buf));
+	/* Set font size to 30 */
+	ut_assertok(vidconsole_select_font(con, NULL, NULL, 30));
+
+	/*
+	 * Navigate with up arrow, insert text, then press Enter. The up arrow
+	 * should be converted to Ctrl-P by scene_txtin_send_key().
+	 * \x1b[A is the escape sequence for up arrow
+	 */
+	console_in_puts("\x1b[A!\x0d");
+	ret = expo_editenv("testvar", initial, buf, sizeof(buf));
 	ut_assertok(ret);
-	ut_asserteq_str("initialabc", buf);
+
+	/* The '!' should be inserted one visual line up from the end */
+	ut_assert(strstr(buf, "tes!ted"));
 
 	/* Check the framebuffer has expected content */
-	ut_asserteq(1029, video_compress_fb(uts, dev, false));
+	ut_asserteq(16829, video_compress_fb(uts, dev, false));
 
 	return 0;
 }