"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

expo: Begin implementation of a text editor

It is useful to be able to edit text, e.g. to allow the user to edit the
environment or the command-line arguments for the OS.

Add the beginnings of an implementation. Future work is needed to finish
this: keypress handling and scrolling. For now it just displays the
text.

Signed-off-by: Simon Glass <sjg@chromium.org>

Simon Glass e005f18b 09f6f915

+164 -4
+1 -1
boot/Makefile
··· 58 58 obj-$(CONFIG_$(PHASE_)LOAD_FIT) += common_fit.o 59 59 60 60 obj-$(CONFIG_$(PHASE_)EXPO) += expo.o scene.o expo_build.o 61 - obj-$(CONFIG_$(PHASE_)EXPO) += scene_menu.o scene_textline.o 61 + obj-$(CONFIG_$(PHASE_)EXPO) += scene_menu.o scene_textline.o scene_textedit.o 62 62 ifdef CONFIG_COREBOOT_SYSINFO 63 63 obj-$(CONFIG_$(PHASE_)EXPO) += expo_build_cb.o 64 64 endif
+5
boot/cedit.c
··· 82 82 case SCENEOBJT_IMAGE: 83 83 case SCENEOBJT_TEXT: 84 84 case SCENEOBJT_BOX: 85 + case SCENEOBJT_TEXTEDIT: 85 86 break; 86 87 case SCENEOBJT_MENU: 87 88 scene_obj_set_pos(scn, obj->id, 50, y); ··· 383 384 case SCENEOBJT_IMAGE: 384 385 case SCENEOBJT_TEXT: 385 386 case SCENEOBJT_BOX: 387 + case SCENEOBJT_TEXTEDIT: 386 388 break; 387 389 case SCENEOBJT_TEXTLINE: { 388 390 const struct scene_obj_textline *tline; ··· 483 485 case SCENEOBJT_IMAGE: 484 486 case SCENEOBJT_TEXT: 485 487 case SCENEOBJT_BOX: 488 + case SCENEOBJT_TEXTEDIT: 486 489 break; 487 490 case SCENEOBJT_TEXTLINE: { 488 491 const struct scene_obj_textline *tline; ··· 555 558 case SCENEOBJT_IMAGE: 556 559 case SCENEOBJT_TEXT: 557 560 case SCENEOBJT_BOX: 561 + case SCENEOBJT_TEXTEDIT: 558 562 break; 559 563 case SCENEOBJT_MENU: 560 564 menu = (struct scene_obj_menu *)obj; ··· 639 643 case SCENEOBJT_IMAGE: 640 644 case SCENEOBJT_TEXT: 641 645 case SCENEOBJT_BOX: 646 + case SCENEOBJT_TEXTEDIT: 642 647 break; 643 648 case SCENEOBJT_MENU: 644 649 menu = (struct scene_obj_menu *)obj;
+28 -2
boot/scene.c
··· 417 417 *widthp = width; 418 418 return height; 419 419 } 420 - case SCENEOBJT_TEXT: { 421 - struct scene_txt_generic *gen = &((struct scene_obj_txt *)obj)->gen; 420 + case SCENEOBJT_TEXT: 421 + case SCENEOBJT_TEXTEDIT: { 422 + struct scene_txt_generic *gen; 422 423 struct expo *exp = scn->expo; 423 424 struct vidconsole_bbox bbox; 424 425 int len, ret, limit; 425 426 const char *str; 427 + 428 + if (obj->type == SCENEOBJT_TEXT) 429 + gen = &((struct scene_obj_txt *)obj)->gen; 430 + else 431 + gen = &((struct scene_obj_txtedit *)obj)->gen; 426 432 427 433 str = expo_get_str(exp, gen->str_id); 428 434 if (!str) ··· 658 664 obj->bbox.y1, box->width, vid_priv->colour_fg); 659 665 break; 660 666 } 667 + case SCENEOBJT_TEXTEDIT: { 668 + struct scene_obj_txtedit *ted = (struct scene_obj_txtedit *)obj; 669 + 670 + ret = scene_txt_render(exp, dev, cons, obj, &ted->gen, x, y, 671 + theme->menu_inset); 672 + break; 673 + } 661 674 } 662 675 663 676 return 0; ··· 677 690 case SCENEOBJT_IMAGE: 678 691 case SCENEOBJT_TEXT: 679 692 case SCENEOBJT_BOX: 693 + case SCENEOBJT_TEXTEDIT: 680 694 break; 681 695 case SCENEOBJT_MENU: { 682 696 struct scene_obj_menu *menu; ··· 736 750 case SCENEOBJT_IMAGE: 737 751 case SCENEOBJT_TEXT: 738 752 case SCENEOBJT_BOX: 753 + case SCENEOBJT_TEXTEDIT: 739 754 break; 740 755 case SCENEOBJT_MENU: { 741 756 struct scene_obj_menu *menu; ··· 782 797 case SCENEOBJT_IMAGE: 783 798 case SCENEOBJT_TEXT: 784 799 case SCENEOBJT_BOX: 800 + case SCENEOBJT_TEXTEDIT: 785 801 break; 786 802 case SCENEOBJT_MENU: 787 803 scene_menu_render_deps(scn, ··· 921 937 return log_msg_ret("key", ret); 922 938 break; 923 939 } 940 + case SCENEOBJT_TEXTEDIT: 941 + /* TODO(sjg@chromium.org): Implement this */ 942 + break; 924 943 } 925 944 return 0; 926 945 } ··· 947 966 case SCENEOBJT_IMAGE: 948 967 case SCENEOBJT_TEXT: 949 968 case SCENEOBJT_BOX: 969 + case SCENEOBJT_TEXTEDIT: 950 970 return -ENOSYS; 951 971 case SCENEOBJT_MENU: { 952 972 struct scene_obj_menu *menu = (struct scene_obj_menu *)obj; ··· 977 997 case SCENEOBJT_NONE: 978 998 case SCENEOBJT_TEXT: 979 999 case SCENEOBJT_BOX: 1000 + case SCENEOBJT_TEXTEDIT: 980 1001 case SCENEOBJT_IMAGE: { 981 1002 int width; 982 1003 ··· 1038 1059 case SCENEOBJT_BOX: 1039 1060 case SCENEOBJT_TEXTLINE: 1040 1061 break; 1062 + case SCENEOBJT_TEXTEDIT: 1063 + scene_txted_set_font(scn, obj->id, NULL, 1064 + theme->font_size); 1065 + break; 1041 1066 case SCENEOBJT_TEXT: 1042 1067 scene_txt_set_font(scn, obj->id, NULL, 1043 1068 theme->font_size); ··· 1079 1104 case SCENEOBJT_MENU: 1080 1105 case SCENEOBJT_TEXT: 1081 1106 case SCENEOBJT_BOX: 1107 + case SCENEOBJT_TEXTEDIT: 1082 1108 break; 1083 1109 case SCENEOBJT_TEXTLINE: 1084 1110 ret = scene_textline_open(scn,
+12
boot/scene_internal.h
··· 414 414 */ 415 415 int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr); 416 416 417 + /** 418 + * scene_txt_generic_init() - Set up the generic part of a text object 419 + * 420 + * @exp: Expo containing the object 421 + * @gen: Generic text info 422 + * @name: Object name 423 + * @str_id: String ID for the text 424 + * @str: Initial text string for the object, or NULL to just use str_id 425 + */ 426 + int scene_txt_generic_init(struct expo *exp, struct scene_txt_generic *gen, 427 + const char *name, uint str_id, const char *str); 428 + 417 429 #endif /* __SCENE_INTERNAL_H */
+61
boot/scene_textedit.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Implementation of a menu in a scene 4 + * 5 + * Copyright 2025 Google LLC 6 + * Written by Simon Glass <sjg@chromium.org> 7 + */ 8 + 9 + #define LOG_CATEGORY LOGC_EXPO 10 + 11 + #include <expo.h> 12 + #include <log.h> 13 + #include <linux/err.h> 14 + #include <linux/sizes.h> 15 + #include "scene_internal.h" 16 + 17 + enum { 18 + INITIAL_SIZE = SZ_4K, 19 + }; 20 + 21 + int scene_texted(struct scene *scn, const char *name, uint id, uint str_id, 22 + struct scene_obj_txtedit **teditp) 23 + { 24 + struct scene_obj_txtedit *ted; 25 + char *buf; 26 + int ret; 27 + 28 + ret = scene_obj_add(scn, name, id, SCENEOBJT_TEXTEDIT, 29 + sizeof(struct scene_obj_txtedit), 30 + (struct scene_obj **)&ted); 31 + if (ret < 0) 32 + return log_msg_ret("obj", ret); 33 + 34 + abuf_init(&ted->buf); 35 + if (!abuf_realloc(&ted->buf, INITIAL_SIZE)) 36 + return log_msg_ret("buf", -ENOMEM); 37 + buf = abuf_data(&ted->buf); 38 + *buf = '\0'; 39 + 40 + ret = scene_txt_generic_init(scn->expo, &ted->gen, name, str_id, buf); 41 + if (ret) 42 + return log_msg_ret("teg", ret); 43 + if (teditp) 44 + *teditp = ted; 45 + 46 + return ted->obj.id; 47 + } 48 + 49 + int scene_txted_set_font(struct scene *scn, uint id, const char *font_name, 50 + uint font_size) 51 + { 52 + struct scene_obj_txtedit *ted; 53 + 54 + ted = scene_obj_find(scn, id, SCENEOBJT_TEXTEDIT); 55 + if (!ted) 56 + return log_msg_ret("find", -ENOENT); 57 + ted->gen.font_name = font_name; 58 + ted->gen.font_size = font_size; 59 + 60 + return 0; 61 + }
+1
doc/develop/expo.rst
··· 560 560 Some ideas for future work: 561 561 562 562 - Default menu item and a timeout 563 + - Complete the text editor 563 564 - Image formats other than BMP 564 565 - Use of ANSI sequences to control a serial terminal 565 566 - Colour selection
+41
include/expo.h
··· 183 183 * @SCENEOBJT_TEXT: Text line to render 184 184 * @SCENEOBJT_MENU: Menu containing items the user can select 185 185 * @SCENEOBJT_TEXTLINE: Line of text the user can edit 186 + * @SCENEOBJT_TEXTEDIT: Simple text editor 186 187 */ 187 188 enum scene_obj_t { 188 189 SCENEOBJT_NONE = 0, 189 190 SCENEOBJT_IMAGE, 190 191 SCENEOBJT_TEXT, 191 192 SCENEOBJT_BOX, 193 + SCENEOBJT_TEXTEDIT, 192 194 193 195 /* types from here on can be highlighted */ 194 196 SCENEOBJT_MENU, ··· 465 467 }; 466 468 467 469 /** 470 + * struct scene_obj_txtedit - information about a box in a scene 471 + * 472 + * A text editor which allows users to edit a small text file 473 + * 474 + * @obj: Basic object information 475 + * @gen: Generic information common to all objects which show text 476 + * @buf: Text buffer containing current text 477 + */ 478 + struct scene_obj_txtedit { 479 + struct scene_obj obj; 480 + struct scene_txt_generic gen; 481 + struct abuf buf; 482 + }; 483 + 484 + /** 468 485 * struct expo_arrange_info - Information used when arranging a scene 469 486 * 470 487 * @label_width: Maximum width of labels in scene ··· 742 759 struct scene_obj_box **boxp); 743 760 744 761 /** 762 + * scene_texted() - create a text editor 763 + * 764 + * @scn: Scene to update 765 + * @name: Name to use (this is allocated by this call) 766 + * @id: ID to use for the new object (0 to allocate one) 767 + * @strid: ID of the string to edit 768 + * @teditp: If non-NULL, returns the new object 769 + * Returns: ID number for the object (typically @id), or -ve on error 770 + */ 771 + int scene_texted(struct scene *scn, const char *name, uint id, uint strid, 772 + struct scene_obj_txtedit **teditp); 773 + 774 + /** 745 775 * scene_txt_set_font() - Set the font for an object 746 776 * 747 777 * @scn: Scene to update ··· 751 781 */ 752 782 int scene_txt_set_font(struct scene *scn, uint id, const char *font_name, 753 783 uint font_size); 784 + 785 + /** 786 + * scene_txted_set_font() - Set the font for an object 787 + * 788 + * @scn: Scene to update 789 + * @id: ID of object to update 790 + * @font_name: Font name to use (allocated by caller) 791 + * @font_size: Font size to use (nominal height in pixels) 792 + */ 793 + int scene_txted_set_font(struct scene *scn, uint id, const char *font_name, 794 + uint font_size); 754 795 755 796 /** 756 797 * scene_obj_set_pos() - Set the postion of an object
+15 -1
test/boot/expo.c
··· 30 30 OBJ_MENU_TITLE, 31 31 OBJ_BOX, 32 32 OBJ_BOX2, 33 + OBJ_TEXTED, 33 34 34 35 /* strings */ 35 36 STR_SCENE_TITLE, ··· 37 38 STR_TEXT, 38 39 STR_TEXT2, 39 40 STR_TEXT3, 41 + STR_TEXTED, 40 42 STR_MENU_TITLE, 41 43 STR_POINTER_TEXT, 42 44 ··· 462 464 { 463 465 struct scene_obj_menu *menu; 464 466 struct scene *scn, *scn2; 467 + struct abuf orig, *text; 465 468 struct expo_action act; 466 469 struct scene_obj *obj; 467 470 struct udevice *dev; ··· 555 558 id = scene_box(scn, "box2", OBJ_BOX2, 1, NULL); 556 559 ut_assert(id > 0); 557 560 ut_assertok(scene_obj_set_bbox(scn, OBJ_BOX, 500, 200, 1000, 350)); 561 + 562 + id = scene_texted(scn, "editor", OBJ_TEXTED, STR_TEXTED, NULL); 563 + ut_assert(id > 0); 564 + ut_assertok(scene_obj_set_bbox(scn, OBJ_TEXTED, 100, 200, 400, 650)); 565 + ut_assertok(expo_edit_str(exp, STR_TEXTED, &orig, &text)); 566 + 567 + abuf_printf(text, "This\nis the initial contents of the text editor " 568 + "but it is quite likely that more will be added later"); 558 569 559 570 scn2 = expo_lookup_scene_id(exp, SCENE1); 560 571 ut_asserteq_ptr(scn, scn2); ··· 666 677 ut_asserteq(ITEM2, scene_menu_get_cur_item(scn, OBJ_MENU)); 667 678 ut_assertok(scene_arrange(scn)); 668 679 ut_assertok(expo_render(exp)); 669 - ut_asserteq(16304, video_compress_fb(uts, dev, false)); 680 + ut_asserteq(19673, video_compress_fb(uts, dev, false)); 670 681 ut_assertok(video_check_copy_fb(uts, dev)); 682 + 683 + /* hide the text editor since the following tets don't need it */ 684 + scene_obj_set_hide(scn, OBJ_TEXTED, true); 671 685 672 686 /* do some alignment checks */ 673 687 ut_assertok(scene_obj_set_halign(scn, OBJ_TEXT3, SCENEOA_CENTRE));